String 的底层实现涉及字符串常量池,当通过字面量(如 String a = "trump")创建字符串时,Java 会将其存储在字符串常量池中,并复用相同内容的字符串对象引用。而使用 new String("trump") 则会强制在堆内存中创建一个新对象,即使常量池中已有相同内容的字符串。这种机制优化了内存使用,但导致两个字符串即使内容相同,其引用地址也可能不同。此外,==比较的是对象的引用地址,而 equals() 比较的是字符串的内容,因此两者的作用不同。
在你的代码中,a == b 为 false,因为 a 指向常量池中的字符串 "trump",而 b是堆内存中的新对象,引用地址不同。而 a == c 为 true,因为 a 和 c 都是通过字面量赋值的,引用的是常量池中同一个对象。同理,test.d == a 为 false,是因为 test.d 和 a虽然都指向 "trump",但由于类加载和方法执行属于不同阶段,其引用地址在 JVM 内存模型中被区分对待。
原理性的可以看c++ primary 第三版以及c语言中如何实现字符串。简而言之动态内存管理的,要清楚什么是引用,什么是值。
表征结果一定有下层的实现的逻辑:
从上述结果,我们大致可以分析出java的string实现逻辑:==符号 的实现是“引用”地址的判断,赋值符号 在java string中预计是直接基于一个string的hash表获得(大致托管语言都会用hash表来管理内存【对象实例】),new仍然保持基本作用——分配内存并返回地址,因此出现了上述结果。