Java 静态最终字符串=";“什么?”静态有意义吗?
我想知道这样的声明在Java中是否有某种意义。我在代码中发现了数千次,但我学习和使用字符串时发现,无论您声明了多少次Java 静态最终字符串=";“什么?”静态有意义吗?,java,string,immutability,object-pooling,Java,String,Immutability,Object Pooling,我想知道这样的声明在Java中是否有某种意义。我在代码中发现了数千次,但我学习和使用字符串时发现,无论您声明了多少次String对象:如果您之前的某个类声明了该字符串,则该字符串将被合并和重用(我指的是在没有显式构造函数调用的情况下创建的字符串) 实际上,这段代码在调用compare时打印true,因此这两个变量引用的是同一个对象。表示不能重新定义final变量,在这种情况下,静态字是完全无用的。我没抓住重点吗 还有几件事: 1-为什么显式调用String构造函数不会导致字符串合并?使用新字符串
String
对象:如果您之前的某个类声明了该字符串,则该字符串将被合并和重用(我指的是在没有显式构造函数调用的情况下创建的字符串)
实际上,这段代码在调用compare时打印true
,因此这两个变量引用的是同一个对象。表示不能重新定义final
变量,在这种情况下,静态
字是完全无用的。我没抓住重点吗
还有几件事:
1-为什么显式调用String
构造函数不会导致字符串合并?使用新字符串(“hello”)
打印false
,上面的代码相同
2-池行为是否保留给字符串?还有一些其他的不可变对象(比如BigInteger),但我认为它们不是池化的。。。为什么?
谢谢,
Carlo静态
意味着对于为该类创建的每个新对象,字符串构造和池只需发生一次。这在计算上节省了一点
public class StringCompare {
private void toCompare(String h) {
String x = "hello";
System.out.println( x == h);
}
public void compare() {
String h = "hello";
toCompare(h);
}
}
是两个字符串
文本。它们位于公共池(字符串池的一部分)中。有相同的参考文献。然后==
检查您将获得的参考true
如果使用String x=new String(“hello”)
,它将创建一个新的String
对象x
。当然是指新的参考资料。现在比较参考给你false
这是因为String=“hello”
或String h
没有在堆中创建任何对象,这些对象都存储在String常量池中,其中为新字符串(“hello”)代码>在堆中创建一个新对象,这样地址就会不同
检查详细信息开发人员使用此模式有几个原因,即使您对运行时行为及其对字符串池的使用的分析是正确的
它更清晰地传达了开发人员的意图。具体来说,字符串现在有了一个比常量更清晰的名称,并且它传递了并非每个人都知道(或者他们不时忘记)的运行时行为
如果开发人员希望更改源文件中的值,并且该值已在多个位置使用,那么只有一个位置可以进行更改
一旦决定使用变量,关键字static将意味着内存使用率更低。也就是说,只有一个字段用于存储ref,而不是每个对象实例一个字段
关于你接下来的问题:
问:为什么显式调用字符串构造函数不会导致字符串被合并?以上代码使用新字符串(“hello”)打印错误
因为字符串池仅用于字符串文本,如JLS所述,调用构造函数并没有被归类为字符串文本
Q:池行为是否保留给字符串李>
字符串池仅用于字符串文本,但当然还有其他缓存用于不同的用例。最明显的一点是用来优化int的自动装箱的int缓存。在这种情况下,即使static没有给您带来内存优势,您仍然可以以静态方式访问字段,因此不需要实例。例如,您经常使用一些URI,因此创建以下类:
String x = "hello";
String h = "hello";
使用static,你只需使用Uris.GOOGLE
而不是newUris()。GOOGLE
这个词“static”是让类访问而不是实例。我不得不说,你对“完全无用”有一个奇怪的定义。你的问题到处都是,您对static和final的关注与literal和新字符串之间的差异无关;字符串池的存在在很大程度上是另一个问题。@MarkRotterVeel我关心池和静态字,当引用池对象的变量被声明为final时。我不认为我的问题是“到处都是”,我只是想理解在一个集合的不可变对象/stringA static(final)是一个常量中发生了什么。也就是说:您为该字符串指定了一个标签,这样您就可以从整个程序中访问它,并且可以确保始终使用正确的值。从内存保护的角度来看,它可能是与文本相同的字符串对象,但这不是使用静态final常量的原因。我没有考虑字段访问,因为我经常发现变量声明为private。但是你的考虑是正确的,谢谢你的回答。关于可读性/意图的第1点,我同意:问题是关于运行时环境的——我仍然不理解只合并文本的决定,我将研究JLS,这背后可能有一些原因decision@CarloBertuccini在创建JLS时,字符串池存储在perm gen中。。那时候是在垃圾堆上,但从来没有垃圾收集过。由构造函数创建的内部字符串可能会破坏堆。现在,这些谓词已经不再是真的了,但是插入确实要付出代价,当前的语言设计让开发人员可以控制何时需要插入字符串,何时不需要。@CarloBertuccini进一步挖掘,您还会在java类文件中遇到常量池;您必须深入研究JVM规范才能找到它。回到那时,这就是字符串文字的作用域,以及字符串的自动插入。它提供了与纯解释语言协同工作的设计。
String x = "hello";
String h = "hello";
public class Uris
{
public static final String GOOGLE = "http://google.com";
public static final String BBC = "http://bbc.co.uk";
}