Обоснование принятия окончательного метода - PullRequest
8 голосов
/ 19 апреля 2011

Извините, быстрый вопрос здесь, только что нашел что-то в моих заметках, которые я не понимаю в связи с завершением метода. Мои заметки утверждают, что вы должны сделать метод окончательным по этой причине:

делает невозможным применение инвариантов.

Строка должна вести себя как Строка.

Я не очень понимаю, что это значит. Может кто-нибудь, пожалуйста, сломать это для меня? Большое спасибо.

Ответы [ 8 ]

7 голосов
/ 19 апреля 2011

Я бы предположил, что следовало сказать: «Сделай возможным применение инвариантов». По сути, если кто-то может переопределить метод, он может изменить поведение, влияющее на инварианты вашего класса.

3 голосов
/ 19 апреля 2011

Как правило, есть две причины сделать метод окончательным: производительность и дизайн.Когда метод является окончательным, он может быть встроенным.До компиляции HotSpot (JDK 1.1.x) эти методы обычно были встроены во время компиляции, тогда как с HotSpot они встроены во время выполнения, если компилятор не может гарантировать, что встроенный метод всегда будет компилироваться вместе с кодом, который его использует.Есть две причины, по которым я знаю, как сделать локальную переменную или параметр final.Первая причина в том, что вы не хотите, чтобы ваш код изменял локальную переменную или параметр.Многие считают плохим стилем изменять параметр внутри метода, поскольку это делает код неясным.По привычке некоторые программисты делают все свои параметры «окончательными», чтобы не допустить их изменения.Я этого не делаю, так как считаю, что сигнатура моего метода выглядит немного некрасиво.

Вторая причина возникает, когда мы хотим получить доступ к локальной переменной или параметру из внутреннего класса.Насколько я знаю, именно по этой причине окончательные локальные переменные и параметры были введены в язык Java в JDK 1.1. Источник

1 голос
/ 19 апреля 2011

Ваши заметки могут иметь больше смысла, если они читают:

Последний метод делает возможным принудительное применение инвариантов.

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

1 голос
/ 19 апреля 2011

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

0 голосов
/ 19 апреля 2011
    class A{
        public A(){
            print("A");
        }

        public void print(String t){
            System.out.println(t);
        }
    }

    class B extends A{
        public B(){
            super();
        }

        @Override
        public void print(String t){
            System.out.println("Not A: " + t);
        }
    }

    new B();

Печатает "Not A: A"

Если метод суперкласса "print (" был последним, этот тип ошибки не мог произойти.

С помощью final вы можете применить этометод остается неизменным, так что A всегда может быть доволен печатью "A"

0 голосов
/ 19 апреля 2011

A String невозможно изменить при его создании. Это означает, что все его внутренние поля объявлены как final, и он не предоставляет метода для обновления его внутреннего содержимого. Поэтому, когда вы объявляете строку как «я строка», вы знаете, что объявленная строка будет хранить это значение до конца времени.

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

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

0 голосов
/ 19 апреля 2011

Обычно, если вы сделаете метод final, вы не сможете переопределить этот метод в подклассе.

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

0 голосов
/ 19 апреля 2011

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

...