关于Integer、 int、 String 的比较判别

Java中==比较的是两个对象是否是同一个引用(即比较内存地址)
equals 对于从写了equals方法的类来说是比较值,没有重写仍然比较地址;

Integer 和 int

public class IntegerAndString {
    @Test
    public void test1(){
        int i1=5;
        Integer i2=5;
        System.out.println(i1==i2); //true

        Integer i3=5;
        Integer i9=new Integer(5);
        Integer i4=new Integer(5);  
        System.out.println(i3==i4); //false
        System.out.println(i9==i4);//false


        Integer i5=20;
        Integer i6=20;
        System.out.println(i5==i6); //true

        Integer i7=129;
        Integer i8=129;
        System.out.println(i7==i8); //false

        int a=new Integer(10);
        Integer b=10;
        System.out.println(a==b);//true
    }

int (是面向对象的残留) 当int 和Integer 数据类型进行比较时Integer会进行自动拆箱操作,所以只会比较实际的值,所以i1==i2 a==b

Integer是int的封装类,一般来说基础变量(int)赋值给Integer对象将自动装箱(Auto Boxing)并为Integer对象分配堆空间。因此即使基础变量值一样,封装类对象指向不同地址

当用Integer i=new Integer(6)创建对象时则是在堆区从新划分一个内存空间,把地址给i,所以i4==i9是false

由于因为JDK 的自动装箱操作可以用Integer i2=5来声明变量,Java在编译的时候会执行将代码封装成Integer i2=Integer.valueOf(5);通过查看源码发现

public static Integer valueOf(int i) {
        final int offset = 128;
        if (i >= -128 && i <= 127) { // must cache 
        return IntegerCache.cache[i + offset];
        }
        return new Integer(i);
        }

也就是说这种方式声明一个Integer对象时,JVM首先会在Integer对象的缓存池中查找有木有值为20的对象,如果有直接返回该对象的引用;如果没有,则使用创建一个对象,并返回该对象的引用地址。),i5和i6都是引用的同一个对象结果为”true“ 且地址值都在常量池中,所以 i3==i4是false

而它维护的常量池从-128~127 当超出这个范围时就返回new Integer(129); 在堆区创建对象,返回地址值,所以i7==i8是false

String

public void test2(){
        String str1="hello";
        String str2="hello";
        System.out.println(str1==str2); //true

        String str3=new String("hello");
        System.out.println(str1==str3);//false

        String str4="ab";
        String str6="abc";
        String str5=str4+"c";
        System.out.println(str6==str5);//false

        String s1="a"+"b"+"c";
        String s2="abc";
        System.out.println(s1==s2);//true
        /*在java中有常量优化机制,byte=4+3 
         * (在编译时会判断将3+4=7在bytede 范围内)是对的,
         * 同理在编译时也变成了三个字符串abc
         * */
    }

String 的机制是String s=”hello” 创建对象时同样是现在常量池中找,若没有就创建,若有则返回地址引用,所以str1==str2

String str3=new String(“hello”),也会去常量池去找,没有就创建,创建完毕后会将这个字符串拷贝到堆区,在堆内存中再创建一个对象,然后将堆的地址返回 所以str3==str1是false

会先在常量池中创建str4和str6字符串对象,对于使用了+将变量str4和“c”相连接,首相会在堆区创建一个Stringbuffer对象,通过方法将其加在一起,产生一个地址值,然后调用它的toString方法转换成一个字符串并创建对象,产生一个地址值并返回,
内存图

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值