写点什么

58 字节常量池面试题,你如何应对?

用户头像
卢卡多多
关注
发布于: 3 小时前
58字节常量池面试题,你如何应对?

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&trade; 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;









发布于: 3 小时前阅读数: 6
用户头像

卢卡多多

关注

努力寻找生活答案的旅途者 2020.04.12 加入

公众号:卢卡多多,欢迎一起交流学习

评论

发布
暂无评论
58字节常量池面试题,你如何应对?