Koe*_*nie 7 java setter final const
我一直在用java编程,最近我开始学习一些c ++.
在C++中,将setter params设置为const是常规的,为什么我们在java中看不到这一点?
我的意思是创建一个像这样的setter有任何缺点:
public void setObject(final Object o){ this.o=o; }
Run Code Online (Sandbox Code Playgroud)
VS
public void setObject(Object o){ this.o=o; }
Run Code Online (Sandbox Code Playgroud)
第一个应该强制Object param o在整个set函数中保持不变,不是吗?
编辑:
最后一个参数将强制执行此操作:
public void setName(String name){
name="Carlos";
this.name=name;
}
Run Code Online (Sandbox Code Playgroud)
用户将永远无法设置与"Carlos"不同的名称
将Java方法参数设置为final是没有什么好处的,因为它不会阻止某人更改方法中的参数引用状态.它所阻止的只是将参数变量重新赋值给其他东西,这对原始引用没有任何作用,它允许在匿名内部类中使用该参数.如果您希望在这种情况下获得真正的安全性,那么您应尽可能使参数类型不可变.
编辑
您发布的:
public void setObject(Object o){
o++; // this does not compile
this.o=o;
}
Run Code Online (Sandbox Code Playgroud)
其中混合了原始数字和引用类型.只有o是Integer或其他数字包装类才有意义,即使这样,最终也不会阻止某人创建:
private void setI(final Integer i) {
this.i = 1 + i;
}
Run Code Online (Sandbox Code Playgroud)
但是上面的代码和上面的代码都不会影响调用代码端的参数对象.
编辑
确定现在你发布了:
public void setName(String name){
name="Carlos";
this.name=name;
}
Run Code Online (Sandbox Code Playgroud)
但是有人可以写
public void setName(final String name){
this.name= name + " Carlos";
}
Run Code Online (Sandbox Code Playgroud)
这就是危险来临的地方,也是最终无济于事的地方.假设您有一个名为Name的类:
public class Name {
private String lastName;
private String firstName;
public Name(String lastName, String firstName) {
this.lastName = lastName;
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
Run Code Online (Sandbox Code Playgroud)
然后是一个类,Foo,带有Name字段和setter.这是危险的代码:
class Foo {
private Name name;
public void setName(final Name name) {
name.setFirstName("Carlos");
this.name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
因为它不仅改变了字段的状态,它还改变了调用代码中Name引用的状态,而final修饰符对一位没有帮助.解决方案:使名称不可变.
例如,
import java.util.Date;
// class should be declared final
public final class BetterName {
private String lastName;
private String firstName;
private Date dateOfBirth;
public BetterName(String lastName, String firstName, Date dob) {
this.lastName = lastName;
this.firstName = firstName;
// make and store a private copy of non-immutable reference types
dateOfBirth = new Date(dob.getTime());
}
// only getters -- no setters
public String getLastName() {
return lastName;
}
public String getFirstName() {
return firstName;
}
public Date getDateOfBirth() {
// return copies of non-immutable fields
return new Date(dateOfBirth.getTime());
}
}
Run Code Online (Sandbox Code Playgroud)
好的,final
不能将参数/变量分配给它。由于Java编译器需要能够确定变量/参数是否实际上是最终的(对于匿名内部类),因此优化不是AFAIK的因素。
C ++具有更大的工具集,而Java尝试减少了更多的工具集。因此,使用C ++ const string&
很重要,
const string&
。现在的java:
回到您的问题:
作为Java中的setter,大多数人不会从final参数中受益。最终将是不使用该变量进行第二次分配的合同。
然而:
public final void setXyz(Xz xyz) {
this.xyz = xyz;
}
Run Code Online (Sandbox Code Playgroud)
更为有用:此方法不能被覆盖,因此可以在构造函数中安全使用。(在构造函数中调用重写方法将处于尚未初始化的子实例的上下文中。)