AKSTIANYE

Aug 03, 2018

关于java一些零零散散的点(一)


==与equals()

  • 对于==
    • 比较基本数据类型时,比较的是
    • 比较对象时,比较的是两个对象的地址
  • 对于equals()
    • equals()方法存在于Object类中
    • Object类是所有类的直接或间接父类
    • Object类中equals()方法底层依赖的是==
      • 没有重写equals()方法的类中,equals()==号的效果一样,即比较对象地址
      • 重写后的equals()方法以实际为准,但一般都是比较两个对象的值

整型缓存问题

先来看一下代码

1
2
3
4
5
6
7
8
9
public static void main(String... strings) {
Integer integer1 = 3;
Integer integer2 = 3;
System.out.println(integer1 == integer2);

Integer integer3 = 300;
Integer integer4 = 300;
System.out.println(integer3 == integer4);
}

我们知道对于对象==比较的是对象的引用地址,由此可能会认为以上代码输出的都是false
然鹅,结果是

1
2
true
false

原因在于由 Java 5 开始,为 Integer 的操作引入了一个新的特性,用来节省内存和提高性能。整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用。

  • 上面的规则适用于整数区间 -128+127,当然这两个值是默认值,可以修改。
  • 这种 Integer 缓存策略自动装箱的时候有用,使用构造器创建的 Integer 对象不能被缓存。

自动装箱:Java 编译器把原始类型 自动转换为封装类过程称为自动装箱,这相当于调用 valueOf 方法

我们可以看一下Integer类中的valueOf方法

1
2
3
4
5
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

可以看到在返回Integer对象前会在缓存中查找,已有的直接返回,找不到再实例化一个对象。

扩展

  • 整型数据的缓存范围可以通过JVM参数-XX:AutoBoxCacheMax=size调整
  • 这种缓存行为不仅适用于Integer对象。我们针对所有整数类型的类都有类似的缓存机制。
    • ByteCache 用于缓存 Byte 对象
    • ShortCache 用于缓存 Short 对象
    • LongCache 用于缓存 Long 对象
    • CharacterCache 用于缓存 Character 对象
      - ByteShortLong 有固定范围: -128127
  • Character, 范围是 0 127
  • 除了 Integer 可以通过参数改变范围外,其它的都不行。

参考
理解Java Integer的缓存策略


OLDER > < NEWER