среда, 14 мая 2008 г.

Java Puzzle 90: It's Absurd, It's Pain, It's Superclass

Следующая программа очень простая и ничего не делает. Но к ней есть два вопроса: почему она не компилируется и как это исправить?
public class Outer {
class Inner1 extends Outer {}
class Inner2 extends Inner1 {}
}

Проблема в том, что при создании класса вызывается "конструктор по-умолчанию", который создаётся автоматически и содержит вызов конструктора суперкласса, а этот вызов выглядит так: this.super(). Теперь становится понятно, почему компилятор ругается "cannot reference this before supertype constructor has been called". Это запрещено согласно спецификации (JLS 8.8.7.1). А исправить можно добавив конструктор без параметров в класс Inner2:
public class Outer {
class Inner1 extends Outer {}
class Inner2 extends Inner1 {
Inner2() {
Outer.this.super();
}
}
}

Такая конструкция уже компилируется, хотя и выглядит очень странно. Кстати, парсер IntelliJ IDEA продолжает показывать ошибку в этом месте.
Авторы предлагают решение лучше и советуют: Когда вы пишете вложенный класс спросите себя, действительно ли нужен доступ к членам класса, в который вы его вкладываете? Если нет, то делайте вложенный класс статическим. Я вообще не люблю вложенные классы. Они усложняют работу с наследованием, а так же с generics и reflection.

Комментариев нет:

Отправить комментарий