Когда стоит использовать модификатор final для переменных
От: kunfui  
Дата: 22.04.06 11:12
Оценка:
Пытаемся придти к соглашению по кодированию. Возник спор по поводу использования модификатора для переменных.
Вот пример:

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 для переменны
От: mikkri Великобритания  
Дата: 22.04.06 12:20
Оценка:
Здравствуйте, kunfui, Вы писали:

K>Что можете сказать по поводу испольщования final таким образом?


ИМХО, ни в одном из указанных слочаев не стоит.

K>Я же считаю, что такие примеы только усложняют читаемость и не несут никакой выгоды.

Я думаю так же
Re: Когда стоит использовать модификатор final для переменны
От: aefimov Россия
Дата: 22.04.06 19:06
Оценка:
Здравствуйте, kunfui, Вы писали:

K>
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 для переменны
От: ettcat США  
Дата: 24.04.06 07:11
Оценка:
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 для переменны
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 24.04.06 08:44
Оценка:
Здравствуйте, kunfui, Вы писали:

K>Что можете сказать по поводу испольщования final таким образом?


имхо в этих случаях не нужно.
Имхо стоит объявлять переменные с модификатором final только в случае инстанс-переменных, чтобы избежать наллпойнтеров в многопоточном приложении. Ну и, естественно в случае внутренних классов и аргументов метода.
http://denis-zhdanov.blogspot.com
Re[2]: Когда стоит использовать модификатор final для переме
От: Lucker Беларусь http://lucker.intervelopers.com/
Дата: 24.04.06 08:59
Оценка:
Здравствуйте, 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 для переме
От: Lucker Беларусь http://lucker.intervelopers.com/
Дата: 24.04.06 09:00
Оценка:
Здравствуйте, bolshik, Вы писали:


B> имхо в этих случаях не нужно.

B>Имхо стоит объявлять переменные с модификатором final только в случае инстанс-переменных, чтобы избежать наллпойнтеров в многопоточном приложении.
объясни, плс.
Re[3]: Когда стоит использовать модификатор final для переме
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 24.04.06 09:22
Оценка:
Здравствуйте, Lucker, Вы писали:

L>объясни, плс.


лок берется по адресу на хипе. Если лочимся по ссылке, а потом ее перекидываем на другой объект, получаем сбой.
http://denis-zhdanov.blogspot.com
Re[4]: Когда стоит использовать модификатор final для переме
От: aefimov Россия
Дата: 24.04.06 09:27
Оценка:
Здравствуйте, bolshik, Вы писали:

B> лок берется по адресу на хипе. Если лочимся по ссылке, а потом ее перекидываем на другой объект, получаем сбой.


Сэр. О чем это вы?
Re[3]: Когда стоит использовать модификатор final для переме
От: ettcat США  
Дата: 24.04.06 09:31
Оценка:
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 для переме
От: Lucker Беларусь http://lucker.intervelopers.com/
Дата: 24.04.06 09:39
Оценка:
Здравствуйте, bolshik, Вы писали:

B> лок берется по адресу на хипе. Если лочимся по ссылке, а потом ее перекидываем на другой объект, получаем сбой.

хм. такое возможно, хотя при нормальном подходе маловероятно. Однако, где появляется "наллпойнтер"?
Re[5]: Когда стоит использовать модификатор final для переме
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 24.04.06 09:44
Оценка:
Здравствуйте, Lucker, Вы писали:

L>хм. такое возможно, хотя при нормальном подходе маловероятно. Однако, где появляется "наллпойнтер"?


замечено, что при подобных ситуациях вылетает именно наллпойнтер. С чем именно это связано затрудняюсь ответить, можно только предполагать, что когда VM пытается освободить лок по адресу, по которому он не был взят, получается невалидный указатель ==> наллпойнтер
http://denis-zhdanov.blogspot.com
Re[6]: Когда стоит использовать модификатор final для переме
От: aefimov Россия
Дата: 24.04.06 09:51
Оценка:
Здравствуйте, 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 = null
      if (s.length() > 0) {
         //
      }
   }
}
Re[6]: Когда стоит использовать модификатор final для переме
От: Lucker Беларусь http://lucker.intervelopers.com/
Дата: 24.04.06 09:52
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Здравствуйте, Lucker, Вы писали:


L>>хм. такое возможно, хотя при нормальном подходе маловероятно. Однако, где появляется "наллпойнтер"?


B> замечено, что при подобных ситуациях вылетает именно наллпойнтер. С чем именно это связано затрудняюсь ответить, можно только предполагать, что когда VM пытается освободить лок по адресу, по которому он не был взят, получается невалидный указатель ==> наллпойнтер


хм, как то все это сказочно. Давай код, который все это демонстрирует.
Re[7]: Когда стоит использовать модификатор final для переме
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 24.04.06 09:52
Оценка:
Здравствуйте, aefimov, Вы писали:

A>NPE вылетает на final переменных только в случае вызовов перегруженных методов из конструктора.



Мы говорим как раз не о final переменных
http://denis-zhdanov.blogspot.com
Re[7]: Когда стоит использовать модификатор final для переме
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 24.04.06 09:54
Оценка:
Здравствуйте, Lucker, Вы писали:

L>хм, как то все это сказочно. Давай код, который все это демонстрирует.


в наличии нет.
С работой подразберусь и налабаю примерчик.
http://denis-zhdanov.blogspot.com
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 для переме
От: aefimov Россия
Дата: 24.04.06 10:39
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Мы говорим как раз не о final переменных


Что-то я туплю сегодня.

Значит тут NPE возможен:
public class A {
   private String s;
}


А тут — нет:
public class A {
   private final String s = "blabla";
}


Это вроде и так понятно. А причем тут лок по какой то "ссылке" и прочее?
Re[3]: Когда стоит использовать модификатор final для переме
От: korostoff Россия  
Дата: 24.04.06 10:53
Оценка:
Здравствуйте, Аноним, Вы писали:

Судя по http://java.sun.com/docs/books/jls/third_edition/html/memory.html#66562 вы поняли правильно:

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 для переме
От: korostoff Россия  
Дата: 24.04.06 10:57
Оценка:
Здравствуйте, aefimov, Вы писали:

NPE даже возможен
 class FinalFieldExample {
  final String x;
  public FinalFieldExample() {
    x = "12";
}

Если из другого потока обращаются к полю x.
http://java.sun.com/docs/books/jls/third_edition/html/memory.html#66562
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.