Question

Possible Duplicate:
Final arguments in interface methods - what’s the point?

While trying to experiment a few things, I've ran into a problem that it's described in 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++
    }
}

Why is such feature possible? I don't know why it's possible to to make a final parameter into a non-final one by just overriding the method. Why is the final keyword ignored in a method signature? And how do I obligate sub-classes to use in their methods final variables?

Was it helpful?

Solution

Java passes arguments to a method by value.

Therefore, no changes to a parameter can propagate back to the caller. It follows that whether or not the parameter is declared final makes absolutely no difference to the caller. As such, it is part of the implementation of the method rather than part of its interface.

What's your motivation for wanting to "obligate sub-classes to use in their methods final variables"?

OTHER TIPS

final for a parameter only means that the value must not be changed within the method body. This is not a part of the method signature, and is not relevant to subclasses.

It should be invalid to have final parameters in interface or abstract methods, because it's meaningless.

Final variables are the only ones that can be used in closures. So if you want to do something like this:

void myMethod(int val) {
    MyClass cls = new MyClass() {
        @override
        void doAction() {
            callMethod(val);  // use the val argument in the anonymous class - closure!
        }
    };
    useClass(cls);
}

This won't compile, as the compiler requires val to be final. So changing the method signature to

void myMethod(final int val)

will solve the problem. Local final variable will do just as well:

void myMethod(int val) {
    final int val0;
    // now use val0 in the anonymous class

Java's final is not C++ const; there is no such thing as const-correctness in Java.

In Java, one achieves const-ness using immutable classes. It turns out to be quite effective because unlike C++, one cannot simply mess with memory. (You can use Field.setAccessible(true), and then use Reflection. But even that corruption-vector can be prevented by running the JVM with an appropriately configured security manager.)

The final keyword for arguments is not part of the method signature, and is only important for the body of the method, because Java passes all arguments by value (a copy of the value is always made for the method call).

I only use the final keyword (for arguments) if the compiler forces me to make it final, because the argument is used inside an anonymous class defined in the method.

In Java parameters are passed by value. Whether a parameter is final or not only affects that method, not the caller. I don't see why a class needs to obligate the subtypes.

Note that final parameters have one main purpose: you can't assign new values to them.

Also note that parameters are always passed by value, thus the caller won't see any assignments to the parameter inside the method.

If you really want to force parameters to be final (in order to prevent bugs that might be introduced when reassigning a parameter accidentially), employ a code anaylzer such as checkstyle.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top