方法签名中的最终关键字

SHi*_*KiT 7 java final method-signature

可能重复:
接口方法中的最终参数 - 重点是什么?

在试图尝试一些事情时,我遇到了一个问题,就在本页中描述了这个问题.

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++
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么这样的功能可能?我不知道为什么可以通过覆盖方法将最终参数变成非最终参数.为什么方法签名中忽略了final关键字?我如何强制子类在其方法中使用最终变量?

NPE*_*NPE 7

Java通过值将参数传递给方法.

因此,对参数的任何更改都不会传播回调用方.因此,无论声明参数是否final与调用者完全没有区别.因此,它是方法实现的一部分,而不是其接口的一部分.

你想要"强制子类在他们的方法中使用最终变量"的动机是什么?

  • "Java通过值将参数传递给方法." 这只有它们是原始的.对象参数传递指针样式,指针本身按值传递.因此,您可以在对象参数上调用mutator方法(如果愿意,甚至可以使用反射),调用者将看到这些更改.调用者唯一不会看到的是重新分配,因为你要重新分配副本,而不是他的副本. (8认同)
  • 它是一个原始变量; 它按值传递,因此默认受保护.声明对象引用final绝不会保护该对象的内容不被修改. (2认同)

Cep*_*pod 6

final对于参数,仅表示不得在方法体内更改该值.这不是方法签名的一部分,与子类无关.

在接口或抽象方法中使用最终参数应该是无效的,因为它没有意义.


Isr*_*man 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);
}
Run Code Online (Sandbox Code Playgroud)

这不会编译,因为编译器需要val是最终的.所以将方法签名更改为

void myMethod(final int val)
Run Code Online (Sandbox Code Playgroud)

将解决问题.本地最终变量也会这样做:

void myMethod(int val) {
    final int val0;
    // now use val0 in the anonymous class
Run Code Online (Sandbox Code Playgroud)