栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

字符串文字,内部和反射

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

字符串文字,内部和反射

可以说这是HotSpot JVM错误。

问题在于字符串字面量的内部机制

  • java.lang.String
    在常量池解析期间,将懒惰地创建字符串文字的实例。
  • 最初,字符串常量在常量池中由
    CONSTANT_String_info
    指向的结构表示
    CONSTANT_Utf8_info
  • 每个类都有自己的常量池。也就是说,
    MyClass
    而且
    PrintStream
    有自己的一双
    CONSTANT_String_info
    /
    CONSTANT_Utf8_info
    CPOOL条目文字 “真”
  • CONSTANT_String_info
    首次被访问时,JVM启动解决进程。字符串实习是此过程的一部分。
  • 为了找到被禁派文字的匹配项,JVM将的内容
    CONSTANT_Utf8_info
    与中的字符串实例的内容进行比较
    StringTable
  • ^^^这就是问题所在。将来自cpool的原始UTF数据与Java
    char[]
    数组内容进行比较,该内容可以由用户通过Reflection欺骗。

那么,您的测试中发生了什么?

  1. f.set("true", f.get("false"))
    启动字面的决议 “真”
    MyClass
  2. JVM在
    StringTable
    匹配序列 “ true”时 未发现任何实例,并创建了一个新实例,并将
    java.lang.String
    其存储在中
    StringTable
  3. value
    该字符串来自的字符串
    StringTable
    通过反射替换。
  4. System.out.println(true)
    在类中启动字面量 “ true” 的解析
    PrintStream
  5. JVM将UTF序列 “ true” 与来自的字符串进行比较
    StringTable
    ,但未找到匹配项,因为该字符串已具有 “ false” 值。创建另一个 ‘true’ 字符串并将其放置在中
    StringTable

为什么我认为这是一个错误?

JLS§3.10.5和JVMS§5.1需要包含相同的字符序列串文字必须指向的同一个实例

java.lang.String

但是,在下面的代码中,具有 相同 字符序列的两个字符串文字的解析导致 不同的 实例。

public class Test {    static class Inner {        static String trueLiteral = "true";    }    public static void main(String[] args) throws Exception {        Field f = String.class.getDeclaredField("value");        f.setAccessible(true);        f.set("true", f.get("false"));        if ("true" == Inner.trueLiteral) { System.out.println("OK");        } else { System.out.println("BUG!");        }    }}

JVM的一个可能解决方法是将指向原始UTF序列的指针

StringTable
java.lang.String
对象一起存储,以便内部处理过程不会将cpool数据(用户无法访问)与
value
数组(可通过Reflection访问)进行比较。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/609687.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号