| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > модификатор final |
| Автор: jer1 13.4.2005, 15:21 | ||||||
| добрый день!, если объявить метод foo вот так :
то что это мне даст?: семантическое подчеркивание что в коде не будет такого оператора
хотя если и будет, то после выхода из метода я всё равно получу указатель на первоначальный объект (ведь в метод ссылка передаётся по значению) я посмотрел конструкции в которых данный модификатор присутствует в исходниках jdk таковые присутствуют вот например один из конструкторов класса JTable:
зачем тут final? а документация javadoc эти модификаторы не показывает вот строка из api JTable(Object[][] rowData, Object[] columnNames) у кого-нибудь есть мысли? спасибо |
| Автор: batigoal 13.4.2005, 15:28 |
| По-моему, это означает, что передаваемый объект не может изменяться. Константен в пределах данного метода. Добавлено @ 15:31 Вообще, это ключевое слово имеет разную семантику при разных применениях. 1. Если мы объявлем класс, как final, то от него нельзя наследовать. 1. Если мы объявлем метод, как final, то его нельзя переопределять. 1. Если мы объявлем объект, как final, то его нельзя изменять. Згачение присваивается при инициализации, или при передаче в метод, как в данном случае. Надеюсь, ничего не напутал. |
| Автор: jer1 13.4.2005, 15:45 | ||
здесь показано, что состояние объекта является изменяемым вопрос про final в контексте объявления формальных параметров метода - есть ли в этом действительно польза (кроме удлинения кода), может это как-то связано с многозадачностью, во всяком случае классы System, Thread, ClassLoader содержат такие объявления методов |
| Автор: batigoal 13.4.2005, 16:18 | ||
Да, проверил, действительно, действие модификатора распространяется только на сам объект, а не на его поля. То ли так и должно быть, то ли я чего-то не понимаю.
Думаю, польза от этого есть, хотя на практике еще не разу не применял. Знаю, что только final-методы могут быть inline => могут дать нам выигрыш в скорости. Что такое assert? |
| Автор: kashka 13.4.2005, 16:48 |
| Seit dem JDK 1.4 gibt es in Java eine assert-Anweisung. Diese, ursprünglich schon für die erste JDK-Version vorgesehene, dann aber aus Zeitgründen zurückgestellte Anweisung wird C- oder C++-Programmierern wohlbekannt sein. Sie dient dazu, an einer bestimmten Stelle im Programmablauf einen logischen Ausdruck zu plazieren, von dem der Programmierer annimmt, daß er stets wahr ist. Ist das der Fall, fährt das Programm mit der nächsten Anweisung fort, andernfalls wird eine Ausnahme des Typs AssertionError ausgelöst. Ein solcher Ausdruck wird auch als Invariante bezeichnet, denn er bleibt unverändert true, solange das Programm korrekt funktioniert. JDK1.1-1.4 Assertions, wie assert-Anweisungen vereinfachend genannt werden, dienen also dazu, bestimmte Annahmen über den Zustand des Programmes zu verifizieren und sicherzustellen, daß diese eingehalten werden. Soll im Programm beispielsweise überprüft werden, ob eine Variable x nicht-negativ ist, könnte dazu die folgende assert-Anweisung verwendet werden: assert x >= 0; Das Programm überprüft die Bedingung und fährt fort, wenn sie erfüllt ist. Andernfalls wird eine Ausnahme ausgelöst. Natürlich hätte derselbe Test auch mit Hilfe einer einfachen if-Anweisung ausgeführt werden können. Die assert-Anweisung hat ihr gegenüber jedoch einige Vorteile: Der Programmcode ist kürzer. Auf den ersten Blick ist zu erkennen, daß es sich um einen Korrektheits-Check handelt und nicht um eine Verzweigung zur Steuerung des Programmablaufs. Assertions lassen sich zur Laufzeit wahlweise an- oder ausschalten. Im Gegensatz zu einer einfachen if-Anweisung verursachen sie praktisch keine Verschlechterung des Laufzeitverhaltens, wenn sie deaktiviert sind. Der im Syntaxdiagramm angegebene ausdruck1 muß immer vom Typ boolean sein, andernfalls gibt es einen Compilerfehler. Fehlt ausdruck2 (er darf von beliebigem Typ sein), wird im Falle des Nichterfülltseins der Bedingung ein AssertionError mit einer leeren Fehlermeldung erzeugt. Wurde ausdruck2 dagegen angegeben, wird er im Fehlerfall an den Konstruktor von AssertionError übergeben und dient als Meldungstext für das Fehlerobjekt. Добавлено @ 16:56 Извеняюсь сейчас переведу. |
| Автор: jer1 13.4.2005, 17:01 | ||||
| когда ты пишешь для себя, т.е контролируешь корректность передачу параметров, их обработку и т.д, то как правило используются assert. Т.е исходим из того, что алгоритм верен - ты просто убеждаешься (при помощи логического утверждения) в корректности каких-то элементов программы сравнение с runtime-эксепшинами
во втором случае ты сам ответственен за то чтобы прайвет метод был вызван с корректным параметром, если этого не будет - алгоритм не верен при помощи assert ты об этом узнаешь и исправишь (при запуске программы утверждения можно включать/отключить даже селективно для разных пакетов, классов) ну а в первом случае клиент должен позаботиться об корректности параметра (javadoc метода об этом должен упоминать) см. также http://javagu.ru/portal/dt?last=false&provider=javaguru&ArticleId=GURU_ARTICLE_64528&SecID=GURU_SECTION_63111 для динамического мониторинга программы http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/package-summary.html |
| Автор: batigoal 13.4.2005, 17:01 |
| kashka Да, так тяжеловато |
| Автор: kashka 13.4.2005, 17:03 |
| команда assert ставиться перед логическим выражением которое по предположению программиста true. Если это действительно так программа продолжает работу, со следующей комманды, в противном случае мы получаем AssertionError. Добавлено @ 17:04 теперь дальше (тоже немного труднавато подходящие слова находить) Добавлено @ 17:05 Хотя jer1 уже все написал. Добавлено @ 17:07 Могу еще преимущества assert перед if написать, если интересно. |
| Автор: batigoal 13.4.2005, 17:15 | ||
| jer1, kashka Спасибо за объяснения. Добавлено @ 17:16
Буду признателен. |
| Автор: Domestic Cat 13.4.2005, 18:41 | ||||||
| Для чего нужен final :
Запуск дает:
Есть, случае с классами и методами. Например, есli метод нельзя перегрузить, вызов егo статичски связан, а нe динамически. |
| Автор: jer1 13.4.2005, 19:54 | ||
а когда метод нельзя перегрузить, пример!) |
| Автор: Domestic Cat 13.4.2005, 19:59 | ||
|
| Автор: batigoal 13.4.2005, 21:27 | ||
Вот это и дает возможность компилятору встроить метод как инлайн-функцию, если, конечно, он сочтет это целесообразным. |
| Автор: jer1 14.4.2005, 09:40 | ||
а в таком примере модиф. final что-то даёт?
|
| Автор: Domestic Cat 14.4.2005, 09:52 |
| По-моему, никакой особой оптимизации это не даст, я думаю проверка идет на уровне компилятора. Это просто удобно - видно что аргумент не меняется; кроме того, локальные классы могут обращаться к переменным в локальном скопе только если те final. |
| Автор: batigoal 14.4.2005, 11:10 | ||
Навряд ли, ведь для простого типа будет передано значение, а не ссылка. |
| Автор: RTFM/STFW 18.4.2005, 18:04 | ||
Be aware that declaring an object attribute final does not prevent it from being changed. In fact, the final only applies to the reference to the object and not the object itself. |
| Автор: batigoal 18.4.2005, 18:21 |
| Логично. Неизменяемой объявляется ссылка, а не объект. |
| Автор: Zandr 22.4.2005, 07:01 |
| Мало того |
| Автор: batigoal 22.4.2005, 09:54 |
| Массив ведь - тоже объект, и когда мы передаем массив, то передаем неизменяемую ссылку на него. |
| Автор: Zandr 22.4.2005, 11:31 | ||
| Короче есть объекты видимые только в методе во время его выполнения. Это объекты, которые объявляются в этом методе и параметры метода. Если мы в этом же методе делаем иннер-класс, который обращается к отмеченным выше объектам - эти объекты должны быть объявлены как final. Попробуйте из примера ниже убрать final из сигнатуры метода - не скомпилируется:
Хотя Domestic Cat об этом уже написал |
| Автор: simanyay 22.4.2005, 12:39 | ||
Кстати это свойство final можно использовать для реализации паттерна Singleton:
Зато так мы будем точно знать, что существует один и только один объект класса MySingleton. |
| Автор: batigoal 22.4.2005, 12:59 |
| simanyay Здесь, в принципе, можно и не указывать final. Мы ведь все равно не сможем создать еще один объект MySingleton - у него же нет неприватного конструктора. Но хуже, конечно, не будет. |
| Автор: Се ля ви 3.5.2005, 08:58 |
| Народ, всё проще. Эккель пишет, что final - это просто напросто замена вызова метода его телом на уровне компиляции. т.е. это указание на то, что методом это считать нужног только в рамках исходника для понятности кода, а реально - это не метод никакой, а просто кусок другого метода в тех местах, где в коде он вызывается. Даёт это экономию при быстродействии программы, поскольку операция вызова метода сопряжена с дополнительными издержками в частности на выделение памяти под контекст. Здесь получается экономия, но платить за неё приходится невозможностью наследования, что очень неудобно когда речь идёт о многократно-используемых библиотеках. |
| Автор: batigoal 3.5.2005, 12:52 | ||
По-моему, он писал не совсем так. Это рекомендация компилятору, которая совсем не обязательно будет выполнена. К тому же, это справедливо для методов и констант простых типов, но никак не для объектов или классов |
| Автор: simanyay 3.5.2005, 14:37 | ||
Но тогда мы сможем после вызова getInstance заменить объект на другой. |
| Автор: Zandr 4.5.2005, 07:46 | ||||
Укажи, пожалуйста, где он это пишет, только точно, чтобы можно было найти. Очень интересно было бы увидеть это своими глазами. И еще вопрос был про final применительно к параметрам метода, а не к самому методу, или классу, или instance member'у.
Только в одном из методов этого класса и никак иначе. Конструктор-то private. |
| Автор: Се ля ви 4.5.2005, 11:25 |
| Zandr угу, мне тоже стало интересно этот момент перечитать уже |
| Автор: simanyay 4.5.2005, 13:25 | ||||
Почему? А так
? |
| Автор: batigoal 4.5.2005, 13:54 |
| Исключений нет. m=null, но INSTANCE спокойно сидит в памяти. |
| Автор: sergejzr 4.5.2005, 14:18 | ||
| Век живи - век учись Так как kashka запропастилась, я попробую перевести этот интересный абзатц про преимущества ассертов перед указанием if (Кстати тоже наследство Си, но в Яве они конечно элегантнее реализованы, т.к. не нужно никаких дефайнов ) ------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
|
| Автор: batigoal 4.5.2005, 14:21 |
| У Эккеля это, оказывается, есть. Дочитываю, наконец |
| Автор: simanyay 4.5.2005, 14:33 | ||
Точно. Но I'll be back Добавлено @ 14:34 sergej.z, хм... интересно. Спасибо за перевод. |
| Автор: Domestic Cat 5.5.2005, 06:03 | ||
В смысле? |
| Автор: batigoal 5.5.2005, 12:26 | ||
simanyay еще подучит Джаву и покажет тебе, Zandr'у, модификатору final и остальным, где раки зимуют. |
| Автор: simanyay 5.5.2005, 13:05 | ||
во во |
| Автор: simanyay 5.5.2005, 13:28 |
| Перечитал я опять главу в Effective Java про синглтоны и теперь полностью согласен с Lamer George и модификатором final по поводу его работы. Вот. |
| Автор: Domestic Cat 5.5.2005, 18:42 |
| Ааа, ну тогда ладно |
| Автор: Zandr 6.5.2005, 06:39 | ||
Дык, я не против |
| Автор: hatsumeika 14.5.2005, 18:59 | ||
Я встречался с ситуацией когда нужно объявить аргумент метода final: при его использование в анонимном классе:
без final компилятор говорит: "FinalAndAnonimClass.java": local variable x is accessed from within inner class; needs to be declared final at line 7, column 28 |
| Автор: Zandr 16.5.2005, 07:19 |
| hatsumeika, в этом треде про этот случай уже минимум два раза написали |
| Автор: hatsumeika 16.5.2005, 13:13 |
| сорри, не заметил |
| Автор: jer1 24.5.2005, 11:04 |
| вот ещё такая реплика: различные инспекторы кода (http://pmd.sourceforge.net/, http://findbugs.sourceforge.net/ etc) данный вопрос помещают в категорию optimization - imho логично: компилятору даётся дополнительная информация, о неизменности параметра по присвоению, а он уже вправе ею воспользоваться https://jjguidelines.dev.java.net/book/html/apas04.html#JAC_003 https://jjguidelines.dev.java.net/book/html/index.html сподобалось |
| Автор: Tamerlann 24.5.2005, 12:24 |
| Скажем прямо, даже у Sun не много про это сказано. http://java.sun.com/docs/books/tutorial/java/nutsandbolts/finalVariables.html |
| Автор: Се ля ви 24.5.2005, 13:37 | ||||
Чё-то совсем из головы вылетело. Если ещё не нашлось, - страница 246, либо "глава 6" -> "Ключевое слово final". Вот кусок (смог найти только http://www.uic.rsu.ru/doc/programming/eckel/TIJ-3rd-edition4.0.zip ):
Ну и дальше - там много про него интересного |
| Автор: nagliyvred 15.11.2005, 21:10 | ||||
Прочитал все вышенаписанное, но так и не понял: что нужно сделать компилятору такого чтобы он заинлайнил final метод? Эккель говорит что это возможно если метод небольшой и компилятор этого захочет... а заставить его никак нельзя? пробовал простейший пример:
дизассемблировал - никакого иналйна не наблюдается... понимаю что этот тест поверхностный и надо было провести более детальное исследование но не было времени..
компилировал 1.4 with optimization(netBeans 5.0 beta) |
| Автор: LSD 15.11.2005, 21:46 |
| Инлайн на этапе компиляции может делаться только для private методов (и то пока это не делается), а для public только JIT-ом. |
| Автор: chief39 16.11.2005, 10:37 |
| Сонный бред был удалён его создателем |
| Автор: Domestic Cat 16.11.2005, 10:41 | ||
Хороша трава |
| Автор: chief39 16.11.2005, 10:50 | ||
Не. Спать надо.... Понесло. Буду кофе пить |
| Автор: Entry_N3 25.3.2007, 16:19 | ||
в продолжении про final у private метода:
Нужен ли final у private-метода (если да, то зачем?) в классе B, если он и так private и не даст себя переопределить? |
| Автор: LSD 25.3.2007, 16:36 |
| Нет не нужен, но и не запрещен. |
| Автор: Entry_N3 25.3.2007, 16:48 |
| LSD, понял. |
| Автор: Shaggie 13.9.2007, 06:31 |
| По поводу увеличения производительности классов и методов, объявленных как final: довольно свежая статья (2007-02) http://www.ibm.com/developerworks/ru/library/j-jtp04223/index.html#N100B8 |
| Автор: EvgenZ 6.12.2007, 00:03 | ||
Чет вроде про это не обсуждали, что странно, как сделать объект-то константым ? Чтобы например
или так нельзя? |
| Автор: powerOn 6.12.2007, 00:16 | ||
|
| Автор: EvgenZ 6.12.2007, 00:34 | ||
| Наверное не четко выразился, имелось ввиду сделать объект именно в этой функции константным. Т.е. именно этот объект "m". Или например при передаче объекта в функцию
|
| Автор: Kangaroo 6.12.2007, 01:38 |
Я думаю нельзя. Как выход - передавать копию объекта в метод. |
| Автор: LSD 6.12.2007, 11:02 | ||
Нет. |