首页 > java > 我们可以说指向不可变对象的引用变量是一个常量变量吗?

我们可以说指向不可变对象的引用变量是一个常量变量吗? (Can we say that the reference variable pointing to an immutable object is a constant variable?)

2017-06-22 javastring

问题

我对stackoverflow中对以下问题的答案之一有疑问:

以下代码创建了多少个String对象?

String x = new String("xyz");
String y = "abc";
x = x + y; 

在斯蒂芬的回答中,他提到x和y不是常数变量。

我的疑问 - String是一个final类,它的实例将是一个常量,因为String是一个不可变的类。为什么这个常量类的引用变量不是常量变量?- 我确实同意Stephen的意见,因为x = x + y;在堆内存中创建了“xyzabc”。

解决方法

您需要了解一些概念。

将类标记为final不会使其不可变。它只是使它不可继承。

JLS§8.1.1.2

如果一个类的定义完整且不需要或不需要子类,则可以将其声明为final。

如果最终类的名称出现在另一个类声明的extends子句(第8.1.4节)中,则是编译时错误; 这意味着最终的类不能有任何子类。

当一个类在初始化后无法更改它所存储的值时,它被认为是不可变的。

常量变量是标有的变量final

JLS§4.12.4

变量可以声明为final。最终变量只能分配一次。声明变量final可以作为有用的文档,它的值不会改变,可以帮助避免编程错误。

如果分配了最终变量,则为编译时错误,除非在分配之前它是明确未分配的(第16段)。

xy这里不是常数,因为他们都没有标注final就是这样

“但字符串不能改变,所以它们是常数,对吧?” 你可能会问。

String对象本身不能改变,但字符串变量可以。我会给你看:

String s = "Hello";
s = "Goodbye";

变量的值被更改,以便它引用另一个字符串。原始字符串“Hello”未更改。

问题

I have a doubt from one of the answers in stackoverflow to the following question:

How many String objects are created by the following code?

String x = new String("xyz");
String y = "abc";
x = x + y; 

In Stephen's answer he mentioned x and y are not constant variables.

My doubt- String is a final class, and it's instance will be a constant because String is an immutable class. Why is the reference variable of this constant class not a constant variable? - I do agree with Stephen though as x = x + y; points at "xyzabc" created in the heap memory.

解决方法

There are a few concepts that you need to understand.

Marking a class as final does not make it immutable. It just makes it un-inheritable.

JLS §8.1.1.2

A class can be declared final if its definition is complete and no subclasses are desired or required.

It is a compile-time error if the name of a final class appears in the extends clause (§8.1.4) of another class declaration; this implies that a final class cannot have any subclasses.

A class is said to be immutable when the values that it stores cannot be changed after initialisation.

A constant variable is a variable marked with final.

JLS §4.12.4

A variable can be declared final. A final variable may only be assigned to once. Declaring a variable final can serve as useful documentation that its value will not change and can help avoid programming errors.

It is a compile-time error if a final variable is assigned to unless it is definitely unassigned (§16) immediately prior to the assignment.

x and y here are not constants because they are not marked final. That's it.

"But strings can't change, so they are constants, right?" you might ask.

String objects themselves can't change, but string variables can. I'll show you:

String s = "Hello";
s = "Goodbye";

The variable's value is changed so that it refers to another string. The original string "Hello" is not changed.

相似信息