可能重复:
Final arguments in interface methods - what’s the point?
在尝试尝试一些事情时,我遇到了this page中描述的问题。
interface B {
public int something(final int a);
}
abstract class C {
public int other(final int b);
}
class A extends C implements B {
public int something(int a) {
return a++;
}
public int other(int b) {
return b++
}
}
为什么这样的功能可能?我不知道为什么可以通过覆盖方法将最终参数变成非最终参数。为什么方法签名中忽略了final关键字?如何强制子类在其方法中使用最终变量?
答案 0 :(得分:7)
Java按值将参数传递给方法。
因此,参数的任何更改都不会传播回调用者。因此,无论参数是否被声明为final
,都与调用者完全没有区别。因此,它是该方法的实现的一部分,而不是其接口的一部分。
你想要“强制子类在他们的方法中使用最终变量”的动机是什么?
答案 1 :(得分:6)
final
仅表示不得在方法体内更改该值。这不是方法签名的一部分,与子类无关。
在接口或抽象方法中使用最终参数应该是无效的,因为它没有意义。
答案 2 :(得分:6)
最终变量是唯一可以在闭包中使用的变量。所以如果你想做这样的事情:
void myMethod(int val) {
MyClass cls = new MyClass() {
@override
void doAction() {
callMethod(val); // use the val argument in the anonymous class - closure!
}
};
useClass(cls);
}
这不会编译,因为编译器要求val
是最终的。所以将方法签名更改为
void myMethod(final int val)
将解决问题。本地最终变量也可以这样做:
void myMethod(int val) {
final int val0;
// now use val0 in the anonymous class
答案 3 :(得分:2)
Java的final
不是C ++ const
; Java中没有const-correctness这样的东西。
在Java中,人们使用不可变类来实现常量。事实证明它非常有效,因为与C ++不同,人们不能简单地弄乱内存。 (您可以使用Field.setAccessible(true)
,然后使用Reflection。但是,即使使用适当配置的安全管理器运行JVM,也可以防止损坏向量。)
答案 4 :(得分:1)
参数的final关键字不是方法签名的一部分,并且仅对方法主体很重要,因为Java会按值传递所有参数(值总是为方法调用创建)。 / p>
如果编译器强制我将其设置为final,我只使用final关键字(用于参数),因为该参数在方法中定义的匿名类中使用。
答案 5 :(得分:1)
在Java中,参数按值传递。参数是最终的还是不影响该方法,而不影响调用者。我不明白为什么一个类需要强制使用这些子类型。
答案 6 :(得分:1)
请注意,final
参数有一个主要目的:您无法为它们分配新值。
另请注意,参数始终按值传递,因此调用者不会在方法内看到对参数的任何赋值。
如果你真的想强制参数是最终的(为了防止在意外重新分配参数时可能引入的错误),请使用代码分析器,例如checkstyle。