Используя “заключительный” модификатор каждый раз, когда применимо в [закрытом] Java

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

189
задан Peter Mortensen 20 December 2017 в 12:21
поделиться

23 ответа

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

Добавление final ко всем вещам, которые не должны , изменение просто сужает возможности, что Вы (или следующий программист, работающий над Вашим кодом), будете неправильно истолковывать или неправильно использовать мыслительный процесс, который привел к Вашему коду. По крайней мере, это должно позвонить в некоторые звонки, когда они теперь хотят изменить Вашу ранее неизменную вещь.

Сначала, это вид взглядов, неудобных видеть много из final ключевые слова в Вашем коде, но довольно скоро, Вы прекратите замечать само слово и будете просто думать, that-thing-will-never-change-from-this-point-on (можно взять его от меня;-)

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

177
ответ дан Johan Pelgrim 23 November 2019 в 05:39
поделиться

Используя финал для констант сильно поощряется. Однако я не использовал бы его для методов или классов (или по крайней мере думал бы об этом некоторое время), потому что это делает тестирование тяжелее, если не невозможный. Если абсолютно необходимо сделать класс или финал метода, удостоверьтесь, что этот класс реализует некоторый интерфейс, таким образом, Вы можете иметь насмешка реализация того же интерфейса.

-1
ответ дан Paweł Hajdan 23 November 2019 в 05:39
поделиться

Отмечание финала класса может также заставить некоторую привязку метода произойти во время компиляции вместо времени выполнения. Рассмотрите "v2.foo ()" ниже - компилятор знает, что B не может иметь подкласса, таким образом, нечто () не может быть переопределено так, реализация для вызова известна во время компиляции. Если класс B НЕ отмечен финал, то возможно, что фактический тип v2 является некоторым классом, который расширяет B и переопределяет нечто ().

class A {
    void foo() {
        //do something
    }
}
final class B extends A {
    void foo() {
    }
}
class Test {
    public void t(A v1, B v2) {
        v1.foo();
        v2.foo();
    }
}
0
ответ дан Eugene 23 November 2019 в 05:39
поделиться

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

Однако при нахождении обязанность поместила много заключительных операторов в коде. Это могло бы быть хорошей подсказкой, Вы делаете что-то не так.

статья, отправленная выше, дает этот пример:

public void doSomething(int i, int j) {
    final int n = i + j; // must be declared final

    Comparator comp = new Comparator() {
        public int compare(Object left, Object right) {
            return n; // return copy of a local variable
        }
    };
}
0
ответ дан Hans Sjunnesson 23 November 2019 в 05:39
поделиться

Я использую его для констант внутри и снаружи методов.

я только иногда использую его для методов, потому что я не знаю, не хотел ли подкласс переопределять данный метод (по любым причинам).

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

IntelliJ IDEA предупреждает Вас, если параметр функции записан во внутреннюю часть функция. Так, я прекратил использовать финал для аргументов функции. Я не вижу их в библиотеке среды выполнения Java также.

0
ответ дан anjanb 23 November 2019 в 05:39
поделиться

Я едва использую финал на методах или классах, потому что мне нравится позволять людям переопределять их.

Иначе, я только использую наконец, если это public/private static final type SOME_CONSTANT;

1
ответ дан jjnguy 23 November 2019 в 05:39
поделиться

Для аргументов я, думают, что они не нужны. Mostley они просто повреждают удобочитаемость. Rreassigning переменная аргумента так безумно глупа, что я должен быть довольно уверен, что их можно рассматривать как константы так или иначе.

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

я пытаюсь осуществить правило, что любой и все переменные должны быть окончательными он, там не чрезвычайно допустимая причина не к. Настолько легче ответить, "что это является переменным?" вопрос, если просто необходимо найти initilization и быть уверены, что это - он.

я на самом деле становлюсь довольно возбужденным вокруг непоследних переменных теперь дни. Это похоже на differnce между наличием ножа, зависающего в потоке abouve Ваша голова, или просто имеющего его Вы кухонная секция...

последняя переменная А является просто хорошим способом маркировать значения.

непоследняя переменная А связывается с частью некоторого склонного к ошибке алгоритма.

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

1
ответ дан John Nilsson 23 November 2019 в 05:39
поделиться

Я никогда не использую их на локальных переменных, существует мало точки для добавленного многословия. Даже если Вы не думаете, что переменная должна быть повторно присвоена, который будет иметь мало значения для следующего человека, изменяющего тот код, который думает иначе, и так как код изменяется, любая исходная цель для того, чтобы сделать его, финал больше не может быть допустимым. Если это только для ясности, я полагаю, что это перестало работать из-за отрицательных эффектов многословия.

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

Это также не имеет никакого влияния на неизменность, как лучший индикатор чего-то являющегося неизменным - то, что это документируется как таковое и/или не имеет никаких методов, которые могут изменить объект (это, наряду с созданием финала класса является единственным способом гарантировать, что это неизменно).

, Но эй, это - просто мое мнение:-)

1
ответ дан Robin 23 November 2019 в 05:39
поделиться

Я настроил Eclipse для добавления финала на всех полях и атрибутах, которые не изменяются. Это работает использование отлично Eclipse, "сохраняют действия", который добавляет эти заключительные модификаторы (среди прочего), сохранив файл.

Наиболее рекомендуемый.

Выезд мое сообщение в блоге из Eclipse Сохраняют Действия.

1
ответ дан zvikico 23 November 2019 в 05:39
поделиться

Даже для локальных переменных, зная, что это объявляется, финал означает, что я не должен волноваться о ссылке, изменяемой позже. Это означает, что при отладке и я вижу, что переменная позже, я уверен, что она относится к тому же объекту. Это - то меньше вещи, о которой я должен волноваться при поиске ошибки. Премия то, что, если 99% переменных объявляются финалом, то несколько переменных, которые действительно являются переменными, выделяются лучше. Кроме того, финал позволяет компилятору найти некоторые более возможные глупые ошибки, которые могли бы иначе остаться незамеченными.

2
ответ дан Diastrophism 23 November 2019 в 05:39
поделиться

Финал, когда используется с переменными в Java обеспечивает замену константы в C++. Таким образом, когда окончательный и статичный используется для переменной, это становится неизменным. В то же время делает перемещенных программистов на C++ довольно счастливыми;-)

, Когда используется со ссылочными переменными это не позволяет Вам повторно ссылаться на объект, хотя объектом можно управлять.

, Когда финал используется с методом, он не позволяет методу быть переопределенным подклассами.

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

нужно только использовать его для переменных, когда Вы чертовски уверены, что значение переменной/должно никогда не быть измененным. Также удостоверьтесь, чтобы Вы следовали соглашению кодирования, поощренному SUN.for, например: заключительный международный COLOR_RED = 1; (Верхний регистр, разделенный подчеркиванием)

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

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

1
ответ дан Omnipotent 23 November 2019 в 05:39
поделиться

финал должен, очевидно, использоваться на константах, и осуществлять неизменность, но на методах существует другое важное использование.

Эффективный Java имеет целый объект на этом (Объект 15) указание на ловушки непреднамеренного наследования. Эффективно, если Вы не разработали и зарегистрировали свой класс для наследования, наследовавшийся ему может дать неожиданные проблемы (объект дает хороший пример). Рекомендация поэтому состоит в том, что Вы используете финал на любом классе и/или методе, который не был предназначен, чтобы быть наследованным от.

, Который может казаться драконовским, но это имеет смысл. Если Вы пишете библиотеку классов для использования другими тогда, Вы не хотите их наследовавшийся вещам, которые не были разработаны для него - Вы будете блокировать себя в конкретную реализацию класса для задней совместимости. Если Вы кодируете в команде нет ничего, чтобы мешать другому члену команды удалить финал , если они действительно имеют к. Но ключевое слово заставляет их думать о том, что они делают, и предупреждает их, что класс, которому они наследовались, не был разработан для него, таким образом, они должны быть дополнительны осторожный.

3
ответ дан DJClayworth 23 November 2019 в 05:39
поделиться

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

4
ответ дан Tom Hawtin - tackline 23 November 2019 в 05:39
поделиться

Я использую final все время для атрибутов объектов.

final ключевое слово имеет семантику видимости, когда используется на атрибутах объектов. В основном устанавливание значения атрибута конечного объекта происходит - прежде чем конструктор возвратится. Это означает, что, пока Вы не позволяете this, ссылка выходит из конструктора, и Вы используете final для весь , Вы приписываете, Ваш объект (под семантикой Java 5), гарантировал, что был правильно создан, и так как это также неизменно, это может быть безопасно опубликовано к другим потокам.

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

я иногда также делаю финал методов, но не как часто. Я seldomly делаю финал классов. Я обычно делаю это, потому что у меня есть мало потребности к. Я обычно не использую наследование очень. Я предпочитаю использовать интерфейсы и объектный состав вместо этого - это также предоставляет себя дизайну, который я нахожу, часто легче протестировать. Когда Вы кодируете к интерфейсам вместо реальных классов, тогда Вы не делаете потребность для использования наследования, когда Вы тестируете, как это, с платформами, такими как jMock, намного легче создать фиктивные объекты с интерфейсами, чем это с реальными классами.

я предполагаю, что должен сделать большинство своего финала классов, но я просто еще не вошел в привычку.

5
ответ дан Chris Vest 23 November 2019 в 05:39
поделиться

Финал должен всегда использоваться для констант. Это даже полезно для недолгих переменных (в отдельном методе), когда правила для определения переменной являются сложными.

, Например:

final int foo;
if (a)
    foo = 1;
else if (b)
    foo = 2;
else if (c)
    foo = 3;
if (d)        // Compile error:  forgot the 'else'
    foo = 4;
else
    foo = -1;
8
ответ дан David Leppik 23 November 2019 в 05:39
поделиться

Я никогда не был в ситуации, где наличие заключительного ключевого слова на переменной мешало мне делать ошибку, так в настоящий момент я думаю, что это - гигантская пустая трата времени.

, Если нет настоящая причина для того, чтобы сделать его (как в Вас хотят сделать конкретный вопрос о той переменной, являющейся окончательным) я не сделал бы этого, так как я нахожу, что это делает код менее читаемым.

, Если, однако, Вы не находите, это делает код тяжелее для чтения, или дольше записать тогда любой ценой идут для него.

Редактирование: Как разъяснение (и попытка вернуть вниз-голоса), который я не говорю, не отмечают константы как финал, я говорю, не делают материала как:

public String doSomething() {
  final String first = someReallyComplicatedExpressionToGetTheString();
  final String second = anotherReallyComplicatedExpressionToGetAnother();

  return first+second;
}

Это просто делает код (по-моему), тяжелее для чтения.

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

11
ответ дан SCdF 23 November 2019 в 05:39
поделиться

Эффективный Java имеет объект, который говорит "Пользу неизменные объекты". При объявлении полей, поскольку финал помогает Вам сделать некоторые маленькие шаги к этому, но существует, конечно, намного больше к действительно неизменным объектам, чем это.

, Если Вы знаете, что объекты неизменны, они могут быть совместно использованы для чтения среди многих потоков/клиентов без забот синхронизации, и легче рассуждать о как прогоны программы.

17
ответ дан Lars Westergren 23 November 2019 в 05:39
поделиться

Я довольно догматичен об объявлении каждой возможной переменной final. Это включает параметры метода, локальные переменные, и редко, поля объекта значения. У меня есть три главных причины для объявления последних переменных везде:

  1. Объявление Намерения: Путем объявления последней переменной я заявляю, что эта переменная предназначена, чтобы быть записанной в только однажды. Это - тонкая подсказка другим разработчикам и большая подсказка к компилятору.
  2. Переменные Единственного использования Осуществления: Я верю в идею, что каждая переменная должна иметь только одну цель в жизни. Путем предоставления каждой переменной только одной цели Вы уменьшаете время, которое это берет к grok цель той конкретной переменной при отладке.
  3. Допускает Оптимизацию: Я знаю, что компилятор раньше имел приемы улучшения производительности, которые положились конкретно на неизменность ссылки на переменную. Мне нравится думать, что некоторые из этих старых приемов производительности (или новые) будут использоваться компилятором.

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

20
ответ дан Ryan Ransford 23 November 2019 в 05:39
поделиться

final модификатор, специально для переменных, является средством иметь компилятор, осуществляют соглашение, которое вообще разумно: удостоверьтесь (локальный или экземпляр), переменная присвоена точно однажды (больше не меньше). Путем проверки определенно присвоена переменная, прежде чем она будет использоваться, можно избежать общих падежей NullPointerException:

final FileInputStream in;
if(test)
  in = new FileInputStream("foo.txt");
else
  System.out.println("test failed");
in.read(); // Compiler error because variable 'in' might be unassigned

, препятствуя тому, чтобы переменная была присвоена несколько раз, Вы препятствуете сверхшироко обзору. Вместо этого:

 String msg = null;
 for(int i = 0; i < 10; i++) {
     msg = "We are at position " + i;
     System.out.println(msg);
 }
 msg = null;

Вы поощряетесь использовать это:

 for(int i = 0; i < 10; i++) {
     final String msg = "We are at position " + i;
     System.out.println(msg);
 }

Некоторые ссылки:

29
ответ дан Bruno De Fraine 23 November 2019 в 05:39
поделиться

Будьте зациклены:

  • поля Final - отмечающие поля, поскольку финал вынуждает их быть установленными к концу конструкции, делая ту неизменную ссылку поля. Это позволяет безопасную публикацию полей и может избежать потребности в синхронизации на более поздних чтениях. (Обратите внимание, что для ссылки на объект, только ссылка поля неизменна - вещи, к которым относится ссылка на объект, может все еще измениться, и это влияет на неизменность.)
  • Заключительные статические поля - Хотя я использую перечисления теперь для многих случаев, где я раньше использовал статические заключительные поля.

Рассматривают, но используют рассудительно:

  • Заключительные классы - дизайн Платформы/API является единственным случаем, где я рассматриваю его.
  • Последние методы - В основном то же как заключительные классы. Если Вы используете шаблонные шаблоны метода как сумасшедший и отмечаете финал материала, Вы, вероятно, полагаетесь слишком много на наследование и недостаточно на делегацию.

Игнорируют если анальное ощущение себя:

  • параметры Метода и локальные переменные - я РЕДКО делаю это в основном, потому что я ленив, и я нахожу, что это создает помехи коду. Я полностью признаю, что маркировка параметров и локальных переменных, которые я не собираюсь изменять, является "более правильной". Мне жаль, что это не было значение по умолчанию. Но это не, и я нахожу код более трудным понять с финалом на всем протяжении. Если я нахожусь в чужом коде, я не собираюсь вытаскивать их, но если я запишу новый код, то я не вставлю их. Одно исключение имеет место, где необходимо отметить что-то заключительное, таким образом, можно получить доступ к нему из анонимного внутреннего класса.
184
ответ дан Alex Miller 23 November 2019 в 05:39
поделиться

Действительно необходимо понять использование в полной мере заключительного ключевого слова перед использованием его. Это может относиться и имеет отличающееся влияние на переменных, полях, методах и классах

, I’d рекомендуют проверить статью, связанную с ниже для получения дополнительной информации.

Финал Word On заключительное Ключевое слово

32
ответ дан maaartinus 23 November 2019 в 05:39
поделиться

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

3
ответ дан Uri 23 November 2019 в 05:39
поделиться

Я уже некоторое время кодирую и использую final, когда могу. Сделав это некоторое время (для переменных, параметров метода и атрибутов класса), я могу сказать, что 90% (или более) моих переменных фактически являются окончательными. Я думаю, что преимущество НЕ изменять переменные, когда вы этого не хотите (я видел это раньше, и иногда это больно), платит за дополнительный набор текста и дополнительные «последние» ключевые слова в вашем коде.

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

Я не часто использую final для классов и методов, подумал. Это более или менее сложный выбор дизайна, если только ваш класс не является служебным (в этом случае у вас должен быть только один частный конструктор).

Я также использую Collections.unmodifiable ...

1
ответ дан 23 November 2019 в 05:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: