zoukankan      html  css  js  c++  java
  • Java面试题之 String

            有这样一个面试题:

        

    String a = "a";
    		String a1 = new String("a");
    		String a2 = a1.trim() + "";
    		String a3 = "a" + "";
    		String a4 = "a".trim() + "";
    		System.out.println(a == a1);
    		System.out.println(a.intern() == a1.intern());
    		System.out.println(a2 == a1);
    		System.out.println(a3 == a);
    		System.out.println(a4 == a);

     请问结果是什么?

    运行后的结果是:

    false
    true
    false
    true
    false
    

     为什么结果是这样呢?这需要从String 本身说起。

    Java在运行时会维护一个字符串常量池String Pool; 在String a="a"; 首先检查字符串常量池中是否有"a",如果有则直接返回,否则在常量池中创建一个新的;

         String a1=new String("a"); 使用new 关键字创建的对象一定在堆栈中,同样也会维护字符串常量池,因为字符串常量池中已经存在了,则不会添加新的。在JAVA中==永远都是比较两个内存地址是否相同,这样因为a和a1不是同一个对象则已定返回false;

       intern()方法时返回字符串常量池中的对象,因为常量池中只存在一个“a” 则两者已定相等;

       a2.trim()+"" 则是在堆栈中创建了一个新对象,同时维护常量池;则该表达式返回false 但是字符串常量的拼接仅仅维护常量池不会在堆栈中创建新对象则"a"+""还是常量池中的“a”;

    为了更直观了解我们可以看一下这段代码的字节码,通过字节码可能更有说服力。

      LDC是将常量推送到栈顶,ASTORE 是将栈顶元素赋值给本地变量。

    iinvokespecial 调用实例初始化方法,父类实例化方法,私有方法

    iinvokevirtual虚方法

    通过字节码可以发现 a是常量指向的地址是#2,a1是通过常量“a"new出来的地址是,a2也是new出来的,a3还是常量“a" #2,a4也是new出来的

    public class core.demo.StringTest {
      public core.demo.StringTest();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
    
      public static void main(java.lang.String[]);
        Code:
           0: ldc           #2                  // String a
           2: astore_1
           3: new           #3                  // class java/lang/String
           6: dup
           7: ldc           #2                  // String a
           9: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
          12: astore_2
          13: new           #5                  // class java/lang/StringBuilder
          16: dup
          17: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
          20: aload_2
          21: invokevirtual #7                  // Method java/lang/String.trim:()Ljava/lang/String;
          24: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          27: ldc           #9                  // String
          29: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          32: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          35: astore_3
          36: ldc           #2                  // String a
          38: astore        4
          40: new           #5                  // class java/lang/StringBuilder
          43: dup
          44: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
          47: ldc           #2                  // String a
          49: invokevirtual #7                  // Method java/lang/String.trim:()Ljava/lang/String;
          52: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          55: ldc           #9                  // String
          57: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          60: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          63: astore        5
          65: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
          68: aload_1
          69: aload_2
          70: if_acmpne     77
          73: iconst_1
          74: goto          78
          77: iconst_0
          78: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
          81: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
          84: aload_1
          85: invokevirtual #13                 // Method java/lang/String.intern:()Ljava/lang/String;
          88: aload_2
          89: invokevirtual #13                 // Method java/lang/String.intern:()Ljava/lang/String;
          92: if_acmpne     99
          95: iconst_1
          96: goto          100
          99: iconst_0
         100: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
         103: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
         106: aload_3
         107: aload_2
         108: if_acmpne     115
         111: iconst_1
         112: goto          116
         115: iconst_0
         116: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
         119: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
         122: aload         4
         124: aload_1
         125: if_acmpne     132
         128: iconst_1
         129: goto          133
         132: iconst_0
         133: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
         136: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
         139: aload         5
         141: aload_1
         142: if_acmpne     149
         145: iconst_1
         146: goto          150
         149: iconst_0
         150: invokevirtual #12                 // Method java/io/PrintStream.println:(Z)V
         153: return
    }
    
     
  • 相关阅读:
    myeclipse codelive插件关闭
    php-memcache基本用法
    css3选择器笔记
    网卡配置/etc/network/interfaces
    javascript 调用cookies
    $_FILES详解
    http_build_query
    javascript写贪吃蛇游戏(20行代码!)
    php 中date显示时间不对与Linux文件乱码问题
    const && define
  • 原文地址:https://www.cnblogs.com/wei-zw/p/8797740.html
Copyright © 2011-2022 走看看