在SCJP的书中,我得到Kathy Sierra的观点,他们不是java中的最终对象。 java中只有最终的引用变量。
但我认为字符串类的对象是最终的。一旦初始化,他们的状态就无法改变。
现在的问题是字符串类的对象是否为final。 如果它们不是字符串类的对象是如何不可变的。
由于
答案 0 :(得分:4)
但我认为字符串类的对象是最终的。一旦初始化,他们的状态就无法改变。
不,它们在Java意义上不是final
。它们是不可变的,但final
纯粹与变量/数据成员有关,而不是对象。
以下是一个例子:
final String a = "foo";
String b = "bar";
b = "updated bar"; // Compiles and works, `b` (the variable) can be changed
a = "updated foo"; // Won't compile, you're not allowed to change the `a` variable
final
是关于是否可以更改“变量”的值,而不是关于是否可以更改对象的状态。
以下是一个引用可变对象的final
变量的示例:
final Map a = new HashMap();
a.add("foo", "bar"); // Works; we're not changing `a`, we're changing the state
// of the object `a` refers to
只是完全取出物品:
final int a = 5;
a = 6; // Won't compile, because we aren't allowed to change `a`
答案 1 :(得分:1)
首先你必须阅读:
因为在Java中,final关键字可以在几个不同的上下文中使用。
String类是不可变的,这意味着在创建后此对象的状态无法更改并且也被声明为final,这意味着它不能被子类化。
答案 2 :(得分:0)
你必须发布章节(顺便说一下,请不要完全给出上下文),但我可以进一步区分这两个概念。
final是java中的一个关键字,在您的情况下适用于引用变量。这意味着一旦对象被实例化,该变量就不能分配给另一个对象,即,如果你这样做:
final String[] stringArray = new String[8];
你再也不能这样做了:
stringArray = new String[2];//stringArray is final and cannot be reassigned
但是,这并不表示如果无法更改stringArray的内容。你可以这样做:
stringArray[3] = "Hey!";
它会编译得很好。这表明只能将引用重新分配给其他任何内容;我们只是在这里谈论参考文献。
当他们说String是不可变的时,他们正在谈论String常量池。在字符串常量池中,有一组已在内存中创建的字符串,这些字符串是为了重用而存储的。如果你说,例如:
String tempString1 = "yo";
String tempString2 = "yo";
您只在字符串常量池(字符串所在的内存的特殊部分)中创建了1个字符串对象,并将其分配给两个不同的引用变量。如果你这样做:
tempString2 = "hey";
String tempString3 = "yo";
你只在字符串常量池中再次创建了1个新对象"嘿" tempString1只改变它指向的内容,而tempString3正在重用"哟"已经创建了。
如果你这样做是因为你对Java很不满意:
tempString1 = tempString2 + tempString3;
String tempString4 = tempString2 + tempString3;
String tempString5 = tempString2 + tempString3;
你只创建了1个字符串" heyyo"。 "哟" "哎"和" heyyo"是String常量池中唯一的字符串。
你做的任何操作都不会改变"嘿嘿"和"哟"在字符串常量池中,即使您可能将输出更改为显示为这些字符串已更改。