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

176 阅读3分钟

「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!」 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;