方法签名中的最终关键字

时间:2011-09-27 14:57:36

标签: java final method-signature

  

可能重复:
  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关键字?如何强制子类在其方法中使用最终变量?

7 个答案:

答案 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。