Should a java class' final fields always be st

2019-02-11 19:04发布

问题:

I could not find any references online about this. But just wanted to know if final fields in a class should always be static or is it just a convention. Based on my understanding of their uses, I feel that it is more of a logical thing to do than something that is imposed by the language.

回答1:

Of course not. They must be static if they belong to the class, and not be static if they belong to the instance of the class:

public class ImmutablePerson {
    private static final int MAX_LAST_NAME_LENGTH = 255; // belongs to the type
    private final String firstName; // belongs to the instance
    private final String lastName; // belongs to the instance

    public ImmutablePerson(String firstName, String lastName) {
        if (lastName.length() > MAX_LAST_NAME_LENGTH) {
            throw new IllegalArgumentException("last name too large");
        }
        this.firstName = firstName;
        this.lastName = lastName;
    }

    // getters omitted for brevity
}


回答2:

No, absolutely not - and it's not a convention.

static and final are entirely different things. static means that the field relates to the type rather than any particular instance of the type. final means that the field can't change value after initial assignment (which must occur during type/instance initialization).

static final fields are usually for constants - whereas instance fields which are final are usually used when creating immutable types.



回答3:

They don't always come together and it's not a convention. final fields are often used to create immutable types:

class Person {

    private final String name;
    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

}

On the other hand static but not final fields are not that common and are quite tricky. static final is seen often because it means application1-wide constant.

1 - well, class loader-wide, to be precise



回答4:

Final fields do not need to be static, and sometimes it can be useful to have a non-static final instance variable. Fields that are marked both static and final are usually used for constants, like this:

public static final int BORDER_WIDTH = 5;

However, sometimes you'll see a non-static final field when an object has a immutable property. Usually, non-static final fields are still marked private for the usual reasons, though, so it's more of an extra check so the compiler can make sure you're never setting the property again.



回答5:

If you want to access them like ClassName.FIELD, then yes, you have to do that. If you don't make it static, you have to do something like new ClassName().FIELD, which is unnecessary and a pointless creation of an object.

However, if you are only using it in the class or making it private, then don't make it static. If you are within the actual class, you can just do FIELD.

To fully grasp this concept, you have to know what static means. Static means that it belongs to the actual class, not an instance of it.



回答6:

Absolutely not. Consider:

class Point {
    public final int x;
    public final int y;

    public Point(int _x, int _y) {
        x = _x;
        y = _y;
    }
}

Drop the final, and the class becomes mutable. Add a static, and all your points are the same, and there is no legal way to write the constructor.



回答7:

Absolutely not. Immutable objects, for example, have final properties, that can be set only once, by the constructor.

For more information, please see: http://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html

Immutable objects are not the only case in which final properties are used, but they provide a evident example of their usefulness.



回答8:

The answer is no.

static

  • "Indicates that only one such data field is available for all instances of this class. Without this modifier, each instance has its own copy of a data field"

    ...meaning there can only be one of this

final

  • "The value provided for the data field cannot be modified"

    ...meaning that this is a constant