java java中的immutable和final有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34087724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between immutable and final in java?
提问by nanospeck
I was recently asked this quesion. But was not able to explain concisely what exactly sets both these concepts apart.
我最近被问到这个问题。但是无法简明地解释这两个概念的区别。
For example
例如
Final and Immutable:
最终的和不可变的:
final String name = "John";
if I now write
如果我现在写
name = "Sam";
I will get a compiler error
我会收到编译器错误
Immutable:
不可变:
String name = "John";
name = "Sam";
it works.
有用。
I think this explains a part of it in application. But can I get a good, easy to understand explanation on both these topic?
我认为这在应用中解释了它的一部分。但是我能得到关于这两个主题的一个很好的、易于理解的解释吗?
回答by Mohammed Aouf Zouag
final
means that you can't change the object's reference to point to another reference or another object, but you can still mutate its state (using setter methods e.g). Where immutablemeans that the object's actual valuecan't be changed, but you can change its reference to another one.
final
意味着您不能更改对象的引用以指向另一个引用或另一个对象,但您仍然可以改变其状态(例如使用 setter 方法)。其中不可变意味着对象的实际值无法更改,但您可以将其引用更改为另一个。
Concerning the second part of your question (immutability part), the compiler creates a new String
object with the value of "Sam", and points the name
reference to it.
关于问题的第二部分(不变性部分),编译器创建一个String
值为“Sam”的新对象,并指向name
它的引用。
回答by Vivek Singh
final
ensure that the address of the object remains the same. Where as the Immutable
suggests that we can't change the state of the object once created.
final
确保对象的地址保持不变。正如所Immutable
暗示的那样,一旦创建对象,我们就无法更改对象的状态。
final
is just a keyword whereas Immutable
is a pattern.
final
只是一个关键字而是Immutable
一个模式。
In Case of your first question you have marked the variable as
final
, which means you would not be able to change the memory address of it and can't assign a value once more.In case of your second question
Immutable
ensures you can't change the state of the object you have created.
在第一个问题的情况下,您已将变量标记为
final
,这意味着您将无法更改它的内存地址,也无法再次赋值。如果出现第二个问题,请
Immutable
确保您无法更改已创建对象的状态。
回答by OldCurmudgeon
final
最后
The objectcannot be changed.
该对象不能改变。
final String s = "Hello";
// Not allowed.
s = "Bye";
immutable
不可变的
The contentsof the object cannot be changed.
对象的内容无法更改。
BigInteger one = BigInteger.ONE;
// Does not change `one` or `BigInteger.ONE`.
one.add(BigInteger.ONE);
// Have to do it this way.
BigInteger two = one.add(one);
回答by Ankur Singhal
When you have a field declared as final
, the reference will not change. It will always point at the same Object.
当您将字段声明为 时final
,引用不会更改。它将始终指向同一个对象。
if the Object is not immutable
, the methods on it can be used to change the Object itself - it is the same Object, but its properties have been changed.
如果对象不是immutable
,则可以使用其上的方法来更改对象本身——它是同一个对象,但其属性已更改。
回答by Damith Ganegoda
when you change the String, create new String object ('abcdef') and change the reference from 'abce'to 'abcdef'.But you can not remove 'abcd'. Only change the reference. That is immutable.
当您更改字符串时,创建新的字符串对象 ('abcdef') 并将引用从'abce'更改为'abcdef'。但您不能删除'abcd'。只更改参考。那是不可变的。
final:
最后:
Actually finalis a keyword.When you add it to variable, you can not change the reference.
其实final是一个关键字。当你把它加到变量中时,你不能改变引用。
回答by achin
When you use keyword "final", that means that you cannot change the reference of the object that the variable points to. So, in this case variable "name" cannot be made to point to another string object. However, please note that we can change the contents of the object since we are using a final reference. Also Strings in java are inherently immutable. i.e. you cannot change its contents. So, in your case, final will make a final reference to a string object. and since you can't change the variable to point to another string object, code fails.
当您使用关键字“final”时,这意味着您不能更改变量指向的对象的引用。因此,在这种情况下,变量“name”不能指向另一个字符串对象。但是,请注意我们可以更改对象的内容,因为我们使用的是最终引用。此外,java 中的字符串本质上是不可变的。即您不能更改其内容。因此,在您的情况下, final 将对字符串对象进行最终引用。并且由于您无法将变量更改为指向另一个字符串对象,因此代码失败。
See the code below to understand working of final variable.
请参阅下面的代码以了解最终变量的工作。
public class test {
public static void main(String[] args) {
final A aObject = new A();
System.out.println("Old value :" + aObject.a);
aObject.a = 2;
System.out.println("New value :" + aObject.a);
}}
class A {
public int a = 1;}
回答by Haseeb Anser
Immutable means that once the constructor for an object has completed execution that instance can't be altered.
不可变意味着一旦对象的构造函数完成执行,该实例就无法更改。
This is useful as it means you can pass references to the object around, without worrying that someone else is going to change its contents. Especially when dealing with concurrency, there are no locking issues with objects that never change
这很有用,因为这意味着您可以传递对对象的引用,而不必担心其他人会更改其内容。特别是在处理并发时,永远不会改变的对象不存在锁定问题
e.g.
例如
class Foo
{
private final String myvar;
public Foo(final String initialValue)
{
this.myvar = initialValue;
}
public String getValue()
{
return this.myvar;
}
}
Foo doesn't have to worry that the caller to getValue() might change the text in the string.
Foo 不必担心 getValue() 的调用者可能会更改字符串中的文本。
If you imagine a similar class to Foo, but with a StringBuilder rather than a String as a member, you can see that a caller to getValue() would be able to alter the StringBuilder attribute of a Foo instance.
如果您想象一个与 Foo 类似的类,但使用 StringBuilder 而不是 String 作为成员,您可以看到 getValue() 的调用者将能够更改 Foo 实例的 StringBuilder 属性。
final is a reserved keyword in Java to restrict the user and it can be applied to member variables, methods, class and local variables. Final variables are often declared with the static keyword in Java and are treated as constants. For example:
final 是Java 中用于限制用户的保留关键字,它可以应用于成员变量、方法、类和局部变量。在 Java 中,final 变量通常用 static 关键字声明,并被视为常量。例如:
public static final String hello = "Hello"; When we use the final keyword with a variable declaration, the value stored inside that variable cannot be changed latter.
public static final String hello = "Hello"; 当我们在变量声明中使用 final 关键字时,存储在该变量中的值不能在以后更改。
For example:
例如:
public class ClassDemo {
private final int var1 = 3;
public ClassDemo() {
...
}
}
Note: A class declared as final cannot be extended or inherited (i.e, there cannot be a subclass of the super class). It is also good to note that methods declared as final cannot be overridden by subclasses.
注意:声明为 final 的类不能被扩展或继承(即,不能有超类的子类)。还需要注意的是,声明为 final 的方法不能被子类覆盖。
Benefits of using the final keyword are addressed in this thread
此线程中解决了使用 final 关键字的好处
回答by Yug Singh
final String name = "John";
When you write the above your code is telling the compiler that the reference name
will always point to the same memory location. Now why I say memory location because it might happen that the object the reference is pointing to is mutable like array or list of integers. So if I say final int[] arr = {5,6,1};
I can do arr[2] = 3;
but I can't do arr = {3,4,5}
cause you will be trying to assign a new int[]
to finalvariable arr
which is a new memory location and seeing this compiler will show error.
当您编写上述代码时,您的代码告诉编译器该引用name
将始终指向相同的内存位置。现在为什么我说内存位置,因为引用指向的对象可能像数组或整数列表一样可变。因此,如果我说final int[] arr = {5,6,1};
我可以做arr[2] = 3;
但我不能做,arr = {3,4,5}
因为您将尝试int[]
为最终变量分配一个新的变量arr
,这是一个新的内存位置,并且看到此编译器将显示错误。
String name = "John";
name = "Sam";
Above the name
variable of type String
is immutablebecause String
in java is immutable
which means you can't change the state of the object pointed out by the reference name
once it is created and even if you change it to Sam
it is now a different object which is pointed by the reference name
and the previous object John
will have no reference and can be collected by garbage collector whenever it runs if it has no other references pointing to it.
上面的name
类型变量String
是不可变的,因为String
在 java 中immutable
,这意味着name
一旦创建引用就无法更改引用所指出的对象的状态,即使将其更改Sam
为现在也是由引用指向的不同对象引用name
,并且前一个对象John
将没有引用,并且如果它没有其他引用指向它,则只要它运行,垃圾收集器就可以收集它。
回答by Ankur Parikh
Immutable : String and wrapper classes are immutable. Because of the String constant pool they can't change their value inside an object, but they can change references of object holding different values.
不可变:字符串和包装类是不可变的。由于 String 常量池,它们不能更改对象内部的值,但它们可以更改持有不同值的对象的引用。
String s1 = new String("cant't change");
Final : when we create a reference of String
Final :当我们创建 String 的引用时
Final String s2 = "cant't change";
The reference for s2
is pointing to object which has value " can't change" inside it.
的引用s2
指向其中具有“无法更改”值的对象。
The reference s will now always point to the object holding value "can't change". It's reference can't be changed.
引用 s 现在将始终指向持有值“无法更改”的对象。它的引用无法更改。