1.废话少说:我们直接上面试题?
当前字符串中 intern(),结果如何,细说一下原因?
package com.test.testdelete.controller;
import java.sql.SQLOutput;
/**
* @author 卢卡多多
* @create 2021-7-23 22:10
* @description 对于字符串,intern()输出对比?
*/
public class StringByte58 {
public static void main(String[] args) {
String lucas = new StringBuilder("58").append("tongcheng").toString();
System.out.println(lucas);
System.out.println(lucas.intern());
System.out.println(lucas == lucas.intern()); //TURE
System.out.println("-------------------------------");
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2);
System.out.println(str2.intern());
System.out.println(str2 == str2.intern()); //FALSE
}
}
复制代码
只有 java 是错误的,其实都是都是正确的表示
解析 Intern 的方法,
源码:
/**
* Returns a canonical representation for the string object.
* <p>
* A pool of strings, initially empty, is maintained privately by the
* class {@code String}.
* <p>
* When the intern method is invoked, if the pool already contains a
* string equal to this {@code String} object as determined by
* the {@link #equals(Object)} method, then the string from the pool is
* returned. Otherwise, this {@code String} object is added to the
* pool and a reference to this {@code String} object is returned.
* <p>
* It follows that for any two strings {@code s} and {@code t},
* {@code s.intern() == t.intern()} is {@code true}
* if and only if {@code s.equals(t)} is {@code true}.
* <p>
* All literal strings and string-valued constant expressions are
* interned. String literals are defined in section 3.10.5 of the
* <cite>The Java™ Language Specification</cite>.
*
* @return a string that has the same contents as this string, but is
* guaranteed to be from a pool of unique strings.
*/
public native String intern();
复制代码
1.为什么说只有 Java 是错误的?
java, java.intern
为什么其他的对象可以直接在常量池中返回,但是就是 java 这个字符串不行呢;
也就是说,我们自己建立的 string 的 java 字符不是不想同,如果相同就会直接是 true;
因为"java "这个是 Java 自己 JDK 自带的,在加载 sun.misc.Version 这个类的时候进入常量池
demo:
package com.atguowang.thirdinterview.javabase;
/**
* @author 卢卡多多
* @description 字符串常量池的面试
**/
public class TestString58 {
public static void main(String[] args) {
// String str1=new StringBuffer("2020/10/20").append("22:45").toString();
// //打印
// System.out.println(str1);
// System.out.println(str1.intern());
// //打印
// System.out.println(str1 == str1.intern());
String str2=new StringBuffer("ja").append("va").toString();
//打印
System.out.println(str2);
System.out.println(str2.intern());
System.out.println("java".intern());
System.out.println(str2 == str2.intern());
System.out.println("java" == "java".intern());
System.out.println(str2 == "java");//引用地址不同
//
// String str3=new StringBuffer("hell").append("alibaba").toString();
// //打印
// System.out.println(str3);
// System.out.println(str3.intern());
// //打印
// System.out.println(str3 == str3.intern());
}
}
复制代码
2.面试题:"java"=="java".intern()的答案是什么?,如何理解?
也就是说,当我们使用的过程中,jdk,底层已经有个"java"的字符串字面量了,所以我们自己创建一个 java 对象的 String 的对象,然后我们可以将数据对比的时候,(假设 str=="java")
str == str.intern();
其实 str.intern();(native 的是运行计算机底层的本地的,如果说存在这个对象,直接存常量池中取出来,然后去返回,)要是不存在吗,就创建一个然后直接返回,并将创建好的数据转化为具体的----》常量池中;
现在来揭晓答案:
第一个为 false,是因为 str1 虽然是“Java”,但是对于 Str.intern()的时候,我们 JDK 底层,jdk/jre/lib/rt.jar/sun.misc/version 类中有具体一个表示,已经明确的实例化出“java”的数据,将这个数据放到了常量池中,所以展示的两个“java”,一个来源于自己创建的,一个是底层已经定义好的,引用地址不一样,所以 false;
第二个为 ture: 因为他是直接的字面量,不是通过 new 得来的 String 对象,我们底层 JDK 已经实现了常量池,所以他们会复用返回,--->TUREl;
至于第三个:false,因为 String 是一个引用类型的数据,==表示对比的事引用对象的地址;
一个是自己创建的时候,从内存中开辟空间得出的,一个是 JDK 自己已经有存放在常量池中的数据;
3.JDK 8 的深层次的源码解析:
System--》initializeSystemClass-->sun.misc.version=java;
评论