Java编程思想简要笔记——第三章 操作符

对一个对象进行操作时,真正操作的是对象的引用。

别名问题

一个对象有两个以上的引用

Trank a = new Trank();
Trank b = a;

一元加减操作符

“+”,“-”能将较小的类型提升为int

++,–

前缀 ++a,先运算,再返回
后缀 --a,先返回

关系操作符 < > <= >= == !=

前面四个是数字类型的比较符,后面两个还可以作为对象的比较符,后者就会涉及equals的问题。对于数字比较要区分包装类型和基本数据类型两种,处理方式是不同的。

Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println("n1 == n2:" + (n1 == n2)); // false
System.out.println("n1.equals(n2):" + n1.equals(n2)); // true
Integer n3 = 47;
Integer n4 = 47;
System.out.println("n3 == n4:" + (n3 == n4)); // true

Integer n5 = 128;
Integer n6 = 128;
System.out.println("n5 == n6:" + (n5 == n6)); // false

Integer是包装类型,每次new的时候都会在堆里新建一个内存,n1和n2是不同的内存块,用 == 比较时是比较的内存地址,所以n1 == n2会返回false,而equals比较的是实际的值,所以n1.equals(n2)返回true。
Integer n3 = 47;会自动进行装箱,所以n3和n4应该是指向不同内存的,而n3 == n4返回true就很奇怪了,所以装箱指向的是同一个内存?好吧假设是这样的,那n5 == n6却是false?

其实Integer n3 = 47; 在编译时会自动写成Integer n3 = Integer.valueOf(47);为了证明这个问题,便看了一下编出来的机器码。

// 源码
public static void main(String[] args) {
    Integer v1 = 4;
    Integer v2 = Integer.valueOf(4);
}
// 机器码
  public static void main(java.lang.String[]);
    Code:
       0: iconst_4
       1: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       4: astore_1
       5: iconst_4
       6: invokestatic  #2                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       9: astore_2
      10: return
}

从4,6两行可以看出来,确实是默认调用的valueOf方法,进入该方法查看

@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
    return i >= -128 && i <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[i + 128] : new Integer(i);
}

从实现来看,当valueOf的入参在-128-[Integer.IntegerCache.high]之间时,返回的时同一个缓存对象,在此范围外时,在重新new一个新对象出来。所以问题解决了。
其中Integer.IntegerCache.high这个值是从JVM虚拟机中读出来的VM.getSavedProperty(“java.lang.Integer.IntegerCache.high”)一般都是127.

逻辑操作符

短路:一旦能够明确无误地确认整个表达式的值,就不再计算表达式的余下部分了。

直接常数

后缀字符

L-long
F-float
D-double

前缀字符

0x-16进制数,后面跟着0-9和a-f
0-八进制,后面只能跟0-7,如果输入08会报编译错误

用toBinaryString()可以转为二进制表示

指数记数法

1.37e-43 = 1.37 * 10^-43
编译器通常将指数作为double处理,float使用时要进行强转

按位操作符

与,&,同一则一
或,|,同零则零
异或,^,相同则零
非,~,一则零

移位操作符

操作符号解释
左移<<在低位补零
有符号右移>>在高位按“符号扩展”,正数高位补零,负数,高位补一
无符号右移>>>“零扩展”无论正负高位补零

char,byte,short位处理是会被转成int,结果也是int。所以“位移”与“符号”连用,char,byte,short慎用,会被先转成int再截断

字符串操作符+和+=

非字符串类型会默认调用toString方法,如果是null则填“null”

类型转换操作符

窄化转换必须强转,面临信息丢失危险|
截尾和舍入浮点->整型,截尾,舍入,用Math.round()
提升float+double->double,int+long->long
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kiba_zwei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值