简体   繁体   中英

At what point can a final variable in Java no longer be modified?

Take this block of code for example:

private final House house;

public static void main(String[] args)
{
    house = new House("Robinsons");
    house.setColor("Red");
}

Would this be a valid use of a final variable? Is it legal to modify it once it has technically been initialized but is being modified while still in the constructor?

final on a variable means the variable cannot be re-assigned after it's been assigned the first time.

Assuming your code compiled, this

house = new House("Robinsons");

is an assignment, so house would be assigned for the first time.

This

house.setColor("Red");

is a method invocation that does not affect the variable house . It affects the object referenced by the variable house .

I'm assuming you left some out, is this the complete code?

public class House {
    private final House house;

    public static void main(String[] args)
    {
        house = new House("Robinsons");
        house.setColor("Red");
    }

    public House(String houseName) {
        // do something
    }

    public void setColor(String color) {
        // do something 
    }
}

If so, there are a number of problems with this.

  1. a final variable needs to be given a value right on declaration. And to answer your question, once a final variable is given a value (when declaring it), that will be the last time you can modify it. (refer to comments below, thanks exception1!).
  2. House is not a static variable, so it cannot be accessed from inside the main method, either make house a static variable, which I wouldn't recommend. Or declare an instance inside the main method before using it.

From the JLS §8.1.3 :

A blank final instance variable must be definitely assigned (§16.9) at the end of every constructor (§8.8) of the class in which it is declared; otherwise a compile-time error occurs.

In effect, this means that, after your object is constructed, either with your own custom constructor, or the default no-arg constructor, your final variable must be assigned a value.

As it stands, that isn't a valid use of final ; the default no-arg constructor isn't capable of assigning it a value during its construction.

A slightly more appropriate usage would be this:

public class PersonsHome {
    private final House house;

    public PersonsHome(String houseName) {
        house = new House(housename);
    }
}

house is definitely assigned at the end of construction 1 , so the contract for final is satisfied.

1: I did mention the default no-arg constructor; that's only created if there's no other constructor around.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM