首页 > 试题广场 >

以下代码执行的结果显示是多少( )?

[单选题]
以下代码执行的结果显示是多少( )?

  • true,false,true
  • false,true,false
  • true,true,false
  • false,false,true
其实当我们在为Integer赋值的时候,java编译器会将其翻译成调用valueOf()方法。比如Integer i=127翻译为Integer i=Integer.valueOf(127)
然后我们来看看valueOf()函数的源码:
public static Integer valueOf(int i)
    {
        //high为127
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.***[i + 128];
        else
            return new Integer(i);
    }
可以看出,对于-128到127之间的数,Java会对其进行缓存。而超出这个范围则新建一个对象。
所以现在回到这道问题
i1和i2为128,超出范围,所以都需要新建对象,对象比较为false;
i5和i6为100,在范围之内,在执行Integer i5=100时,就会直接缓存到内存中,但执行执行Integer i6=100时,就直接从缓存里取,而不需要新建对象,所以为true。
发表于 2017-10-02 10:37:01 回复(18)
String s = "abc":通过字面量赋值创建字符串。则将栈中的引用直接指向该字符串,如不存在,则在常量池中生成一个字符串,再将栈中的引用指向该字符串
String s = “a”+“bc”:编译阶段会直接将“a”和“bc”结合成“abc”,这时如果方法区已存在“abc”,则将s的引用指向该字符串,如不存在,则在方法区中生成字符串“abc”对象,然后再将s的引用指向该字符串
String s = "a" + new String("bc"):栈中先创建一个"a"字符串常量,再创建一个"bc"字符串常量,编译阶段不会进行拼接,在运行阶段拼接成"abc"字符串常量并将s的引用指向它,效果相当于String s = new String("abc"),只有'+'两边都是字符串常量才会在编译阶段优化
发表于 2019-08-27 10:09:25 回复(13)
代码片段
public class Test03 {

    
    public static void main(String[] args) {
       
        Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;

         
        System. out.println( f1 == f2); //true
        System. out.println( f3 == f4); //false
    }
}

当我们给一个Integer赋予一个int类型的时候会调用Integer的静态方法valueOf
Integer f1 = Integer.valueOf(100);
Integer f2 = Integer.valueOf(100);
Integer f3 = Integer.valueOf(150);
Integer f4 = Integer.valueOf(150);
思考:那么Integer.valueOf()返回的Integer是不是是重新new Integer(num);来创建的呢?如果是这样的话,那么== 比较返回都是false,因为他们引用的堆地址不一样。

具体来看看Integer.valueOf的源码
public static Integer valueOf(int i) {
        
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.***[i + (-IntegerCache.low)];
        return new Integer(i);
}
在IntegerCache中***数组初始化如下,存入了-128 - 127的值
*** = new Integer[(high - low) + 1];
int j = low;
for( int k = 0; k < ***.length ; k ++)
    ***[k] = 
    ***[k] = new Integer(j ++);
从上面我们可以知道给Interger 赋予的int数值在-128 - 127的时候,直接从***中获取,这些***引用对Integer对象地址是不变的,但是不在这个范围内的数字,则new Integer(i) 这个地址是新的地址,不可能一样的.

编辑于 2017-08-27 19:20:07 回复(15)
Integer的范围是-128~127,如果超出范围的话会新建一个对象,否则就是使用内存中的那个对象。
发表于 2017-08-19 19:51:22 回复(5)

关于字符串的解释(摘自:https://www.cnblogs.com/huajiezh/p/6565301.html):String str1=”java”;    //指向字符串池
String str2=”blog”;   //指向字符串池


String s=str1+str2;   //s是指向堆中值为"javablog"的对象,+运算符会在堆中建立来两个String对象,这两个对象的值分别是"java" "blog". 也就是说从字符串池中复制这两个值,然后在堆中创建两个对象,然后再建立对象s,然后将"javablog"的堆地址赋给s.    这句共创建了?个String 对象!

System.out.println(s==”javablog”);   //结果是false。
Jvm确实对型如String str1=”java”;的String对象放在常量池里,但是它是在编译时那么做的,而String s=str1+str2;是在运行时刻才能知道,也就是说str1+str2是在堆里创建的,所以结果为false了

发表于 2018-07-04 21:43:19 回复(1)
关于拆箱和装箱问题,可参考博客http://www.importnew.com/15712.html
引申:
若题中代码改为 Integer i5 = new Integer(100);Integer i6 = new Integer(100); 则i5==i6 结果为false,因为两个对象之间比较并不会自动拆箱,所以==比的是对象的引用地址,故不相等。而原来题目中相等是因为当自动装箱时,JVM会优化,出于节省内存的考虑,JVM会缓存-128到127的Integer对象,所以当自动装箱的数值在这区间时,所装箱的结果都是对缓存池中同一个对象的引用,故==比较地址会为true。
编辑于 2018-07-28 21:27:21 回复(1)
Integer的范围是-128~127 超过范围会new
发表于 2017-08-18 17:53:44 回复(1)
例题一:
TRUE    FALSE    TRUE
第一次String a="1234"时,会在常量池中创建一个常量1234,String b=1234时,常量池中已经有了该常量,所以直接取,a和b的地址一样,所以地址值相等
String c = newString("1234")重新new了对象,在堆内存中开辟了新的空间,所以地址值不想等,而equals方法比较的是值是否相等

拓展与总结:
在String中 == 是判断地址是否相等
关于equals这个方法,在String类中是被重写了的,可以先判断地址是否相同,再比较值是否相同
并不是所有类的equals都是比较值,例如object类的equals方法和==是一样的
注:instanceof是用来判断前后两个对象是否是一个家族中的,也就是判断是否有继承关系

例题二:

false,false,true

拓展与总结:
在Integer中,使用 == 来作比较两个对象时(和常数进行比较时,是直接比较值是否相同),需要注意的一点是:对Integer对象进行初始化赋值时,是通过调用valueOf来实现的。
而对于-128到127之间的数(最小值-128是确定了的,但是最大值127是可以通过虚拟机的配置文件来配置),Java会对其进行缓存。而超出这个范围则新建一个对象。
也就是说,如果第一次创建值时在缓存范围之内,第二次如果也是第一次相同的数,其实就是直接在缓存中取的,并没有新建对象,地址相同。

equals的源码↓

编辑于 2018-12-10 14:07:52 回复(1)
Integer范围-128-127。两个Integer类型数据比较,在其范围内则之比较其值,如果超出范围则new Integer(),地址不同则比较结果为false
发表于 2018-01-18 09:01:34 回复(0)
integer对象在-128和127范围内,是使用的内存中对象,比较值。而超过这个范围,则要新建一个对象,比较的是对象所在的内存地址,所以两个都要新建对象,地址不一样,false. i5和i6都是100,使用的是内存中的对象,比较的是值的大小,所以是true 。 string i3=100 在常量池中创建100 string i4="1"+new string("00") 是常量池中新建1,,然后建立一个字符串对象。然后在常量池中新建00,,建立一个字符串对象。最后是常量池中新建100,,建立一个字符串对象。 字符串比较,==比较的是地址是否相同,equals比较地址是否相同,相同然后比较值是否相同。 显然地址不相同的,对象个数都不一样。
编辑于 2019-03-15 13:33:19 回复(1)
String i3 = "100";
String i4 = "10"+new String("0");
System.out.println(i3 == i4);
String i7 = "100";
String i8 = "10" +"0";
System.out.println(i7 == i8);
false,true
发表于 2017-10-10 11:48:42 回复(3)
integer在-128到127之间会有个缓存问题,主要是因为integer有个valueOf的方法进行缓存处理,不明白可以看一下这个函数源码。
发表于 2017-08-23 08:02:07 回复(0)
使用 valueOf()方法创建的对象,使用 “==” 符号时,运行结果有时候正确,有时候不正确。 原因: 整数类型在 -128~127 之间时,会使用缓存,如果已经创建了一个相同的整数,使用Integer=128 自动装箱(在装箱的时候自动调用的是 Integer 的 valueOf(int) 方法)创建第二次时,不会使用 new 关键字,而使用已经缓存的对象。 所以使用 ValueOf 方法创建两次对象,若对应的数值相同,且数值在 -128~127 之间时,两个对象都指向同一地址。 查看valueOf方法的源码更为直观。
发表于 2017-09-22 14:59:59 回复(0)
对于数字在-128到127的数字,Java会对其进行缓存,超出范围后会创建一个对象,所以第一个true,第三个false。 直接赋值的字符串在常量池中,i3都直接指向常量池,new字符串是在堆栈中创建,并且==比较的是地址,所以第二个i3和i4的地址肯定不一样啊,为false
发表于 2022-10-11 00:30:49 回复(0)
Integer范围-128-127。两个Integer类型数据比较,在其范围内则之比较其值,如果超出范围则new Integer(),地址不同则比较结果为false
发表于 2021-11-05 19:06:35 回复(0)
Integer i1 = 100  //底层调用valueof方法在-128-127  范围之间能直接获取值,并没有创建新的对象  true
Integer i2  = 128  //底层调用valueof超出了127范围,会新创建对象,只要是新new出来都是false
发表于 2019-12-07 23:32:17 回复(0)
Integer的范围是-128~127,如果超出范围的话会新建一个对象,否则就是使用内存中的那个对象。
发表于 2018-07-13 13:19:15 回复(1)
记错了,记成-128到+128了,是-128到127
发表于 2023-09-16 08:06:28 回复(0)
Integer的范围是-128~127 (使用内存中的对象)超过范围会new 一个新的Integer对象,比较的地址指向不一样
发表于 2023-04-02 12:08:38 回复(0)
Integer范围-128-127,在其范围内则之比较其值,如果超出范围则new Integer()
发表于 2023-01-28 22:02:37 回复(0)