Внутренний класс Java с тем же именем, что и другой класс верхнего уровня - PullRequest
5 голосов
/ 05 мая 2011

У меня есть вопрос, связанный с внутренними классами 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 ]

9 голосов
/ 05 мая 2011

Используйте полное имя класса:

new com.mypackage.A();
4 голосов
/ 05 мая 2011

Вы должны предоставить разные имена пакетов для ваших двух A с тем, чтобы они были явно разными типами, тогда вы можете ссылаться на них по их полным именам.

Например:

my.package.for.toplevel.A outerA = new my.package.for.toplevel.A(); // prints "A outer"
                                                                    // if this is the
                                                                    // package

Или, что еще лучше, используйте два разных имени для двух разных классов.

4 голосов
/ 05 мая 2011

Если ваши классы находятся в пакетах, я ожидаю, что это будет самый простой способ достичь этого.Я не верю, что есть какой-то эквивалент C # global:: для Java, чтобы заставить подобные вещи.

В конечном счете, я бы просто попытался изменить имена классов, чтобы избежать проблемы, возникающей впервое место.Обычно это лучший подход, чем использование обходных путей.

3 голосов
/ 05 мая 2011

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

Если класс верхнего уровня находится в пакете по умолчанию (в этом случае его каноническое имя совпадает с его простым именем), вы все равно можетеполучить к нему доступ через отражение.

1 голос
/ 05 мая 2011

Да, просто используйте пакеты или не называйте их одинаковыми с самого начала.Интересно, какова ваша причина называть их одинаковыми в любом случае?

Чтобы объяснить вашу ошибку, это происходит из-за того, что он пытается получить доступ к внутренней А, но так как этот класс не объявлен как статический, и нет Mainэкземпляр доступен, он не может создать нестатический внутренний объект A, для которого требуется ссылка на родительский экземпляр Main.

0 голосов
/ 06 августа 2012

Предполагается, что классы находятся в пакете по умолчанию.Для разрешения конфликта именования в этом случае необходимо либо переименовать конфликтующие классы, либо использовать именованный пакет.Затем используйте FQCN для решения проблемы.

...