2012-08-02 2 views
12

Это из Effective JavaЧто значит сказать, что int enum patterns - это константы времени компиляции?

программ, которые используют INT перечислимого шаблона хрупки. Поскольку int перечислены константы времени компиляции, они скомпилируются в используемые им клиенты.

Может кто-нибудь объяснить, почему ИНТ перечисление модель называется скомпилированный тип постоянной и что подразумевается под составленный в клиентов?

Вот с пример такой константы:

public static final int APPLE_FUJI = 0; 
+0

Это одна из немногих оптимизаций 'javac', и вообще я бы предпочел, чтобы это не так;) –

ответ

17

Предположим, у вас есть два файла:

Foo.java: 
public class Foo 
{ 
    public static final int SOMETHING = 1; 
} 

Bar.java: 
public class Bar 
{ 
    public static void main(String[] args) 
    { 
     System.out.println(Foo.SOMETHING); 
    } 
} 

компилировать их обоих, запустите java Bar и он будет распечатывать 1.

Теперь измените Foo.java так что SOMETHING является 2, и перекомпилировать просто Foo .java. Rerun java Bar и будет еще print 1. Постоянное значение будет скопировано на каждый фрагмент кода, который его использует, вместо того, чтобы запрашивать значение от Foo во время выполнения.

На практике, если вы перекомпилируете все в любое время, что-либо изменится, это не проблема.

+0

не является Java-динамическим языком привязки? Почему мы должны перекомпилировать все? – Geek

+2

@ Geek У вас нет ** есть ** для этого. Но это настоятельно рекомендуется, чтобы избежать того, что описывает Джон Скит выше. На мой взгляд, такое поведение компилятора Java плохое. Эта константа должна храниться только в 'Foo.class'. 'Bar' должен ВСЕГДА получать эту константу из' Foo'. Как и многие другие глупые вещи на языке: он не будет изменен, потому что, возможно, он сломает существующий код. Какая кучка крик-младенцев ... –

+0

@Geek: Вам нужно было бы определить «динамический язык привязки», чтобы я мог ответить на ваш первый вопрос. Но причина, по которой вам приходится перекомпилировать в этом случае, состоит в том, что спецификация языка явно вызывает постоянные выражения, подобные этому. –

5

Значение „0“ сама будет построен в .class файлов во время компиляции. Если вы затем измените это значение, вам необходимо перекомпилировать все, что использует его, включая любой код клиента, который использует ваше приложение/библиотеку.

Если вы этого не сделаете, вы не получите предупреждение, а скорее неправильное поведение.

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