前言
Java的数据类型在程序语言的构成要素里占有相当重要的地位。 因此,了解好数据类型很重要!
一、数据类型
Java中规定了8中基本数据类型变量来存储整数、浮点数、字符和布尔值。
如下图(这里实在去不了水印,用它家的产品做的思维导图): 类型的范围: 不同类型的变量,其能表示的数据范围也是不一样的。Java的基本数据类型占用内存位数及可表示的数据范围如下表:
1.整数类型
整数类型,简称整型,表示的是不带有小数点的数字。在Java中,有4种不同类型的整型,按照占据空间大小的递增次序,分别为(byte)(位)、short(短整型)、int(整数)及long(长整型)。
一般来说,整数类型都指int型。
1.1.byte类型
基本语法格式:
byte 变量名 = 初始值;
byte a= 0;
System.out.println(a);
在Java种,byte类型占据1字节内存空间,它的取值范围是-128~127。
什么是字节?
字节是计算机中表示空间大小的基本单位. 计算机使用二进制表示数据. 我们认为 8 个二进制位(bit) 为一个字节(Byte). 我们平时的计算机为 8GB 内存, 意思是 8G 个字节. 其中 1KB = 1024 Byte, 1MB = 1024 KB, 1GB =1024 MB. 所 以 8GB 相当于 80 多亿个字节.
那么,这个取值范围我们怎么得来的呢? 我们在这里介绍一下,接下来介绍到的数据类型取值范围都是这样求得。
我们说,每个基本的数据类型都有几个静态属性,比如说MAX_VALUE 、MIN_VALUE、SIZE、TYPE等等,分别是求最大值、最小值、大小和类型。
那么,如果我们要得到这些值,我们可以用名称为该类型首字母大写对象通过点(.)操作符将其读取出来。
比如说,byte类型对应Byte对象。
一个Byte类型的对象只包含byte的字段。
public static void main(String[] args) {
byte max=Byte.MAX_VALUE;
byte min=Byte.MIN_VALUE;
byte size=Byte.SIZE;
System.out.println(max);
System.out.println(min);
System.out.println(size);
}
1.2.short类型
基本语法格式:
short 变量名=初始值;
short a= 0;
System.out.println(a);
1.short类型数据占据2个字节内存空间,取值范围为-32768~32767 2.这个表示范围比较小, 一般不推荐使用
1.3.int类型
基本语法格式:
int 类型名=初始值;
int a=0;
System.out.println(a);
int类型占据4个字节内存空间,取值范围为-2147483648~2137383647
public static void main(String[] args) {
int maxValue = Integer.MAX_VALUE;
System.out.println(maxValue+1);
int minValue = Integer.MIN_VALUE;
System.out.println(minValue);
}
假如我们要存储的数据比int类型所能存储的范围还大,比如说22亿这个数字,如果我们把22亿放到int类型里面会怎样? 答案:会产生数据的溢出问题。
public static void main(String[] args) {
int max=Integer.MAX_VALUE;
int min=Integer.MIN_VALUE;
System.out.println(max);
System.out.println(min);
System.out.println(max+1);
System.out.println(max+2);
System.out.println(min-1);
}
所以,当我们的int类型不够大的时候,我们可以采用范围更大的类型,long类型。
1.4.long类型
基本语法格式
long 类型名=初始值;
long a=0;
System.out.println(a);
long类型数据占据8个字节内存空间,取值范围为 -2^63 ~2^63-1。
【注意】 整形数据出现了溢出问题,如果要解决,我们可以扩大数据的操作范围。我们有以下两种方法。
1.直接在数据前增加一个long; 2.直接在数据后增加一个字母L或者l(小写)。
public static void main(String[] args) {
int max=Integer.MAX_VALUE;
int min=Integer.MIN_VALUE;
System.out.println(max);
System.out.println(min);
System.out.println(max+(long)1);
System.out.println(max+(long)2);
System.out.println(min-1L);
}
2.浮点类型
2.1.float类型
基本语法格式:
float 变量名 = 初始值;
float num = 1.0f;
System.out.println(num);
float 类型在 Java 中占四个字节, 同样遵守 IEEE 754 标准. 由于表示的数据精度范围较小, 一般在工程上用到浮点数都优先考虑 double, 不太推荐使用float。
【注意】 含小数的实数默认为double类型,如上面的1.0,如果定义的是float类型,为其赋值的时候,必须要执行强制转换类型。 方法如下: 1.直接加上字母F/f,如上面"float num=1.0f; "。 2.直接在数字前加强制转型为float,如上面,float “num=(float)1.0;” 。
2.2.double类型
基本语法格式:
double 变量名 = 初始值;
double num = 1.0;
System.out.println(num);
双精度浮点型的长度为64个字节,有效范围是-1.710^308 ~ 1.710^308 .
2.3.字符类型char
基本语法格式:
char 变量名 = 初始值;
char ch = 'a';
字符,就是字母和符号的统称。
字符类型在内存中占用2个字节。
我们来看一下下面这段代码。
public static void main(String[] args) {
char ch1=97;
char ch2='a';
System.out.println("ch1="+ch1);
System.out.println("ch2="+ch2);
}
我们要注意,字符要用一队(’ ‘)括起来,但是如果我们把一个字符变量ch赋值成一个单引号(例如:char ch=’ ’ ';),这时候就会出问题。所以就有了转义字符的概念。
转义字符把不容易混淆的字符代替那些敏感字符,作为一个整体使用。
转义字符 | 解释 |
---|
\n | 换行 | \t | 水平制表符 | ’ | 单引号 | " | 双引号 | \ | 反斜杠 |
3.布尔类型
基本语法格式:
boolean 变量名 = 初始值;
boolean a= true;
System.out.println(a);
- boolean 类型的变量只有两种取值, true 表示真, false 表示假.
- Java 的 boolean 类型和 int 不能相互转换, 不存在 1 表示 true, 0 表示 false 这样的用法.
- boolean 类型有些 JVM 的实现是占 1 个字节, 有些是占 1 个比特位, 这个没有明确规定
4.数据类型的转换
Java有严格的数据类型限制,当需要进行数据类型的转换的时候,必须遵循严格的步骤和规定。
数据类型转换的转换方式有以下两种,“自动类型转换”和“强制类型转换”。
4.1自动类型转换
自动类型转换,我们可以理解成“扩大转换”。
什么意思?
就是字节小的类型可以转换到字节大的类型,反之不成立。
比如。一个字符型的变量(char,本质上是2字节大小的整数)和一个整型变量(int,一般是4个字节大小整数),进行计算,需先转换成相同类型,才能进行运算。
在这里,只能将char类型转换成int类型,不然可能会导致整型变量溢出,导致计算错误。
public static void main(String[] args) {
float a = 10f;
int b = 20;
a = b;
b = a;
}
【注意】
- 在Java中,由于Boolean类型只能存放true和flase,与整数及字符不兼容,因此Boolean类型不可能与其他任何数据类型进行转换。整数与浮点数亦是兼容的,所以可相互转换。
- 当两个数中有一个为浮点数时,运算结果会直接转换为浮点数。
- 当表达式中变量的类型不同时,Java会自动把较小的数据类型表示范围,转换成较大的数据类型表示范围后,再做运算。
【自动类型转换规律】
byte -> short -> in -> long -> float -> double
4.2强制转换类型
基本语法格式:
(欲转换的数据类型)变量名称;
```java
public static void main(String[] args) {
int a=10;
b=(long)a;
}
【注意】 由于在转换的过程中可能会丢失数据的精确度,因此Java并不会自动做这些类型的转换。若需要,我们可自行做强制性的转换。
4.3一道练习
思考一下下面的练习题输出的答案是什么?
public static void main(String[] args) {
int a=2;
int b=3;
System.out.println(a+b+"a");
System.out.println(3+3+"cc"+3+3);
}
为什么是这个答案呢? 我们来分析一下。
对于“System.out.println(a+b+“a”);”这个表达式,a+b=5,没有问题,关键在于后面的“a”是字符串,通过类型转换知乎将5转换成了字符,所以第二个+号相当于一个字符串连接符。
对于“ System.out.println(3+3+“cc”+3+3);”,也是遇到cc后前面3+3=6的值被转换成字符串。同时,系统也将后面的两个整数3、3都转换成字符串了,所以输出6cc33。
二、运算符
程序是由许多语句组成的,而语句组成的基本单元就是表达式与运算符。下面,我们逐一介绍算术运算符、关系运算符、逻辑运算符、位运算符、移位运算符和条件运算符。
1.算术运算符
这个运算符比较简单,基本上跟我数学上的没什么大的出入。 值得注意的是以下几点。
- int 结果还是 int, 需要使用 double 来计算
int a = 1;
int b = 2;
System.out.println(a / b);
· 增量赋值运算符 += -= *= /= %=
int a = 10;
a += 1;
System.out.println(a);
其他的也可以类推出来,不一一讲述。
· 自增/自减运算符 ++ –
int a = 10;
int b = ++a;
System.out.println(b);
int c = a++;
System.out.println(c);
2.关系运算符
关系运算符主要有六个:
== != <> <= >=
int a = 10;
int b = 20;
System.out.println(a == b);
System.out.println(a != b);
System.out.println(a < b);
System.out.println(a > b);
System.out.println(a <= b);
System.out.println(a >= b);
【注意】
关系运算符的表达式返回值都是 boolean 类型.
3.逻辑运算符
常见的逻辑运算符由3个,与(&&)、或(||)、非(!)。
逻辑运算符只对布尔型操作符运算并返回一个布尔型数据。
逻辑与&&:两个操作数都为 true, 结果为 true, 否则结果为 false
逻辑或||: 两个操作数都为 false, 结果为 false, 否则结果为 true
逻辑非!:操作数为 true, 结果为 false; 操作数为 false, 结果为 true(这是个单目运算符, 只有一个操作数)
而上面三个运算符,我们又称为短路运算符。为什么呢? 我们通过下面例子来理解:
System.out.println(10 > 20 && 10 / 0 == 0);
System.out.println(10 < 20 || 10 / 0 == 0);
我们都知道, 计算 10 / 0 会导致程序抛出异常. 但是上面的代码却能正常运行, 说明 10 / 0 并没有真正被求值.
【结论】
-
对于 && , 如果左侧表达式值为 false, 就立即返回false,无需计算右侧表达式. -
对于 ||, 如果左侧表达式值为 true, 就立即返回true, 无需计算右侧表达式.
非短路逻辑运算符&和|
- 对于&,运算符左右两边的操作符都需要运算,任何一个操作数不和Java语法规定的地方,均不被编译器认可
- 对于|,左右两个运算符都被运算。
4.位运算符
位运算符主要有以下4种。
& (“and”) 、| (“or”) 、^ (“xor”)、 ~ (“not”)
在Java中,对数据的操作的最小单位不是字节, 而是二进制位。
而位操作表示按二进制位运算。计算机中都是使用二进制来表示数据的(01构成的序列), 按位运算就是在按照二进制位的每一位依次进行计算。
按位与 &: 如果两个二进制位都是 1, 则结果为 1, 否则结果为0
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a & b);
}
按位或 |: 如果两个二进制位都是 0, 则结果为 0, 否则结果为 1
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a | b);
}
}
【注意】
当 & 和 | 的操作数为整数(int, short, long, byte) 的时候, 表示按位运算, 当操作数为 boolean 的时候, 表示逻辑运算。
按位取反~:
按位取反 ~: 如果该位为 0 则转为 1, 如果该位为 1 则转为 0
public static void main(String[] args) {
int a = 10;
System.out.printf("%d\n", ~a);
}
按位异或 ^:
按位异或 ^: 如果两个数字的二进制位相同, 则结果为 0, 相异则结果为 1
public static void main(String[] args) {
int a = 10;
int b=20;
System.out.printf("%d\n", a^b);
}
5.移位运算符
以下举例讲解均用正数,因为正数的原码、反码、补码一样。想深入了解可阅读我之前写过的这篇文章: 【C语言】玩转操作符——操作符的那些东西!
里面又对计算机存储形式更深入的讲解。
移位运算符有三个:
<< >> >>>
都是按照二进制位来运算。
左移<<:最左侧位不要了,最右侧补0。
public static void main(String[] args) {
int a=10;
System.out.printf("%d\n", a << 1);
}
右移 >>: 最右侧位不要了, 最左侧补符号位(正数补0, 负数补1)
public static void main(String[] args) {
int a=10;
System.out.printf("%d\n", a >> 1);
}
无符号右移 >>>: 最右侧位不要了, 最左侧补 0。
public static void main(String[] args) {
int a=10;
System.out.printf("%d\n", a >>> 1);
}
【注意】
- 左移 1 位, 相当于原数字 * 2. 左移 N 位, 相当于原数字 * 2 的N次方.
- 右移 1 位, 相当于原数字 / 2. 右移 N 位, 相当于原数字 / 2 的N次方.
- 由于计算机计算移位效率高于计算乘除, 当某个代码正好乘除 2 的N次方的时候可以用移位运算代替.
- 移动负数位或者移位位数过大都没有意义
6.条件运算符
条件运算符只有一个:
表达式1?表达式2:表达3;
当 表达式1 的值为 true 时, 整个表达式的值为 表达式2 的值; 当 表达式1 的值为 false 时, 整个表达式的值为 表达式 3 的值。
这里最经典的例子就是求2个数的最大值了。
public static void main(String[] args) {
int a = 10;
int b = 20;
int max = a > b ? a : b;
}
7.运算符的优先级
这里为大家整理了一个表格,仅供参考。 优先级表格:
运算符 | 综合性 |
---|
[ ]、( )、(方法调用) | 从左向右 | ! - ++ + ( 一元运算)-( 一元运算)(_ )( 强制类型转换)new | 从右向左 | * / % | 从左向右 | + - | 从左向右 | << >> >>> | 从左向右 | < <= > >= instanccof | 从左向右 | = = != | 从左向右 | & | 从左向右 | ^ | 从左向右 | 非短路逻辑或 | 从左向右 | && | 从左向右 | 按位或 | 从左向右 | ? : | 从右到左 | = += _ = *= /= %= &= ^= <<= >>= >>>= | 从右到左 |
最后
整体来看, Java 的运算符的基本规则和 C语言基本一样。 本文内容参考《Java从入门到精通》一书、学习时所作笔记撰写而成。希望对看到的各位有所帮助。这里也可以与我之前写的C语言操作符对照着看。链接如下: 【C语言】玩转操作符——操作符的那些东西! 感谢!
|