Integer i2=100 与 Integer i3=100 的比较以及String实例的联想

本文探讨了Java中Integer对象的比较方式,解释了为何在特定范围内(-128到127)的整数对象可以直接通过==比较,而超出此范围的对象则不行。同时对比了String类型的实例化过程及其在常量池中的行为。

先来看一段代码

public class IntegerDemo01 {

public static void main(String[] args) {
     Integer i2 =100;
     Integer i3 =100;
     System.out.println(i2==i3);

     Integer i4 =1000;
     Integer i5 =1000;
     System.out.println(i3==i4);

    }
}

以上输出是true 还是false呢?
其中第一个是true ,第二个是false。初学者就会对这个答案产生疑问。为啥会出现这个情况呢?
先通过反编译 查看一下到底编译器是怎么处理这行代码的?

import java.io.PrintStream;
public class IntegerDemo01
 {

  public IntegerDemo01()
  {
    }

  public static void main(String args[])
 {
    Integer i2 = Integer.valueOf(100);
    Integer i3 = Integer.valueOf(100);
    System.out.println(i2 == i3);
    Integer i4 = Integer.valueOf(1000);
    Integer i5 = Integer.valueOf(1000);
    System.out.println(i3 == i4);
 }
}

从上面代码可以得知,编译器引用变量的定义和初始化中使用到了Integer.valueOf()方法,这个valueOf()是干嘛用的呢?

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
   //如果数值在-128~127之间的 
return IntegerCache.cache[i + (-IntegerCache.low)];
   //返回 
    return new Integer(i);
 }

来看这段代码的描述
* Returns an {@code Integer} instance representing the specified
{@code int} value.,
返回了这个Integer的含有指定的值的实例
* as this method is likely to yield significantly better space and time performance by
* 显着更好的空间和时间性能
* caching frequently requested values.


  1. 这个方法返回了一个带有值的实例,
  2. 然后返回了一个从-128~127的值的缓存数组,用于缓存在这个范围内所有创建的实例对象。
  3. 如果之前有存在就直接拿来用,不存在的话就新建new 一个Integer对象。

有人会联想到String类型,因为String的实例有时候也是这么赋值的。那么编译器在背后有没有进行转化呢?看一下代码?

    String str = "abc";
    String str2 ="abc";
    System.out.println(str==str2);
    String str3 = new String("abc");
    String str4 = new String("abc");
    System.out.print(str3==str4);

如上的结果第一个是true ,第二个是false。第一个是在常量池中去查找是否有没有这个abc这个值,有的话,直接进行引用。没有的话,再在常量池中创建。所以第一个的引用变量他们的地址都相同的,因此为true。
第二个用到了new,这个单词告诉了编译器 直接在堆内存中给我开辟了一个空间,不管之前是否有存在。因此,尽管值也一样,但是它们引用的地址是不一样的。因此为false。
再来看一下编译器是否有将String的实例构建进行某些转换?

    String str = "abc";
    String str2 = "abc";
    System.out.println(str == str2);
    String str3 = new String("abc");
    String str4 = new String("abc");
    System.out.print(str3 == str4);

发现没有任何操作,没有偷着我们干了什么事。


建议,如果要判断包装类的对象是否相等,最好用equals()方法.

以上大体想法来源于知乎专栏 -java那些事

`Integer a1 = new Integer(100);` 这行代码的主要作用是创建一个 `Integer` 类的对象实例,并且将其初始化为 100。以下从几个方面进行详细解释: ### 代码作用 在 Java 里,`int` 属于基本数据类型,而 `Integer` 是 `int` 的包装类,属于引用类型。使用 `new Integer(100)` 会在堆内存中生成一个新的 `Integer` 对象,此对象包含整数值 100。变量 `a1` 实际上是一个引用,它指向堆内存中这个新创建的 `Integer` 对象。 ### 使用场景 - **集合操作**:Java 的集合框架(像 `ArrayList`、`HashMap` 等)只能存储对象,无法直接存储基本数据类型。要是想在集合中存放整数,就得使用 `Integer` 对象。 ```java import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> numbers = new ArrayList<>(); Integer a1 = new Integer(100); numbers.add(a1); } } ``` - **泛型使用**:泛型要求使用引用类型,所以在泛型代码里使用整数时,要用到 `Integer` 类型。 ### 注意事项 - **内存占用**:每一次使用 `new Integer()` 都会在堆内存中创建一个新的对象,这会占用额外的内存空间。要是频繁创建 `Integer` 对象,可能会造成内存开销过大。 - **比较问题**:在使用 `==` 比较 `Integer` 对象时,比较的是对象的引用地址,而非对象的值。若要比较两个 `Integer` 对象的值,应当使用 `equals()` 方法。 ```java Integer a1 = new Integer(100); Integer a2 = new Integer(100); System.out.println(a1 == a2); // false System.out.println(a1.equals(a2)); // true ``` - **缓存机制**:Java 为了提升性能,对 -128 到 127 之间的 `Integer` 对象做了缓存。不过,使用 `new Integer()` 时,不会触发这个缓存机制,无论值处于哪个范围,都会创建新的对象。 ### 其他方式对比 - **`Integer a = 100;`**:这种方式会触发自动装箱,Java 会默认通过 `valueOf()` 方法进行装箱操作。对于 -128 到 127 之间的值,会从缓存中获取对象,而非创建新对象。 ```java Integer a = 100; Integer b = 100; System.out.println(a == b); // true ``` - **`int b = 100;`**:`int` 是基本数据类型,直接存储数值,不涉及对象的创建,内存占用相对较少。当 `int` 变量和 `Integer` 对象比较时,`Integer` 对象会自动拆箱为 `int` 类型,然后比较值的大小。 ```java Integer a1 = new Integer(100); int b = 100; System.out.println(a1 == b); // true ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值