Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Создание константы с динамическим значением


Автор: PashaOvechkin 10.7.2008, 17:20
Код

...
private static final boolean isFine= SuperClass.isSomethingOK(); 
public static final int COLUMN_ID = isFine? 2 : 1;
...

public static void main (String [] a){
int p = 5;

switch p {
 case COLUMN_ID:   // here is error
   //la la la
....
}
}


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

Автор: AntonSaburov 10.7.2008, 19:28
Если на этапе компиляции это не константа, то смысла уже никакого. 
Сделай класс, который будет инициализировать переменную внутри себя из какого-нибудь конфига и определи только get.

Автор: PashaOvechkin 10.7.2008, 19:40
хмм... А чем мой вариант плох? smile 
Всё компилится! До тех пор пока ету "константу" не используем в свиче...

Добавлено через 27 секунд
Помоему, так сделать просто нельзя (без рефлексии)

Автор: niasilil 11.7.2008, 05:09
Нетипично очень, так final константы не определяют. Не надо так делать, другим же потом этот код читать

Автор: PashaOvechkin 11.7.2008, 10:40
Ничего нeчитабельного в таком определении не вижу.
Другое дело что ето не совсем константа получается.... 
Несмотря на то что атрибут определён как: public static final

Автор: powerOn 11.7.2008, 11:13
А Вы сможете гарантировать что вызов SuperClass.isSomethingOK() вернёт то адекватное значение? Порядок инициализации Вы как синхронизируете?   
Момент инициализации статических полей остаётся на усмотрение виртуальной машины. Обычно это происходит в момент загрузки класса, но не факт. Главное, что бы поле было инициализировано раньше чем прочитано. Существует определённая вероятность, что SuperClass.isSomethingOK() вернёт не верное значение в момент инициализации поля isFine. 


Автор: PashaOvechkin 11.7.2008, 12:09
Я же ничего не утверждаю... Порядок инициализации статуческих компонентов в апликации одному богу (йвм) известен.
Мне кажется странным что дозволено делать вот так -> 

Код

private static final boolean isFine= SuperClass.isSomethingOK(); 
public static final int COLUMN_ID = isFine? 2 : 1;


вроде как константа создаётся, но в итоге она левая какая то получается

Автор: Kangaroo 11.7.2008, 14:06
Цитата(PashaOvechkin @  10.7.2008,  17:20 Найти цитируемый пост)
switch p {
 case COLUMN_ID:   // here is error
   //la la la
....
}

В switch можно использовать только COMPILED TIME constant, а не просто константу.

Автор: Shurr 11.7.2008, 14:44
PashaOvechkin
Идеология switch подразумевает увеличение скорости выполнения условных конструкций за счет создания таблицы переходов по заранее заданным значениям. Для создания таблицы переходов значение константы должно быть определено на этапе компиляции, а не на этапе выполнения.

Автор: PashaOvechkin 11.7.2008, 15:21
Спасибо - не знал етого
А можно ссылочку для верности??

Автор: Ulysses4j 11.7.2008, 21:22
Kangaroo, интересно, спасибо за инфо, несколько неожиданно.
Цитата(PashaOvechkin @  11.7.2008,  15:21 Найти цитируемый пост)
А можно ссылочку для верности??

К примеру:
Цитата
Код
 switch ( int expression )
    {
        case int constantExpression :
            statement;
        [ case int constantExpression
            statement;  ]
        ...
        [ default :
            statement;  ]
    }

The case expression for each branch must evaluate to a different constant integer value at compile time.

Knudsen, Niemeyer. Learning Java 3ed, 2005: 4.4.1.5 switch statements.

Автор: Shurr 11.7.2008, 23:12
Цитата(PashaOvechkin @ 11.7.2008,  14:21)
Спасибо - не знал етого
А можно ссылочку для верности??

Если по поводу требования compile-time constant - то тут прямая дорога к JLS. В частности пункт http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#35518 так определяет лейбы:
Цитата
Any statement immediately contained by the switch block may be labeled with one or more case or default labels. These labels are said to be associated with the switch statement, as are the values of the constant expressions (§15.28) in the case labels. (выделение болдом мое - Shurr)
 
Пункт же http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#5313, на который идет ссылка, в числе прочего говорит:
Цитата
A compile-time constant expression is an expression denoting a value of primitive type or a String that is composed using only the following:

Literals of primitive type and literals of type String 
Casts to primitive types and casts to type String 
The unary operators +, -, ~, and ! (but not ++ or --) 
The multiplicative operators *, /, and % 
The additive operators + and - 
The shift operators <<, >>, and >>> 
The relational operators <, <=, >, and >= (but not instanceof) 
The equality operators == and != 
The bitwise and logical operators &, ^, and | 
The conditional-and operator && and the conditional-or operator || 
The ternary conditional operator ? : 
Simple names that refer to final variables whose initializers are constant expressions 
Qualified names of the form TypeName . Identifier that refer to final variables whose initializers are constant expressions

Т.е. ни о каких вызовах методов при инициализации значения речи не идет.


Что же касается преимущественной реализации оператора switch через таблицу переходов - в JLS этого, естественно, нету, т.к. это детали реализации. Но то, что исторически сложилось именно так - это факт. Так, навскидку, ссылок даже и не дам, разве что http://en.wikipedia.org/wiki/Switch_statement smile :
Цитата
Compilation

If the constants form a compact range then a switch statement can be implemented very efficiently as if it were a choice based on whole numbers. This is often done by using a jump table.

А вообще мне кажется это в литературе по компиляторам должно быть.

Автор: Kangaroo 12.7.2008, 13:32
Цитата(Ulysses4j @  11.7.2008,  21:22 Найти цитируемый пост)
Kangaroo, интересно, спасибо за инфо, несколько неожиданно.

Не зря, все-таки, подготовка к SCJP проходит smile


Shurr, спасибо за дополнительную инфу.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)