Final keyword in method signatures [duplicate]
Asked Answered
C

7

9

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?

Cornish answered 27/9, 2011 at 14:57 Comment(1)
final is not part of the method signature. How the subclass's method implements it is of no concern to the interface.Shanel
P
9

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"?

Paleobotany answered 27/9, 2011 at 15:1 Comment(5)
For me it does makes difference. I don't want to my variable to be changed in the caller method. It's original value must be preserved at all costs.Cornish
it's a primitive variable; it is passed by value and is thus protected by default. Declaring an object reference final in no way protects the contents of that object from modification.Precaution
It will be preserved, because Java always make a copy of the value before passing it to the method. If the method changes the argument value, it will change a copy, and the value of the caller method will always be unaffected, whether final is used or not.Nudd
Yes, I made I mistake. After working so much with objects, and therefore it passes an copy of a "pointer" of the object, I completly forgot about primitive variables and final classes, like Integer. Wheter it's a primitive value or a Final class, I don't have to worry, because the original value will be preserved. Thank you all who have answered!Cornish
"Java passes arguments to a method by value." This is only if they are primitive. Object arguments are passed pointer style, with the pointer itself being passed by value. Therefore, you can call mutator methods on an object argument (or even use reflection if you like), and the caller will see those changes. The only thing that the caller would not see is a reassignment, since you are reassigning a copy, not his copy.Danelle
A
7

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.

Ascocarp answered 27/9, 2011 at 15:4 Comment(1)
"It should be invalid to have final parameters in interface or abstract methods, because it's meaningless." Yes it should, and yes it is meaningless, but it's not invalid. :-)Danelle
W
7

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
Whereas answered 1/1, 2013 at 21:55 Comment(0)
U
2

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.)

Unparalleled answered 27/9, 2011 at 15:10 Comment(4)
I presume by "really funky things" you mean "reflection"? foo.getClass().getDeclaredField("bar").setAccessible(true) is all you need, on a VM that doesn't care.Danelle
Only if you have no security manager enabled. On teams I lead, we always install a security manager and whitelist access violations on a case by case basis. Contrast that to C++, where it is impossible to prevent (or even detect) a library from writing junk to memory.Unparalleled
You did say on a unsecured VM, hence, no security manager.Danelle
I see your point. Editing answer.Unparalleled
N
1

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.

Nudd answered 27/9, 2011 at 15:2 Comment(0)
A
1

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.

Alacrity answered 27/9, 2011 at 15:4 Comment(0)
R
1

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.

Randyranee answered 27/9, 2011 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.