1. 莫衷一是——i+++j该如何计算?
三个加号
在java中默认 前面结合 也就是 (i++) + j
int i = 25;
int j = 2;
int result = i++ + j;
System.out.println(i);
System.out.println(j);
/*26 2*/
贪心规则
编译器的贪心规则,分析符号的时候,编译器会尽可能多地结合有效地符号
例如: i ++ + j
+ 、 ++ 都是有效的符号, 但是+++ 不是有效的。
而a - -b a - 负b, 编译器会a-- b 编译错误
为何贪心?
贪心规则是有用的,因为这样可以对转义字符等进行特殊处理。
编译器尽可能多地对有效字符结合,否则转义字符将时区作用。
对于“、1717” 、 “\431”,会按两个字符处理。因为这两个数值都炒股了八进制转义字符的取值范围("\0" -- "\377");
2.千差万别——++i与i++仅是“先加”与“后加”的差别吗?
前置++ 与 后置++
举出一个特殊的例子
int i = 25;
i = i++;//这里是后置
System.out.print(i);//25
后置++ 的自白
//前置
int i= 25;
int j = ++i * 25;
//编译之后
i+=1;
int j = i * 25;
//后置
int i= 25;
int j = i++ * 25;
//编译之后
int temp = i;
i+=1;
int j = temp * 25;
3.大相径庭——相除与求余在Java中的具体表现
整型相除与求余运算的表现。
浮点类型相除与求余运算的表现。
浮点相除与求余运算的各种特殊情况。
浮点值+0与-0的差别。
特殊的浮点值
int a = 25;
float b = 23.5f;
float divided = 0.0f;
try {
int c = a/0;
} catch (Exception e) {
System.out.println("int 0 divide");
}
try {
int c = a%0;
} catch (Exception e) {
System.out.println("int 0 mod");
}
try {
float c = b/0.0f;
} catch (Exception e) {
System.out.println("float 0 divide");
}
try {
float c = b%0.0f;
} catch (Exception e) {
System.out.println("float 0 mod");
}
除数为0的浮点运算
Infinity 、 -Infinity 、 NaN
+0 -0 的差异
1.当+0 -0参与浮点类型的相关运算,符号不同
2.+0 -0 在浮点类型变量存储中,符号位是不同的
3.Java类库中的某些类也是吧浮点类型的+0 -0视为完全不同的力两个1数值处理
4.移形换位-移位运算的真实剖析
Java中三bit运算符 左移<< 、右移>>、无符号右移>>>
3种移位运算符的使用。
移位运算对右侧操作数的处理。
移位运算与乘除运算的关联。
无符号右移。
超过自身位数1的移位置
3 >> 32
对于整形来说,Java会首先对移动的bit位进行取余操作,int/long最大的bit位作为模量
当移位为 负数时候。
左边为int类型, 右侧操作数只有低5位是有效的。首先与0x1f进行与运算,再进行位运算。
同样,long只有低6位有效, 可以看作右侧操作数与0x3f做与运算
移位运算与乘除运算
*左移一位 === 2 、 右移一位 === 1/2 : 前提条件是是奇数, 因为涉及到舍入问题
也就是: 一旦不能整除,就会涉及到舍入模式
-9 /2 == -4 (向上舍入 趋于0)
-9 >> 1 == -5 (向下舍入 )
所以,乘以2"与左移n位的值是相等的,如果可以整除,除以2"与右移n位的值也是相等的。如果不能整除,当被除数为正数时,除以2"与右移n位的值相等,当被除数为负数时,除以2"与右移n位的值则是不相等的。
int a = -8;
int b = a << 1;
System.out.println(b);
int c = a >>> 1; //2147483644
//补码进行运算, 所以会溢出。
// 无符号>>> 左侧符号0
System.out.println(Integer.toBinaryString(a));
//11111111111111111111111111111000
System.out.println(Integer.toBinaryString(c));
//01111111111111111111111111111100
5.鞭劈近里-条件运算符(? : )的深入
" ? :"条件表达式的类型
- 条件运算含有三个表达式,表达式1必须为booleaan 或Boolean类型,表达式2与表达式3可以i是任意类型,根据表达式1的取值不同,只会计算表达式2与表达式3 其中的一个。
- 根据表达式2与3的类型不同,条件表达式的类型也会不对。
6.井然有序-运算顺序的详细挖掘
从左到右的计算顺序
int b = a + (++a) + (a = 1) + a; // 5 a=1 1 + 2 + 1 + 1;
复合运算符
复合运算符可以自动将右侧运算的结果转华安为左侧操作数的类型
byte b = 25;
b = b + 1;//编译失败
b+=1;//编译通过
7.异曲同工-变换变量的3种方式
-
中间变量
-
相加减
-
异或操作
int a = 5; int b = 25; System.out.println(Integer.toBinaryString(a)); System.out.println(Integer.toBinaryString(b)); // a: 0 0101 // b :1 1001 a = a^ b; // 11100 b = a ^b; //00101 a = a ^ b;
8.择木而栖-开关选择表达式switch的类型内幕
对包装类的处理
Integer a = 2;
switch (a){ //编译之后, a.intValue();
case 2->{
System.out.println("2");
}
case 3->{
}
default -> throw new IllegalStateException("Unexpected value: " + a);
}
对枚举类的处理
对于枚举类型, 首先会在内部生成一个匿名类, 该匿名类含有一个int[]类型的静态final成员变量,数组的长度位枚举常量的个数,数组元素的值位枚举常量的序数(ordinal方法返回的值)。
switch对枚举进行处理时, 辅助的静态匿名类 由编译器生成。如果子集生命匿名类, 类中不允许有静态成员
对String类型的处理
会将switch语句拆分成两个switch语句, 第一个1switch根据1对象哈希码对应一个1临时变量赋值,第二个switch根据这个值匹配1case 。
String s="Apple";String sl=S;
byte byte0 =-1;
switch (sl.hashCode()) {
case 1982479237:
if (sl.equals( "Banana")){
byte0=0;
break;
case63476538:
if(sl.equals( "Apple")){
byte0 =1;
break;
switch (byte0){
case0:
System.out.println("B");break;
case l:
System.out.println("A");break;
switch表达式可以是 byte、short、char、int、Byte、Short、Character、Integer、String或枚举类型。
case表达式必须是常量表达式或枚举常量名,并且其类型可以赋值给switch表达式类型。switch表达式的类型为基本数据类型的包装类型时,将包装类型拆箱为基本数据类型。
当switch类型为枚举类型时,会创建一个匿名类来辅助完成。
当switch类型为String类型时,将switch语句拆分为两个switch语句,分别对 String对象的哈希码及临时变量来辅助完成。
标签:02,Java,int,System,运算符,switch,println,表达式,out
From: https://www.cnblogs.com/lartimes/p/17858101.html