модификатор 'final' для класса в Java - PullRequest
8 голосов
/ 02 августа 2011

У меня быстрый и простой вопрос. У меня есть привычка делать каждый класс «окончательным», если, конечно, его не нужно расширять другим.

Это вредная привычка? Хорошая привычка? Имеет ли это значение? Я понимаю влияние модификатора на класс.

Заранее большое спасибо!

Edit: Вот пример кода. Этот класс не будет расширен другими классами.

public final class Application {

    /**
     * Starts the application.
     * 
     * @param arguments arguments provided from command-line
     */
    public static void main(String[] arguments) {
        LaunchUtilities util = new LaunchUtilities(new EventHandler());

        try {
            util.addListener(43594);
        } catch (IOException ioe) {
            Logger.getLogger(Application.class.getName()).log(Level.SEVERE, "Could not bind a port to a listener!", ioe);
        }

        util.start();
    }
}

Ответы [ 7 ]

8 голосов
/ 02 августа 2011

Программисты (даже гуру Java) не согласны с этим.

Джош Блох, который разработал библиотеку Java Collections, java.Math, assert и является главным архитектором Java в Google (или был до того, как нанял Гослинга), имеет раздел своей книги «Эффективная Java», посвященный этой проблеме , Я согласен с тем, что он говорит:

Пункт 17: Дизайн и документ для наследования или иначе запретить

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

Кроме того, проектирование наследования обходится дорого.

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

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

Прочтите «Эффективная Java», это делает этот аргумент гораздо более убедительным. Это также сделает вас лучшим программистом.

7 голосов
/ 02 августа 2011

Я скажу «плохая привычка» по следующим причинам:

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

Например:

public static void main(String[] args) {
    final Fruit mockFruit = Mockito.mock(Fruit.class);
}

private static final class Fruit {

}

... приведет к ...

Exception in thread "main" org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class org.foo.Foo$Fruit
Mockito cannot mock/spy following:
  - final classes
  - anonymous classes
  - primitive types

Конечно, существуют допустимые сценарии для завершения классов.Например, ваш класс неизменен.

7 голосов
/ 02 августа 2011

Это хорошая привычка. Изменение финального класса на нефинал не должно нарушать код. Изменение нефинального класса на final может привести к поломке кода.

5 голосов
/ 02 августа 2011

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

2 голосов
/ 02 августа 2011

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

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

В заключение * Модификатор 1006 * для класса - это обычно подсказка кому-то другому о том, как должен использоваться ваш класс, а не настоящая хорошая / плохая привычка. * * 1007

0 голосов
/ 02 августа 2011

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

0 голосов
/ 02 августа 2011

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

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