9

可能重复:
接口方法中的最终参数 - 有什么意义?

在尝试做一些事情时,我遇到了这个页面中描述的问题。

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

4

7 回答 7

8

Java 按值将参数传递给方法。

因此,对参数的任何更改都不能传播回调用者。由此可见,参数是否被声明final对调用者完全没有影响。因此,它是方法实现的一部分,而不是其接口的一部分。

您想要“强制子类在其方法中使用最终变量”的动机是什么?

于 2011-09-27T15:01:43.670 回答
7

finalfor a parameter only 表示不得在方法主体内更改该值。这不是方法签名的一部分,与子类无关。

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

于 2011-09-27T15:04:14.060 回答
7

最终变量是唯一可以在闭包中使用的变量。所以如果你想做这样的事情:

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)

将解决问题。局部 final 变量也可以:

void myMethod(int val) {
    final int val0;
    // now use val0 in the anonymous class
于 2013-01-01T21:55:54.277 回答
2

Javafinal不是 C++ const;Java 中不存在 const 正确性之类的东西。

在 Java 中,使用不可变类来实现 const-ness。事实证明它非常有效,因为与 C++ 不同,不能简单地弄乱内存。(您可以使用Field.setAccessible(true),然后使用反射。但即使是这种损坏向量也可以通过使用适当配置的安全管理器运行 JVM 来防止。)

于 2011-09-27T15:10:07.347 回答
1

参数的 final 关键字不是方法签名的一部分,仅对方法体很重要,因为 Java 按值传递所有参数(始终为方法调用制作值的副本)。

如果编译器强制我将其设为 final,我只使用 final 关键字(用于参数),因为该参数是在方法中定义的匿名类中使用的。

于 2011-09-27T15:02:50.380 回答
1

在 Java 中,参数是按值传递的。参数是否为最终参数不仅影响该方法,而不影响调用者。我不明白为什么一个类需要指定子类型。

于 2011-09-27T15:04:18.377 回答
1

请注意,final参数有一个主要目的:您不能为它们分配新值。

另请注意,参数始终按值传递,因此调用者不会在方法内看到对参数的任何分配。

如果您真的想强制参数为最终参数(以防止意外重新分配参数时可能引入的错误)​​,请使用代码分析器,例如 checkstyle。

于 2011-09-27T15:04:19.210 回答