是在编译时计算的常量字节数组的新String()吗?

时间:2016-06-01 09:33:28

标签: java

我有一个常量字节数组,例如

static final byte[] myArray = "something".getBytes();

用于编写某处(XML,JMS ...),我想使用值“something”作为String而不声明一个新的常量(我知道我应该)。

我想知道,如果我写

anObject.setMessage(new String(myArray));

是在编译时计算的表达式new String(myArray)吗?

The java language specification表示在编译时只计算字符串文字,这不是字符串文字,但我不明白为什么在编译时不会对它进行评估。

2 个答案:

答案 0 :(得分:2)

  

表达式new String(myArray)是否在编译时进行了评估?

不,使用new String 始终 在运行时创建新的String引用。

答案 1 :(得分:2)

  

是在编译时计算的新String(myArray)表达式吗?

没有。它在运行时进行评估。

如果使用:

,可以在编译时对其进行评估
static final String myString = "something";

anObject.setMessage(myString);
  

我不明白为什么在编译时不会对它进行评估。

JLS Sec 15.9.4

中对此进行了描述
  

每次评估[类实例创建]表达式时,都会创建一个新对象。

但除此之外,如果您使用byte[]作为参数,它不是常量表达式:即使您无法为static final数组引用分配新值,您仍然可以更改数组元素。这应该引起关注,特别是因为myArray字段是(或至少看起来)是非私人的。

此外,new String(byte[])使用JVM的默认字符编码,可以在表达式的评估之间进行更改。

由于String是不可变的,因此static final String 常量。但是,这并不意味着如果使用字符串,可以在编译时对其进行评估,因为上面的JLS引用。