Внутренний класс Java с тем же именем, что и другой класс верхнего уровня
У меня есть вопрос, связанный с внутренними классами Java.
Есть ли способ получить доступ к классу верхнего уровня A из класса высшего уровня Main, который определяет внутренний класс A?
Ниже приведен пример кода, демонстрирующий проблему:
class A { // Outer Class A
{
System.out.println("A outer");
}
}
class B { // Outer Class B
{
System.out.println("B outer");
}
}
public class Main {
class A { // Inner Class A
{
System.out.println("A inner");
}
}
public void newA() {
class A { // Local Class A
{
System.out.println("A local");
}
}
new A();
}
public static void main(String[] args) {
new Main().newA(); // prints "A local"
new Main().new A(); // prints "A inner"
//new A(); // compiler error: No enclosing instance of type Main is Accessible.
new B(); // but this works and prints "B outer"
}
}
6 ответов
Вы должны предоставить разные имена пакетов для ваших двух A
Если они явно разных типов, вы можете ссылаться на них по их полным именам.
Например:
my.package.for.toplevel.A outerA = new my.package.for.toplevel.A(); // prints "A outer"
// if this is the
// package
Или, что еще лучше, используйте два разных имени для двух разных классов.
Если ваши классы находятся в пакетах, я ожидаю, что это будет самый простой способ достижения этого. Я не верю, что есть какой-либо эквивалент C# global::
для Java, чтобы заставить такого рода вещи.
В конечном счете, я бы просто попытался изменить имена классов, чтобы избежать проблемы, возникающей в первую очередь. Обычно это лучший подход, чем использование обходных путей.
Говорят, что имя внутреннего класса скрывает имя класса верхнего уровня. На класс верхнего уровня нельзя ссылаться по его простому имени в области видимости внутреннего класса; на класс верхнего уровня можно ссылаться только через определенное имя.
Если класс верхнего уровня находится в пакете по умолчанию (в этом случае его каноническое имя совпадает с его простым именем), вы все равно можете получить к нему доступ через отражение.
Да, просто используйте пакеты или избегайте называть их одинаковыми с самого начала. Интересно, какова ваша причина, чтобы назвать их так или иначе?
Чтобы объяснить вашу ошибку, это происходит из-за того, что он пытается получить доступ к внутреннему A, но так как этот класс не объявлен как статический и нет доступного экземпляра Main, он не может создать нестатический внутренний A, который требует ссылки в родительский главный экземпляр.
Предполагается, что классы находятся в пакете по умолчанию. Для разрешения конфликта именования в этом случае необходимо либо переименовать конфликтующие классы, либо использовать именованный пакет. Затем используйте FQCN для решения проблемы.