Java的基本数据类型及运算符介绍

  • 基本类型
    • short(短整型)
    • byte(字节类型)
    • int( 整型)
    • long(长整型)
    • double(双精度浮点型)
    • float(单精度浮点型)
    • char(字符类型)
    • boolean(布尔类型)
    • 小结
  • 算术运算符
    • 除 /
    • 取余 %
  • 赋值及复合赋值运算符
  • 自增自减运算符
  • 关系运算符
  • 逻辑运算符
    • 逻辑与 &&
    • 逻辑或 ||
    • 逻辑非 !
  • 位运算符
    • 按位与 &
    • 按位或 |
    • 逻辑 & 和 | (不推荐使用)
    • 按位异或 ^
    • 按位取反 ~
  • 移位运算
    • 左移位运算 <<
    • 右移位运算 >>
    • 无符号右移 >>>
  • 条件运算符 :?
  • 运算符优先级
  • 运算符小结

基本类型

在java里有八种基本类型及每一种类型都对应了一种包装类
Java的基本数据类型及运算符介绍_第1张图片

  • 在了解基本数据类型之前需要说一下,java的所有类型的字节大小都和平台没有关系。
  • 所有整型没有无符号概念。

short(短整型)

  1. short 占用 2 个字节, 表示的数据范围是 -32768~32767
  2. 因为范围比较小,不是必须的话,不推荐使用。
    使用示例
short value = 10; 
System.out.println(value);

注意事项

short a = 10;
short b = 20;
short c = a + b;
System.out.println(c);

当运行这段代码的时候会出现报错。
Java的基本数据类型及运算符介绍_第2张图片
即使short 和 short 都是相同类型, 但是会出现编译报错. 原因是, 虽然 a 和 b 都是 short变量, 但是计算 a + b 会先将 a 和 b 都提升成 int, 再进行计算, 得到的结果也是 int, 这是赋给 c, 就会出现上述错误

正确的写法

short a = 10; 
short b = 20; 
short c = (short)(a + b); 
System.out.println(c);

给a+b的表达式强制转换为short类型则不会报错。

byte(字节类型)

  1. 字节类型也属于整型的一种,不过它的字节大小是1,取值范围是-128~127

使用示例

byte value = 10; 
System.out.println(value);

注意事项

  1. byte类型和short类型都是低于4个字节,在运算时均会发生数值提示的现象,使用时需要更加注意
  2. 因为范围比较小,不是必须的话,不推荐使用。

int( 整型)

使用示例

int num = 10; // 定义一个整型变量
System.out.println(num) ;
  1. 在java中int类型就是4个字节,跟系统无关。
  2. 由于在java中是没有无符号整型概念的,所以int的取值范围是 -2^31 ~ 2^31-1

以下代码可以查看int的数据范围。

public static void main(String[] args) {
     
     System.out.println(Integer.MAX_VALUE); // int 的最大值
     System.out.println(Integer.MIN_VALUE); // int 的最小值
 }

运行截图
在这里插入图片描述
如果运算的结果超出了int的取值范围,则数据就会溢出

public static void main(String[] args) {
     
    System.out.println(Integer.MAX_VALUE+1); // int 的最大值加1会溢出
    System.out.println(Integer.MIN_VALUE-1); // int 的最小值-1会溢出
}

运行截图
在这里插入图片描述有细心的读者会发现,int所表示的最大值加1溢出后变成了最小值,而最小值减1后变成了最大值,我们可以把类型范围表示看成一个圆形
Java的基本数据类型及运算符介绍_第3张图片
中间的是分界线,如果超过了最大值则就变成了最小值,这种概念可以应用与所有的整型类型。

long(长整型)

对于int能表示21亿,这样的数字对于当前大数据时代来说,是很容易溢出的,针对这种情况, 我们就需要使用更大范围的数据类型来表示了. Java 中提供了 long 类型.

使用示例

long num = 10L; // 定义一个长整型变量, 初始值写作 10l 也可以(小写的 L, 不是数字1). 
System.out.println(num) ;
  1. 需要注意的是初始化设定的值为 10L ,表示一个长整型的数字,10l 也可以.
  2. 使用 10 初始化也可以, 10 的类型是 int, 10L 的类型是 long, 使用 10L 或者 10l 更好一些.(这里推荐用大写的L,因为有些字体小写的l可能容易被看成数字1)
  3. java中long占8个字节,取值范围在 -2^63 ~ 2^63-1

使用以下代码查看 Java 中的长整型数据范围

public static void main(String[] args) {
     
    System.out.println(Long.MAX_VALUE);
    System.out.println(Long.MIN_VALUE);
}

运行结果在这里插入图片描述
这个数据范围远超过 int 的表示范围. 足够绝大部分的工程场景使用.

double(双精度浮点型)

  1. 在java中小数默认是double类型。

使用示例

double num = 1.0;//定义一个浮点型变量
System.out.println(num)

浮点型和整型有什么不一样呢?来看下面一段代码。

public static void main(String[] args) {
     
    int a = 1;
    int b = 2;
    System.out.println(a / b);
}

如果站在数学角度来讲,得到的应该是0.5,可运行结果得到的是0。
运行截图
在这里插入图片描述
因为a和b是int类型变量,所以得到的结果也会是int类型的值,而int是无法储存小数的。如果想要得到小数,那我们就需要把int改成double。

public static void main(String[] args) {
     
    double a = 1.0;
    double b = 2.0;
    System.out.println(a / b);
}

运行截图
在这里插入图片描述
来看一段有趣的代码

public static void main(String[] args) {
     
   double a = 1.1;
   double b = 1.1;
   System.out.println(a * b);
}

运行截图
在这里插入图片描述
理论来讲,得出的结果应该是1.21,为什么后面还多了个2?这是因为Java 中的 double 虽然也是 8 个字节, 但是浮点数的内存布局和整数差别很大, 不能单纯的用 2 ^ n 的形式表示数据范围,Java 的 double 类型的内存布局遵守IEEE 754 标准(和C语言一样), 尝试使用有限的内存空间表示可能无限的小数, 势必会存在一定的精度误差,关于IEEE 754标准,有兴趣的读者可以去度娘了解一下,这里就不多介绍了。

float(单精度浮点型)

  1. float 类型在 Java 中占4个字节, 同样遵守 IEEE 754 标准. 由于表示的数据精度范围较小, 一般在工程上用到浮点数都优先考虑 double, 不太推荐使用 float.

使用示例

float num = 1.0f;    // 写作 1.0F 也可以
System.out.println(num);

初始化需要注意在值需要加一个大写的F或者小写的f来表示这是一个float类型的小数,因为在java中小数是默认是double型的,不加f的话就相当于把一个double类型的值赋给float类型,则会发生精度丢失的错误。

char(字符类型)

  1. char类型不能存储负数, 取值范围在是~65535
  2. Java 中使用 Unicode 表示字符. 因此一个char占用2个字节, 表示的字符种类更多, 包括中文
  3. Java 中使用 单引号 + 单个字母 的形式表示字符字面值.

使用示例

public static void main(String[] args) {
     
    char a = 'A';
    char b = 'B';
    char c = 65;//对应Unicode表上的字符'A'
    char d = '中';
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);
    System.out.println(d);
}

运行结果
在这里插入图片描述

boolean(布尔类型)

使用示例

boolean value = true; 
System.out.println(value);
  1. boolean 类型的变量只有两种取值, true 表示真, false 表示假.
  2. Java 的 boolean 类型和 int 不能相互转换, 不存在 1 表示 true, 0 表示 false 这样的用法.
  3. boolean 类型有些 JVM 的实现是占 1 个字节, 有些是占 1 个比特位, 这个没有明确规定.

小结

  1. 不同类型的数据混合运算, 范围小的会提升成范围大的.
  2. 对于 short, byte 这种比 4 个字节小的类型, 会先提升成 4 个字节的 int , 再运算
  3. 更推荐在代码中避免不同类型混用的情况, 来规避类型转换和类型提升的问题
  4. 在Java中局部变量是没有默认值的,如果局部变量没有给初始值,在编译时会出现异常。

基本数据类型介绍到这,最后附上一张数据类型概况图,关于引用数据类型,会在以后的博客中讲。
Java的基本数据类型及运算符介绍_第4张图片

算术运算符

Java的基本数据类型及运算符介绍_第5张图片
四则运算规则比较简单,这里我就讲比较容易出错的取余和除法运算符。

除 /

除法在进行运算的时候,会根据类型不同得出不同结果。

public static void main(String[] args) {
     
        System.out.println(12 / 5);
        System.out.println(12 / (float)5);
}

运行截图
在这里插入图片描述
从运行结果我们可以看到,两个数值一样类型不一样得到的结果不一样,需要注意除法有两种规则。

  1. 如果两个操作数都是整型则执行整型运算
  2. 如果有一个操作数是浮点型则执行浮点型运算

需要注意,除数不能为0否则编译会报错
Java的基本数据类型及运算符介绍_第6张图片

取余 %

在java中取余运算符是可以对小数取余的
Java的基本数据类型及运算符介绍_第7张图片
需要注意跟除法一样,不能对0进行取余否则会报错,报错原因跟除法相同。

这里有道负数取余的例子

System.out.println(10%3);
System.out.println(10%-3);
System.out.println(-10%3);
System.out.println(-10%-3);

运行结果
在这里插入图片描述
解析

  1. 10取余3商3余1
  2. 10取余-3商-3余1
  3. -10取余3商-3余-1
  4. -10取余-3商3余-1

赋值及复合赋值运算符

Java的基本数据类型及运算符介绍_第8张图片

使用方式

int a = 10;//赋值
a += 1;//等价与a=a+1;
a -= 1;//等价与a=a-1;
a *= 1;//等价与a=a*1;
a /= 1;//等价与a=a/1;
a %= 1;//等价与a=a%1;

自增自减运算符

在这里插入图片描述
使用方式

int a = 10;
int b = 0;
a--;//等价与a = a-1;
a++;//等价与a = a+1;
b = ++a;//前置++
b = a++;//后置++
b = --a;//后置--
b = a--;//后置++

自增自减运算符需要区分是否作为单独一条语句,或者是作为赋值语句
Java的基本数据类型及运算符介绍_第9张图片

上面代码我们看到,两个相同的值,在做自增时,如果是后置++则先赋值然后自增,如果是前置++则先自增后赋值。
如果不取自增运算的表达式的返回值, 则前置自增和后置自增没有区别.

//单独一条语句时,此时前置和后置++等价
a++;
++a;

自减操作符同理

关系运算符

Java的基本数据类型及运算符介绍_第10张图片
使用方式

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);

注意事项

  1. 关系运算符的表达式返回的是boolean类型的值
  2. 关系表达式的等于是两个=号
    Java的基本数据类型及运算符介绍_第11张图片

逻辑运算符

Java的基本数据类型及运算符介绍_第12张图片
短路与、短路或也称逻辑与逻辑或

逻辑与 &&

  • 规则: 两个操作数都为 true, 结果为 true, 否则结果为 false.

使用方式

(表达式1) && (表达式2)
如果表达式1和表达式2都为true,则逻辑与的结果为true,否则为false

逻辑或 ||

  • 规则: 两个操作数都为 false, 结果为 false, 否则结果为 true

使用方式

(表达式1) || (表达式2)
如果表达式1和表达式2都为false,则逻辑或的结果为false,否则为true

关于&& 和 || 短路求值的属性

作为"&&“和”||"操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程便告终止,这称之为短路求值

Java的基本数据类型及运算符介绍_第13张图片
我们都知道, 计算 10 / 0 会导致程序抛出异常. 但是上面的代码却能正常运行, 说明 10 / 0 并没有真正被求值.

结论:

  1. 对于 && , 如果左侧表达式值为 false, 则表达式的整体的值一定是 false, 无需计算右侧表达式.
  2. 对于 ||, 如果左侧表达式值为 true, 则表达式的整体的值一定是 true, 无需计算右侧表达式.

逻辑非 !

  • 规则: 操作数为 true, 结果为 false; 操作数为 false, 结果为 true(这是个单目运算符, 只有一个操作数)

使用示例
Java的基本数据类型及运算符介绍_第14张图片

位运算符

Java 中对数据的操作的最小单位不是字节, 而是二进制位.
Java的基本数据类型及运算符介绍_第15张图片
位操作表示 按二进制位运算. 计算机中都是使用二进制来表示数据的(01构成的序列), 按位运算就是在按照二进制位的每一位依次进行计算.

按位与 &

  • 规则:如果两个二进制位都是 1, 则结果为 1, 否则结果为 0

代码示例

int a = 10; 
int b = 20; 
System.out.println(a & b);

运算过程

0000 0000 0000 0000 0000 0000 0000 1010 //10的二进制
0000 0000 0000 0000 0000 0000 0001 0100 //20的二进制
0000 0000 0000 0000 0000 0000 0000 0000 //按位与后 得到结果0

运算结果
Java的基本数据类型及运算符介绍_第16张图片

按位或 |

  • 规则: 如果两个二进制位都是 0, 则结果为 0, 否则结果为 1.

代码示例

int a = 10; 
int b = 20; 
System.out.println(a | b);

运算过程

0000 0000 0000 0000 0000 0000 0000 1010 //10的二进制
0000 0000 0000 0000 0000 0000 0001 0100 //20的二进制
0000 0000 0000 0000 0000 0000 0001 1110 //按位或后得到结果为30

运算结果
Java的基本数据类型及运算符介绍_第17张图片

逻辑 & 和 | (不推荐使用)

  • & 和 | 如果操作数为 boolean 的时候, 也表示逻辑运算. 但是和 && 以及 || 相比, 它们不支持短路求值.

代码示例

System.out.println(10 > 20 & 10 / 0 == 0); // 程序抛出异常
System.out.println(10 < 20 | 10 / 0 == 0); // 程序抛出异常

使用&当逻辑运算时,不管表达式1是否为假它都会执行表达式2。
Java的基本数据类型及运算符介绍_第18张图片
使用 | 当逻辑运算时,不管表达式1是否为真它都会执行表达式2。
Java的基本数据类型及运算符介绍_第19张图片
总体来说尽量不使用逻辑& 和 逻辑 | 用作逻辑运算。

按位异或 ^

  • 规则:如果两个数字的二进制位相同, 则结果为 0, 相异则结果为 1.

代码示例

int a = 8; 
int b = 13; 
System.out.println(a ^ b);

运算过程

0000 0000 0000 0000 0000 0000 0000 1000 //8的二进制
0000 0000 0000 0000 0000 0000 0000 1101 //13的二进制
0000 0000 0000 0000 0000 0000 0000 0101 //按位异或后得到结果为5

运行结果
Java的基本数据类型及运算符介绍_第20张图片
按位异或的4个特点

  1. 0异或任何数=任何数
  2. 1异或任何数 = 任何数取反
  3. 任何数异或自己 = 0
  4. a异或b得到c,c可以通过异或b得到a或者异或a得到b。

按位取反 ~

  • 规则:如果该位为 0 则转为 1, 如果该位为 1 则转为 0
  • 需要注意按位取反是对整数的补码进行取反

代码示例

int a = 2;
System.out.printf("%d\n", ~a);//打印的是原码

运算过程

0000 0000 0000 0000 0000 0000 0000 0010   //2的补码
1111 1111 1111 1111 1111 1111 1111 1101   //按位取反得到补码
1111 1111 1111 1111 1111 1111 1111 1100   //补码减一得到反码
1000 0000 0000 0000 0000 0000 0000 0011   //反码按位取反得到原码,十进制的-3

运算结果
Java的基本数据类型及运算符介绍_第21张图片
如果有读者不清楚原码、反码、补码的话,可以去看我另一篇博客链接

移位运算

  • 移位运算符有三个,都是按照补码二进制位来运算
    Java的基本数据类型及运算符介绍_第22张图片

左移位运算 <<

  • 规则:二进制向左移位,二进制左边丢弃,右边补0

代码示例

int a = 10;
System.out.println(a << 1);

运算过程
Java的基本数据类型及运算符介绍_第23张图片

运算结果
Java的基本数据类型及运算符介绍_第24张图片
关于 << 位运算,左移一位有乘2的效果。

右移位运算 >>

  • 规则:右边丢弃, 左边补符号位(正数补0, 负数补1)

代码示例

int a = 10;
System.out.println(a >> 1);

运算过程
Java的基本数据类型及运算符介绍_第25张图片
运算结果
Java的基本数据类型及运算符介绍_第26张图片
关于 >> 运算符,右移1位有除2的效果。

无符号右移 >>>

  • 规则: 右边位丢弃, 左边位补0(不区分有没有符号)

代码示例

int a = -1;
System.out.println(a >>> 1);

运算过程
Java的基本数据类型及运算符介绍_第27张图片
运算结果
Java的基本数据类型及运算符介绍_第28张图片

条件运算符 :?

在这里插入图片描述

  • 条件运算符只有一个: 表达式1 ? 表达式2 : 表达式3 当 表达式1 的值为 true 时, 整个表达式的值为表达式2的值; 当 表达式1 的值为 false 时, 整个表达式的值为 表达式3 的值
  • 是 Java 中唯一的一个 三目运算符, 是条件判断语句的简化写法

代码示例

int a = 10; 
int b = 20; 
int max = a > b ? a : b;
System.out.println(max);

运行截图
Java的基本数据类型及运算符介绍_第29张图片

运算符优先级

先看一段代码

System.out.println(1 + 2 * 3); 

结果为 7, 说明先计算了 2*3 , 再计算 1+

另外一个例子

System.out.println(10 < 20 && 20 < 30); 

此时明显是先计算的 10 < 20 和 20 < 30, 再计算 &&. 否则 20 && 20 这样的操作是语法上有误的(&& 的操作数只能是boolean).

结论

  • 运算符之间是有优先级的. 具体的规则我们不必记忆. 在可能存在歧义的代码中加上括号即可.

最后附上一张运算符优先级图
Java的基本数据类型及运算符介绍_第30张图片

运算符小结

  1. % 操作再 Java 中也能针对 double 来计算.
  2. 需要区分清楚 前置自增 和 后置自增之间的区别.
  3. 由于 Java 是强类型语言, 因此对于类型检查较严格, 因此像 && 之类的运算操作数必须是 boolean.
  4. 要区分清楚 & 和 | 什么时候是表示按位运算, 什么时候表示逻辑运算.

整体来看, Java 的运算符的基本规则和 C 语言基本一致。

你可能感兴趣的:(java)