Должны ли конечные поля класса Java всегда быть статическими?

Я не мог найти никаких упоминаний в Интернете об этом. Но просто хотел узнать, всегда ли конечные поля в классе должны быть static или это просто соглашение. Основываясь на моем понимании их использования, я чувствую, что это более логично, чем то, что навязывается языком.


person Karthick S    schedule 16.02.2013    source источник


Ответы (8)


Конечно нет. Они должны быть статическими, если принадлежат классу, и не быть статическими, если принадлежат экземпляру класса:

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
}
person JB Nizet    schedule 16.02.2013

Нет, абсолютно нет, и это не условность.

static и final — это совершенно разные вещи. static означает, что поле относится к типу, а не к какому-либо конкретному экземпляру типа. final означает, что поле не может изменить значение после первоначального присвоения (что должно произойти во время инициализации типа/экземпляра).

Поля static final обычно предназначены для констант, тогда как поля экземпляра со значением final обычно используются при создании неизменяемых типов.

person Jon Skeet    schedule 16.02.2013

Они не всегда собираются вместе, и это не условность. Поля final часто используются для создания неизменяемых типов:

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;
    }

}

С другой стороны, поля static, но не final не так уж распространены и довольно сложны. static final часто встречается, поскольку означает константу для всего приложения1.

1 — если быть точным, для всего загрузчика класса

person Tomasz Nurkiewicz    schedule 16.02.2013

Конечные поля не должны обязательно быть статическими, и иногда может быть полезно иметь нестатическую конечную переменную экземпляра. Поля, помеченные как static, так и final, обычно используются для констант, например:

public static final int BORDER_WIDTH = 5;

Однако иногда вы увидите нестатическое конечное поле, когда объект имеет неизменяемое свойство. Однако обычно нестатические поля final по обычным причинам по-прежнему помечаются private, так что это скорее дополнительная проверка, чтобы компилятор мог убедиться, что вы больше никогда не устанавливаете свойство.

person Alexis King    schedule 16.02.2013
comment
Это не только дополнительная проверка. Заключительные поля обеспечивают дополнительные гарантии безопасности потоков. - person JB Nizet; 16.02.2013

Если вы хотите получить к ним доступ как ClassName.FIELD, то да, вы должны это сделать. Если вы не сделаете его статическим, вам придется сделать что-то вроде new ClassName().FIELD, что является ненужным и бессмысленным созданием объекта.

Однако, если вы используете его только в классе или делаете его private, не делайте его статическим. Если вы находитесь в реальном классе, вы можете просто сделать FIELD.

Чтобы полностью понять эту концепцию, вы должны знать, что означает static. Статический означает, что он принадлежит фактическому классу, а не его экземпляру.

person tckmn    schedule 16.02.2013

Точно нет. Рассмотреть возможность:

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

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

Отбросьте final, и класс станет изменяемым. Добавьте static, и все ваши точки будут одинаковыми, и нет никакого законного способа написать конструктор.

person Eric    schedule 16.02.2013

Точно нет. Например, неизменяемые объекты имеют final свойств, которые могут быть установлены конструктором только один раз.

Для получения дополнительной информации см.: http://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html

Неизменяемые объекты — не единственный случай использования final свойств, но они представляют собой очевидный пример их полезности.

person gd1    schedule 16.02.2013

Ответ - нет.

статический

  • #P3#
    #P4#

финал

  • #P6#
    #P7#
person ERROR Source Uncompilable    schedule 31.01.2018
comment
На самом деле конечные поля не обязательно должны быть постоянными. final просто означает, что ссылка не может быть изменена. Рассмотрим, например, final Map<K,V> x = new HashMap<>();. Карта x является окончательной, и тем не менее ее содержимое может быть изменено во время выполнения, поэтому оно не константа. - person Blake; 15.03.2018