Пытаемся придти к соглашению по кодированию. Возник спор по поводу использования модификатора для переменных.
Вот пример:
final List list = getList();
for (final Iterator i = list.iterator(); i.hasNext(); ) {
final Object o = i.next();
final String str = o.toString();
// some code
}
Использование final здесь оправдывают защитой переменных от переопределения.
Я же считаю, что такие примеы только усложняют читаемость и не несут никакой выгоды.
Что можете сказать по поводу испольщования final таким образом?
Re: Когда стоит использовать модификатор final для переменны
K>final List list = getList();
K>for (final Iterator i = list.iterator(); i.hasNext(); ) {
K> final Object o = i.next();
K> final String str = o.toString();
K> // some code
K>}
K>
Использование final необходимо там, где можно накосячить. Например, константы лычше делать final.
Методы, которые вызываются из конструкторов, тоже необходимо делать final, если они не private.
Ну и т.д.
K>Что можете сказать по поводу испольщования final таким образом?
В приведеном коде — это просто кому то очень нравится слово final писхать везде, где оно не нужно. Знаете, так обычно работают генераторы кода , чтобы обезопасить самих себя от неверной кодо-генерации.
Да и использование for в данном случае, тоже не особо здорово. Хотя, это может дело вкуса, но когда в for есть пустое место, мне это не нравица ровно, как и использование внутри for break или continue.
Re: Когда стоит использовать модификатор final для переменны
kunfui wrote: > Пытаемся придти к соглашению по кодированию. Возник спор по поводу использования модификатора для переменных. > Вот пример: > >
> final List list = getList();
>
> for (final Iterator i = list.iterator(); i.hasNext(); ) {
> final Object o = i.next();
> final String str = o.toString();
>
> // some code
> }
>
> > Использование final здесь оправдывают защитой переменных от переопределения. > Я же считаю, что такие примеы только усложняют читаемость и не несут никакой выгоды. > > Что можете сказать по поводу испольщования final таким образом?
ИМХО final оправдано применять в таких случаях например:
public class SomeClass {
private final long i;
public SomeClass() {
i = ...;
}
}
Сразу понятно что i определяется в конструкторе, и нигде не меняется
(разумеется не все переменные можно определить final). Компилятор
ругнется, если i ничего не присваивается в конструкторе.
Во вторых, я думаю, оправданно применять final с Immutable типами,
типа int, String и т.д. Это дает дополнительную семантическую нагрузку.
final String prop = props.getProperty("some.prop"); // теперь я точно
уверен что prop не меняется
Опять же, ИМХО, не имеет смысла применять final с типами, которые могут
менять свое состояние(Calendar, массивы, контейнеры).
final StringBuilder buf = new StringBuilder(); // buf может спокойно
менять свое состояние
Еще одно оправданное, ИМХО, применение — в ветвлениях:
final int i;
if (...) {
i = 1;
} else {
i = 0;
}
Здесь компилятор проследит, что i определяется, причем только один раз.
Posted via RSDN NNTP Server 2.0
Re: Когда стоит использовать модификатор final для переменны
Здравствуйте, kunfui, Вы писали:
K>Что можете сказать по поводу испольщования final таким образом?
имхо в этих случаях не нужно.
Имхо стоит объявлять переменные с модификатором final только в случае инстанс-переменных, чтобы избежать наллпойнтеров в многопоточном приложении. Ну и, естественно в случае внутренних классов и аргументов метода.
Здравствуйте, ettcat, Вы писали:
E> Во вторых, я думаю, оправданно применять final с Immutable типами, E>типа int, String и т.д. Это дает дополнительную семантическую нагрузку. E>
E> final String prop = props.getProperty("some.prop"); // теперь я точно
E>уверен что prop не меняется
E>
E>Опять же, ИМХО, не имеет смысла применять final с типами, которые могут E>менять свое состояние(Calendar, массивы, контейнеры). E>
E> final StringBuilder buf = new StringBuilder(); // buf может спокойно
E>менять свое состояние
E>
а как относится модификатор переменной final к содержимому объекта, на который эта переменная ссылается?
final StringBuilder buf = new StringBuilder(); говорит о том что значение buf неожиданно не поменяется, а не то что состояние StringBuilder останется неизменным.
Re[2]: Когда стоит использовать модификатор final для переме
B> имхо в этих случаях не нужно. B>Имхо стоит объявлять переменные с модификатором final только в случае инстанс-переменных, чтобы избежать наллпойнтеров в многопоточном приложении.
объясни, плс.
Re[3]: Когда стоит использовать модификатор final для переме
Lucker wrote: > Здравствуйте, ettcat, Вы писали: > > E> Во вторых, я думаю, оправданно применять final с Immutable типами, > E>типа int, String и т.д. Это дает дополнительную семантическую нагрузку. > E>
> E> final String prop = props.getProperty("some.prop"); // теперь я точно
> E>уверен что prop не меняется
> E>
> > E>Опять же, ИМХО, не имеет смысла применять final с типами, которые могут > E>менять свое состояние(Calendar, массивы, контейнеры). > E>
> E> final StringBuilder buf = new StringBuilder(); // buf может спокойно
> E>менять свое состояние
> E>
> > а как относится модификатор переменной final к содержимому объекта, на который эта переменная ссылается? > final StringBuilder buf = new StringBuilder(); говорит о том что значение buf неожиданно не поменяется, а не то что состояние StringBuilder останется неизменным.
Конечно. final StringBuilder buf говорит только о том, что ссылка на
buf не поменяется. Состояние buf при этом можно менять как хочешь. Лично
мне кажется, что это усложняет читаемость.
Posted via RSDN NNTP Server 2.0
Re[4]: Когда стоит использовать модификатор final для переме
Здравствуйте, bolshik, Вы писали:
B> лок берется по адресу на хипе. Если лочимся по ссылке, а потом ее перекидываем на другой объект, получаем сбой.
хм. такое возможно, хотя при нормальном подходе маловероятно. Однако, где появляется "наллпойнтер"?
Re[5]: Когда стоит использовать модификатор final для переме
Здравствуйте, Lucker, Вы писали:
L>хм. такое возможно, хотя при нормальном подходе маловероятно. Однако, где появляется "наллпойнтер"?
замечено, что при подобных ситуациях вылетает именно наллпойнтер. С чем именно это связано затрудняюсь ответить, можно только предполагать, что когда VM пытается освободить лок по адресу, по которому он не был взят, получается невалидный указатель ==> наллпойнтер
Здравствуйте, bolshik, Вы писали:
B> замечено, что при подобных ситуациях вылетает именно наллпойнтер. С чем именно это связано затрудняюсь ответить, можно только предполагать, что когда VM пытается освободить лок по адресу, по которому он не был взят, получается невалидный указатель ==> наллпойнтер
NPE вылетает на final переменных только в случае вызовов перегруженных методов из конструктора.
public abstract class A {
public A() {
test();
}
protected abstract void test();
}
final String s = "blabla";
new A() {
protected void test() {
// Вот тут s = nullif (s.length() > 0) {
//
}
}
}
Re[6]: Когда стоит использовать модификатор final для переме
Здравствуйте, bolshik, Вы писали:
B>Здравствуйте, Lucker, Вы писали:
L>>хм. такое возможно, хотя при нормальном подходе маловероятно. Однако, где появляется "наллпойнтер"?
B> замечено, что при подобных ситуациях вылетает именно наллпойнтер. С чем именно это связано затрудняюсь ответить, можно только предполагать, что когда VM пытается освободить лок по адресу, по которому он не был взят, получается невалидный указатель ==> наллпойнтер
хм, как то все это сказочно. Давай код, который все это демонстрирует.
Re[7]: Когда стоит использовать модификатор final для переме
Re[2]: Когда стоит использовать модификатор final для переме
От:
Аноним
Дата:
24.04.06 10:37
Оценка:
Здравствуйте, bolshik, Вы писали:
B>Имхо стоит объявлять переменные с модификатором final только в случае инстанс-переменных, чтобы избежать наллпойнтеров в многопоточном приложении. Ну и, естественно в случае внутренних классов и аргументов метода.
У Doug Lee в Concurrent Programming в описании Memory Model есть такие строки
The first time a thread accesses a field of an object, it sees either the initial value[4] of the field or a value since written by some other thread.
[4] As of this writing, the JLS does not yet clearly state that the visible initial value read for an initialized final field is the value assigned in its initializer or constructor. However, this anticipated clarification is assumed throughout this book. The visible initial default values of non-final fields are zero for scalars and null for references.
Значит ли это что если инстанс поле не final то в ситуации наличия конструктора типа
public Object obj;
public MyObj() {
obj = new Object();
}
и поле obj более нигде не меняется все равно возможна ситуация когда в многопоточном коде какой-нить поток увидит null в этом поле?
Т.к. например ссылка на объект уже опубликуется в main memory а значение еще нет.
А в случае с final такого произойти не может, т.к. "initial value read for an initialized final field is the value assigned in its initializer or constructor".
Прально ли я все это понял?
Re[8]: Когда стоит использовать модификатор final для переме
The example below illustrates how final fields compare to normal fields.
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
}
The class FinalFieldExample has a final int field x and a non-final int field y. One thread might execute the method writer(), and another might execute the method reader().
Because writer() writes f after the object's constructor finishes, the reader() will be guaranteed to see the properly initialized value for f.x: it will read the value 3. However, f.y is not final; the reader() method is therefore not guaranteed to see the value 4 for it.
Re[9]: Когда стоит использовать модификатор final для переме