Частный финал против финального приватного

Несколько человек искали в Интернете и не смогли найти на это простого ответа. Моя проблема заключается в использовании Java в Android Framework, но я считаю, что это также стандартное поведение Java. Я понимаю определения final и private, которые используются для доступа к переменным и модификаторов. Я следил за некоторым кодом и учебными пособиями, когда в инструкциях меня просили инициализировать переменную как переменную final private. Не видя этого раньше, я вместо этого создал переменную private final. Позже код попросил меня инициализировать переменную в конструкторе, что явно не работает с переменной private final, поскольку она неизменяема. ОДНАКО, он не потерпел неудачу, когда я изменил переменную на final private ... что меня заинтересовало. Есть у кого-нибудь идеи, почему это так?

Спасибо за ответы!

Вы можете назначить окончательные необъявленные поля в конструкторе. Пожалуйста, покажите пример

OneCricketeer 27.06.2018 03:02
final private и private final - это то же самое. Порядок не имеет значения.
Elliott Frisch 27.06.2018 03:03
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
11
2
5 228
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Later on, the code asked me to initialize the variable in a constructor, which obviously fails against a private final variable as it is immutable.

Члены, помеченные как final, можно инициализировать в конструкторе. Вы можете либо создать параметризованный конструктор, который принимает значения извне класса, либо просто инициализировать эти члены напрямую с помощью объявления. Если вы выберете позже и тип данных будет примитивным, отметьте эти элементы как static, поскольку они останутся одинаковыми для всех экземпляров класса.

HOWEVER, it did not fail when I changed the variable to a final private... which made me interested

Это невозможно, поскольку private final и final private практически одно и то же и не имеют никакого значения. Однако первое считается хорошей практикой. Вы можете следить за этим ТАК для получения более подробной информации о заказе.

Я не согласен с частью ответа static. Вы можете, например, объявить final List<Object> objs = new ArrayList<>(), который запрещает каждому полю ссылаться на другой список, но сам список не является неизменным, поэтому каждый экземпляр может иметь разные списки с разным содержимым, и, следовательно, static неверен. Голосуйте против, пока эта часть ответа не будет удалена, поскольку она вводит в заблуждение.

Andreas 27.06.2018 03:16

@Andreas Спасибо за выделение. Обновил свой ответ. Я упустил этот момент

Sagar 27.06.2018 03:18

В качестве примера приведу несколько случаев, когда с final все в порядке, а что - нет. Нет никакой разницы между private final и final private. Чтобы добавить к тому, что сказал @Sagar, вы можете инициализировать переменные внутри строки или в конструкторе, но не то и другое вместе.

public class TestClass {

    private final String i1;
    final private String i2;
    private final String i3 = "test"; // ok
    private final String i4; // not ok, never initialized

    TestClass() {
        i1 = "test1"; // ok
        i2 = "test2"; // ok
        i3 = "test3"; // not ok, overrides already set value
    }

    void mod() {
        i1 = "test0"; // not ok, can't edit final i1
    }
}
Ответ принят как подходящий

Спецификация языка Java, раздел 8.3.1. Модификаторы поля, говорит:

FieldModifier:
  (one of)
  Annotation public protected private
  static final transient volatile

If two or more (distinct) field modifiers appear in a field declaration, it is customary, though not required, that they appear in the order consistent with that shown above in the production for FieldModifier.

Это означает, что private final - это стиль предпочтительный, но он точно такой же, как final private.

Честно говоря, я всегда так думал. Я использую IntelliJ / Android Studio, и по какой-то причине интерпретатор кричал до того, как я фактически скомпилировал его, заявив, что я не могу попытаться сделать то, что пытался сделать. По какой-то причине об этом больше не говорится, поэтому я, честно говоря, понятия не имею, что произошло, но, тем не менее, я ценю ясность на случай, если у кого-то еще возникнет такая же проблема!

DustNSummers 27.06.2018 03:53

Большинство статических анализаторов, средств проверки стиля и т. д. @ShoeShiner отмечают отклонения от порядка, указанного в JLS, как проблемы - возможно, вы видели один из этих советов?

Hulk 27.06.2018 10:57

private final и final private не имеют разницы. Для модификаторов доступа порядок не имеет значения. Таким образом, они оба будут вести себя одинаково.

Попробуй это:

public class Test {

    private final String privateFinal;
    final private String finalPrivate;

    public Test() {
        privateFinal = "Private Final";
        finalPrivate = "Final Private";
    }
}

Приведенный выше код компилируется абсолютно нормально.

они одно и то же. частный финал> финал частный

Другие вопросы по теме