Question

I have a very simple question and just asking to know more about final method arguments.

final variables can be initialized just once in its life. In JAVA method arguments are accepted as pass by value and reference is also passed as a value.

Now my question is :

How method doesn't know that passed object is final and already initialized?

Here is sample code:

public static void xyz(Abc obj) {
    System.out.println("hash code in xyz method :"+obj.hashCode());
    obj = new Abc(); // here there is no issue to initialize it again
}

public static void abc() {
    final Abc obj = new Abc();
    //obj=new Abc(); // final variable can be initialized just once

    System.out.println("hash code in abc method :"+obj.hashCode());
    xyz(obj);
}

public static void main(String[] a) {
    abc();
}
Était-ce utile?

La solution 3

The obj variable in abc is not the same as the obj parameter in xyz. When you call xyz, xyz works with a copy of the reference (NOTE: this is not a copy of the object, but it's a copy of the reference). So when obj = new Abc() is executed in xyz, it modifies only the copy in xyz. It has no effect on the obj in abc(), because the reference is passed by value.

Autres conseils

That's because references are passed by value; you cannot reseat references in Java. If you reassign obj to something else, it only has been reassigned within the scope of the method and not within the calling-scope. So what you have is only a copy of the reference of the final variable.

Hence the "finality" of the original object isn't violated.

If you want to make the parameter final as well, you can simply do:

public String myMethod(final Object myParameter) {
   ...
}

I think you might be confusing final variables with immutability. Immutability is something entirely different. It means that the underlying object's state cannot be modified once initialized. The variable that refers to this object may or may not be final; it has nothing to do with the mutability or immutability of an object. Indeed, the object that a final variable points to can be modified (if it is mutable) and using final will not guard against that. What it does guard against is the possibility of reassignment.

Drawing time

    Object          Reference    
 [some object]  <---  1234

And your variable

       initialized with value
obj    ---------------------->    1234

It can no longer be changed because it is final.

When you use it as an argument

xyz(obj);
...
public static void xyz(Abc someRandomNameNotToBeConfused) {

Java takes the value of obj, the reference 1234 and binds it to someRandomNameNotToBeConfused.

Now

                                initialized with value
someRandomNameNotToBeConfused   ---------------------->    1234

But someRandomNameNotToBeConfused can be changed because it is not final. So if you had a second Abc object

    Object          Reference    
 [some object]  <---  1234
 [other object] <---  678

You could change the reference that someRandomNameNotToBeConfused holds

someRandomNameNotToBeConfused = new Abc(); // 678

becomes

                                reassigned to
someRandomNameNotToBeConfused ------------------> 678

The variable obj in the calling method remains the same.

The reference is final, but the object it points at is not. When the reference is passed into xyz, it is copied, so the original reference is not modified.

There is no reason why the copy of a final reference is also final. The reference in abc() was final, but the reference in xyz() is not.

If you are coming from a language like C++, this might look like a const violation where a const reference is passed into a function that has a non-const parameter, but Java's final does not work that way.

Note that the hashCode() can be overwritten by the object's class definition, so it may be equal even if a new object is created.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top