Инициализация Java - интерфейс класса v / s - PullRequest
7 голосов
/ 30 января 2011

Я застрял в представленной ниже концепции инициализации класса и интерфейса Java:

Я прочитал следующее предложение в указанной ниже книге:

Интерфейс инициализируется только потому, что используется непостоянное поле, объявленное интерфейсом, а не потому, что необходимо инициализировать подинтерфейс или класс, реализующий интерфейс.
Но это не тот случай, когда мы инициализируем любой класс Java.

Таким образом, инициализация класса требует предварительной инициализации всех его суперклассов, но не его суперинтерфейсов.
Инициализация интерфейса не требует инициализации его суперинтерфейсов.

Myвопрос Почему это так?

Любая помощь будет принята с благодарностью!

Спасибо

PS: Книга - "Внутри виртуальной машины Java »Билла Веннерса (Глава 7 - LifeTime класса)

Ответы [ 3 ]

5 голосов
/ 30 января 2011

Единственное, что вы можете объявить в интерфейсе - это сигнатуры методов и константные поля. Последний может быть инициализирован с использованием постоянных значений (то есть строковых литералов, целых чисел и т. Д., Возможно, в некоторой комбинации) или с использованием непостоянных значений (то есть вызовов методов). Таким образом, если интерфейс не имеет непостоянных полей, инициализация не требуется - все известно во время компиляции. Если в программе используются непостоянные поля, необходимо выполнить код инициализации, чтобы убедиться, что этим полям присвоено значение.

Надеюсь, это поможет.

P.S .: Эта глава доступна онлайн здесь , если кто-то хочет прочитать ее полностью.

1 голос
/ 31 января 2011

Интересно.Давайте посмотрим, почему суперкласс должен быть инициализирован перед подклассом.

class A
    static x = DB.insert(1,...);
class B extends A
    static y = DB.select(1);

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

Однако тот же аргумент может применяться к суперинтерфейсам.Я не вижу жесткой причины, по которой Java не инициализирует суперинтерфейсы с нетерпением. Мягкие причины являются чьим-либо предположением.

Дайте правила, как они есть, мы должны быть осторожны с инициализацией полей в интерфейсах:

  1. лучше не иметь никаких полей винтерфейс
  2. в противном случае поля должны быть только постоянной времени компиляции
  3. в противном случае инициализация поля лучше не иметь побочных эффектов.
  4. в противном случае побочный эффект должен быть доступен только черезсамо поле
1 голос
/ 30 января 2011

Цитировать спецификацию языка Java §12.4.1:

Класс или интерфейс типа T будет инициализируется непосредственно перед Первое появление любого из следующее:

  • T является классом, и создается экземпляр T.
  • T является классом, и вызывается статический метод, объявленный T.
  • Статическое поле, объявленное T, присваивается.
  • Статическое поле, объявленное T, используется, а ссылка на поле не константа времени компиляции (§15.28). Ссылки на константы времени компиляции должны быть решены во время компиляции в копия константы времени компиляции значение, поэтому использование такого поля никогда вызвать инициализацию.

вызов определенного рефлексивного методы в классе Class и в пакете java.lang.reflect также вызывает класс или инициализация интерфейса. Класс или интерфейс не будет инициализирован при любых других обстоятельствах.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...