Question

Why is the following code possible? (Just an example I just came up with while working on other code)

public String getLogIdentifierFromFile(final File file) {
    //this.file = null; //Gives compiler error as obviously expected
    nullify(file);
    return "";
}

public void nullify(Object object) {
    object = null;
}

And how can I ensure that the final from the top function actually has an effect? This time it is me making the nullify method, but it can also be anyone's code that my method needs to call.

Was it helpful?

Solution

The code doesn't do what you think it does.

final applies to the reference. Your code nulls out a non-final copy of the original final reference. The copy is taken when you call nullify().

If you examine file after calling nullify(), you will observe that it remains unchanged.

Thus, this isn't a loophole in how final works.

OTHER TIPS

The statement final File file make only the references as final. This is to ensure that you do not reassign value to this variable accidentally.

In your code object = null; // 'object' is not marked as a final reference. Hence it works

This is because object is not final in your second method.

So:

public String getLogIdentifierFromFile(final File file) {
    //Have a final reference to file
    //Pass it into nullify
    nullify(file);
    //Reference to file is unchanged
    return "";
}

And:

public void nullify(Object object) {
    //get a reference to some object
    //set it to null
    object = null;
}

Think of this as getLogIdentifierFromFile is passing a business card with the details of file to nullify and then nullify is scratching off the address on the card.

This does not affect where file lives, nullify just forgets where file lives.

Java is slightly confusing in this regard as it passes object references by value. This means that when you pass on your reference to another method it create a copy of the reference and passes that copy.

This means that if you carry out actions on the reference (such as File.setExecutable()) the actions will happen on the referenced object. If you change the reference itself, i.e. reassign it, then this only affects the local copy.

final only prevents the reassignment of a reference.

When you change object var you do not change file var - Java passes arguments by value not by reference

The nullify function (or any other function for that matter) receives a reference to an objects, and then changes the reference by assigning null to it. It does not change the original object or the original reference to the object, so the fact that was final is inconsequential.

       public String getLogIdentifierFromFile(final File file) {
          //this.file = null //Gives compiler error as obviously expected
              nullify(file);
           return "";
          } 

         public void nullify(final Object object) {
          object = null; //this will produce error

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