面试官问你是true还是false你可以最后反问他这个

叁歲伎倆 2023-05-28 06:45 26阅读 0赞

我们常常看到一些用==号判断是true还是false的面试题,今天就列出来几个,看看到底是true还是false,原因是什么。

  1. String s1 = "abc";
  2. String s2 = "abc";
  3. System.out.println(s1 == s2);

答:true,因为”abc”是一个常量,所以首先会去常量池中判断(equals)有没有值”abc”的对象,如果没有会在常量池中创建一个,并返回该对象的引用,如果有,就直接返回该对象的引用,这里会创建一个”abc”对象,然后返回该对象的引用,这样也就创建了我们常说的对象s1,当我们创建s2对象的时候,我们发现常量池中已经存在”abc”对象了,所以直接返回该对象的引用,s1和s2指向了同一个常量池对象,所以为true。

  1. String s1 = new String("abc");
  2. String s2 = new String("abc");
  3. System.out.println(s1 == s2);

答:false,因为在用new关键字创建对象的时候,会把对象存放到堆内存中,然后返回对象的引用,但是对String类来说就比较特殊了,new String(“abc”)创建对象时,首先会在常量池中判断是否存在”abc”,如果不存在会在常量池中创建一个对象,然后再会再堆内存中创建一个对象,并返回堆内存的引用,创建s2的时候,此时常量池中已经存在”abc”,则不再创建,但是堆内存中的对象还是会新创建的,然后返回一个新创建的对象的引用,所以为false(暂不知道为啥要那个常量池中的对象)。

  1. String s1 = new String("abc");
  2. String s2 = "abc";
  3. System.out.println(s1 == s2);

答:false,经过上面两个讲解,这个应该就好理解了,s1是堆内存中的引用,s2是常量池中的引用,不得不提的是,在创建s2的时候,并没有在常量池中新创建对象,而是直接用的s1在常量池中创建的对象,这样我们更一步确定,s1返回的是堆中的引用而不是常量池中的引用,所以为false。

  1. String s1 = "a" + "b" + "c";
  2. String s2 = "abc";
  3. System.out.println(s1 == s2);

答:true,这里的s1来的挺不容易的,首先会在常量池中创建”a”对象,然后创建”b”对象,然后创建”ab”对象,然后创建”c”对象,然后创建”abc”对象,最后把”abc”对象的引用返回给s1,创建s2对象的时候,直接就返回”abc”对象的引用了,所以是true。

  1. String s1 = "ab";
  2. String s2 = s1 + "c";
  3. String s3 = "abc";
  4. System.out.println(s2 == s3);

答:false,首先s1会在常量池中创建”ab”对象,然后返回引用,此时就创建了s1对象,在创建s2对象的时候,相当于是字符串的拼接,像StringBuffer这种类型一样,通过append方法拼成一个新的对象,该对象保存在堆中,所以为false。

  1. Integer a = 100;
  2. Integer b = 100;
  3. Integer c = 200;
  4. Integer d = 200;
  5. System.out.println(a == b);
  6. System.out.println(c == d);

答:true,false,因为在int的包装类Integer中,用这种直接赋值的方式创建对象,在Integer中有一个IntegerCatch,这里存放了-128~127,所以在这个范围内的数,会直接在IntegerCatch中返回,所以为true,而对于范围之外的,则需要new对象,所以为false,下图是源码。
在这里插入图片描述
最后面试官问你,在方法中定义的int型变量是放到哪了,然后你说,随着方法的调用被加载到栈中,当方法调用完毕释放内存。面试官又问你,那定义的int型的成员变量呢,然后你又说,这是全局的,不会随着方法的调用完毕而释放,是存在堆中的,然后面试官说不错,那再给你出最后一道题。

  1. public class Main {
  2. static int a = 10;
  3. public static void main(String[] args) {
  4. int b = 10;
  5. System.out.println(a == b);
  6. }
  7. }

你要是敢这样回答:是false,因为一个在堆中一个在栈中。那就前功尽弃了。
面试官:是true,因为他是基本数据类型,比较的是值,而不是引用或地址。记住一句话,基本数据类型比较的都是引用,引用数据类型才有那么多的坑去考虑。
最后的最后你可以问一下面试官,在用new关键字创建String对象的时候,为啥会创建两个对象,常量池中的那个对象有啥用呢

发表评论

表情:
评论列表 (有 0 条评论,26人围观)

还没有评论,来说两句吧...

相关阅读

    相关 面试什么Hash表

    Hash表(哈希表),也叫散列表,在这之前还以为这是两种数据结构呢,不知道为啥他俩能扯上关系,翻译了一波才知道,hash就是把……弄乱;斩碎的意思,这下明白名字的由来了。