Java 8 Java8-它会改变最终字符串变量的结束位置吗?

Java 8 Java8-它会改变最终字符串变量的结束位置吗?,java-8,metaspace,Java 8,Metaspace,我找不到这个问题,如果我的搜索技能没有找到,很抱歉 在Java 8之前,我相信如下声明: ... public final String someString = "Hi"; public final int someInt = 17; 最好声明为: ... public static final String someString = "Hi"; public static final int someInt = 17; 与后PermGen(现在的Metaspace)还有区别吗?-XX:+

我找不到这个问题,如果我的搜索技能没有找到,很抱歉

在Java 8之前,我相信如下声明:

...
public final String someString = "Hi";
public final int someInt = 17;
最好声明为:

...
public static final String someString = "Hi";
public static final int someInt = 17;

与后PermGen(现在的Metaspace)还有区别吗?
-XX:+UseStringDuplication
是否对该差异有任何影响(无论如何对于字符串)?

包含对象引用的变量对被引用对象没有影响。如果有,那会很奇怪,因为可能有很多不同的变量引用同一个对象

换句话说,我假设,您已经知道所有具有相同内容的字符串文本都引用相同的对象,因此如果您同时声明这两个对象

someString1
someString2
引用同一对象。那么,如果变量的声明对对象产生了影响,那么在这里哪一个应该是相关的呢

您甚至可以使用同一对象而不使用任何变量,例如

System.out.println("Hi");

声明变量
static
的原因要简单得多。它总是有相同的内容,所以没有理由为它的每个对象保留内存,只是为了总是从该常量读取相同的引用。事实上,由于这种声明是编译时常量,因此在运行时甚至不会读取它。

包含对对象引用的变量对引用的对象没有影响。如果有,那会很奇怪,因为可能有很多不同的变量引用同一个对象

换句话说,我假设,您已经知道所有具有相同内容的字符串文本都引用相同的对象,因此如果您同时声明这两个对象

someString1
someString2
引用同一对象。那么,如果变量的声明对对象产生了影响,那么在这里哪一个应该是相关的呢

您甚至可以使用同一对象而不使用任何变量,例如

System.out.println("Hi");

声明变量
static
的原因要简单得多。它总是有相同的内容,所以没有理由为它的每个对象保留内存,只是为了总是从该常量读取相同的引用。事实上,由于这样的声明是编译时常量,它甚至不会在运行时被读取。

同样,变量的类型对
字符串的存储方式没有影响。变量仅包含对对象的引用。当您在表达式中仅使用文字
“Hi”
时,操作期间引用将位于操作数堆栈上。当您通过非
静态
字段或数组引用字符串时,引用将位于普通堆中,当变量为
静态
时,引用可能位于元空间中。变量是否为
final
,对存储没有任何影响。不同内存区域中可能有多个引用指向同一
String
String文本,自Java 6以来,Perm Gen(或Metaspace)中从未出现过。Oracle/OpenJDK为类的所有静态字段创建了一个特殊的单例对象。您可以在堆转储中看到此对象。我想这取决于实现。@PeterLawrey确实如此,从Java 7开始,更新6,
intern()
将不再复制
字符串
(因为
offset
length
字段已经消失),从Java 9开始,内部数组将是
字节[]
数组),但是这些都独立于引用这些对象的字段的修饰符,并且依赖于实现(所以我们在这里讨论的是HotSpot/OpenJDK).@PeterLawrey从Java 9开始,它总是一个
字节[]
,我想他们不想在这里使用类型转换。但该数组包含iso-latin-1或utf-16编码字符串。该类型编码在一个
int
字段中,该字段包含一个或两个,允许用基本算术替换许多条件,因为该类型值反映字符在数组中需要多少字节。或者,它也可能是,并且代表偏移量/长度计算的偏移量,归结起来是相同的。我现在懒得查找源代码。同样,变量的类型对
字符串的存储方式没有影响。变量仅包含对对象的引用。当您在表达式中仅使用文字
“Hi”
时,操作期间引用将位于操作数堆栈上。当您通过非
静态
字段或数组引用字符串时,引用将位于普通堆中,当变量为
静态
时,引用可能位于元空间中。变量是否为
final
,对存储没有任何影响。不同内存区域中可能有多个引用指向同一
String
String文本,自Java 6以来,Perm Gen(或Metaspace)中从未出现过。Oracle/OpenJDK为类的所有静态字段创建了一个特殊的单例对象。您可以在堆转储中看到此对象。我想这取决于实现。@PeterLawrey确实如此,从Java 7开始,更新6,
intern()
将不再复制
字符串
(因为
offset
length
字段已经消失),从Java 9开始,内部数组将是
字节[]
数组),但是这些都独立于引用这些对象的字段的修饰符,并且依赖于实现(所以我们在这里讨论的是HotSpot/OpenJDK).@PeterLawrey从Java 9开始,它总是一个
字节[]
,我想他们不想在这里使用类型转换。但该数组包含iso-latin-1或utf-16编码字符串。该类型编码在一个
int
字段中,该字段包含一个或两个条件,允许用基本算术替换许多条件,如t