有这样一个面试题:
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 }
相关推荐
│ Java面试题08.String.mp4 │ Java面试题09.讲一下java中的集合.mp4 │ Java面试题10.ArrayList LinkedList.mp4 │ Java面试题11.HashMap和HashTable的区别.mp4 │ Java面试题12.实现一个拷贝文件的类使用字节流...
以下是对标题和描述中涉及的一些常见Java面试题的详细解释: 1. **JDK 和 JRE 的区别** JDK(Java Development Kit)是用于开发和调试Java程序的完整工具集,包括JRE(Java Runtime Environment)、编译器(javac...
为了在Java面试中脱颖而出,了解和掌握常见的面试题及答案至关重要。以下是一些关键知识点的详细解析: 1. **super()与 this()的区别** `super()`用于调用父类的构造器,确保子类实例化时父类的初始化;`this()`则...
【JAVA笔试题与面试题详解】 1. **Java基础知识** - Java的基本数据类型包括整型(byte, short, int, long)、浮点型(float, double)、字符型(char)和布尔型(boolean)。String不是基本数据类型,而是类,它...
【Java笔试题解析】 在2020年兴业银行的Java笔试中,涉及了多个核心的Java编程和技术概念。以下是对部分题目进行的详细解答: 1. 输入一个正整数,计算并输出距离它最近的对称数 对称数是指从左向右读和从右向左...
java面试题精讲视频MP4Java面试题08.String提取方式是百度网盘分享地址
### Java面试笔试题详解 #### 一、集合框架与线程安全性 - **线程安全类**:在Java集合框架中,存在一部分被设计成线程安全的类,这意味着它们能够在多线程环境下安全地使用,而不需要额外的同步措施。这类包括`...
整理了网上的一些java面试题目,很全很强大 面向对象的特征有哪些方面 1. 抽象:抽象就是忽略一个主题中与当前目标2. 无关的那些方面,3. 以便更充分地注意与当前目标4. 有关的方面。抽象并不5. 打算了解全部问题...
"Java面试题及答案详解" Java是目前最流行的编程语言之一,在软件开发行业中广泛应用。以下是Java面试题及答案的详解: Java基础 1. JDK 和 JRE 的区别是什么? JDK(Java Development Kit)是Java开发工具包,...
Java是一种广泛应用的编程语言,java面试笔试题大汇总涵盖了Java的多方面知识点,包括Java面试题目、多线程编程、通信编程、数据库查询、异常处理机制、事件机制、多形与继承、抽象类与接口、String与StringBuffer的...
### Java经典面试题知识点 #### Java数据结构容器 - **核心知识点**:Java集合框架,包括List、Set、Map等接口及其实现类。List接口代表有序的集合,例如ArrayList和LinkedList;Set接口代表不允许重复元素的集合,...
Java 面试题大全 Java 是一种广泛使用的编程语言,本文总结了 Java 面试中常见的知识点,涵盖了 Java 基础、字符串操作、数据类型、运算符、抽象类等方面的知识。 Java 基础 1. JDK 和 JRE 的区别:JDK(Java ...
在Java编程语言中,`String`与`StringBuffer`是两个重要的字符串处理类,它们各自具有独特的特性和用途,尤其在面试或笔试中常被提及作为考察应聘者对Java基础知识掌握程度的重要知识点。 ### `String`类:不可变性...
除了以上具体功能的实现,笔试题还可能涉及Java的基础语法,如循环、条件判断、异常处理,以及数组、链表、栈、队列等基本数据结构的使用。 6. **面向对象编程**: 交通银行的笔试题也可能包含设计模式、继承、...
本文档概括了Java面试题的知识点,涵盖了Java基础知识、JSP&Servlet技术、J2EE相关知识、Web安全性、MVC、XML、structs、Session Bean、EJB、Java多线程、文件加密技术、软件开发生命周期、路由协议、Java AWT和...
### Java经典面试题知识点解析 #### 一、单项选择题知识点解析 1. **Java的起源** - **知识点**:Java的历史和发展。 - **解释**:Java是由Sun Microsystems公司的James Gosling等人于1995年创建的。它是在C++的...
Java笔试题汇总 本文档概括了Java笔试题,涵盖了Java的基础知识、Java集合框架、Spring框架、J2EE事务、Java多线程、UML类图等多个方面的知识点。 访问权限控制 在Java中,存在五种访问权限控制等级,从最宽松到...
本资料集涵盖了丰富的Java面试题,旨在帮助求职者准备Java相关的技术面试,以期在竞争激烈的IT市场中脱颖而出。 1. **Java基础** - 讲解Java的特性:自动内存管理(垃圾回收)、多线程支持、异常处理等。 - 面试...