Java基础面试——String“==”问题
来源:互联网 发布:mysql charindex 编辑:程序博客网 时间:2024/06/16 00:02
1.面试题一:
public static void main(String[] args) { String a = "helloworld"; String c = "hello"+"world"; if(a == c){ System.out.println("a=c"); }else{ System.out.println("a!=c"); }}
输出:a=c
解释:JVM在编译时会将 String c = “hello”+”world”; 优化成 “helloworld”。
- 然后编译器在常量池中查找是否有值相同的变量,存在则返回字符串的引用,不存在就将字符串存到常量池中,然后返回存入后字符串的引用。
所以,该题在常量池中查找“helloworld”,发现已存在,则返回常量池中的“helloworld”的引用,这样,String a和String c就指向了同一个引用,即a==c;
补充:
- 另外,其实正常情况下,执行 String c = “hello”+”world”; 这句话,会产生2个临时对象“hello”和“world”,最后的对象“helloworld”才会赋给String c,但由于JVM编译时优化,所以不会这样,而是会创建一个新对象StringBuilder,然后append()拼接,这样省去了多个临时对象的产生。
- 也就是说对于用“+”连接字符串时,JVM会创建一个StringBuilder并调用append()拼接字符串,然后使用toString()返回拼接好的字符串。如果连接的不止字符串,比如String c = “hello”+ 2;将String类型的“hello”和int型的“2”连接在一起,append()的各种重载方法也会处理好。
那么这样就能解释为什么非常不推荐类似这样的写法:
public static void main(String[] args) {String str = "ha"; for(int i = 0; i < 100; i++){ str += "ha"; }}
这个程序循环使用“+”会重复的创建许多个StringBuilder,性能降低,浪费内存,所以应该一开始就使用StringBuilder,然后不断append()。
2.面试题二:
public static void main(String[] args) { String a = "helloworld"; String b = "world"; String c = "hello" + b; if(a == c){ System.out.println("a=c"); }else{ System.out.println("a!=c"); }}
输出:a!=c
解释:编译 String c = “hello” + b; 这行代码时并不会像上面一样优化,b是一个变量,不是已知字符串字面量,所以编译器无法做出优化,到运行时才能知道b是什么,然后做拼接,最后保存为一个新地址,所以与String a不是同一个地址,即a != c。
3.面试题三:
public static void main(String[] args) { String a = "helloworld"; final String b = "world"; String c = "hello" + b; if(c == a){ System.out.println("c=a"); }else{ System.out.println("c!=a"); }}
输出:c=a
解释:当String b被final修饰为常量,会在常量池中有一个副本,编译时可以直接取到,而不是像面试题二中String b是不确定的,所以JVM也会将String c优化为“helloworld”,然后和String a指向同一个地址,即c==a。
4.面试题四:
public static void main(String[] args) { String a = "helloworld"; final String b = getString(); String c = "hello" + b; if(c == a){ System.out.println("c=a"); }else{ System.out.println("c!=a"); }}static String getString(){ return "world";}
输出:c!= a
解释:虽然String b是final,但是编译时是无法确定b的值的,那么就不会JVM编译时优化,只有在运行时才能知道getString()会返回什么,然后拼接成为String c,所以String a和String c不会是同一个地址,即c != a。
补充:
引号声明的字符串是会直接在字符串常量池中生成的。例如:
- String s = new String(“hello”)
则会生成常量池中的“hello” 和堆空间中的字符串对象s。
- Java基础面试——String“==”问题
- 【Java基础】10个有关String的面试问题
- java 面试基础问题
- java面试基础问题
- Java面试基础问题
- Java String中的面试问题
- java基础经典问题String str=new String("abc")和String str="abc"
- Java基础面试——传值问题
- JAVA面试问题—基础篇(上)
- JAVA面试问题—基础篇(下)
- java 之 --------------- String 面试基础的 题
- java面试基础问题 整合
- Java基础——String
- Java 基础——String
- Java基础—String类
- Java基础—String类
- (Java)关于String的面试问题
- 面试十大常见Java String问题
- 爬虫的综合案例
- 日记(周中)
- Android Study Material Design 二 之:这可能是RecyclerView最全解析 高级拓展 实现复杂布局(三)
- Linux上安装JDK+Mysql+Tomcat环境
- 配置vim
- Java基础面试——String“==”问题
- EL表达式使用fmt:formatNumber标签保留两位小数
- Codeforces 873 D Merge Sort(归并排序性质)
- 【面试】--mysql 默认隔离级别 where 语句最长多少字符,int(10)10表示多大,char(128)128多大(357)
- Git流程理解与深度解析
- listview复用原理
- Android Study Material Design 三 之:侧滑DrawerLayout ^_^
- Windows编程基础--第3节 初探MFC
- Pandas处理数据出现MemoryError与Anaconda的安装