2013-07-26 3 views
9

Как может статический внутренний класс M и статический член M [из класса C] имеют одно и то же имя?статический внутренний класс и статический член класса разделяет SAME NAME?

Следующий код создает «белый» в качестве вывода:

public class Amazed{ 

    public static void main(String[] args) { 
     System.out.println(B.M.W); 
    } 
} 

class B { 
    public static class M {  
     static String W = "Black"; 
    } 

    static C M = new C(); 
} 

class C { 
    String W = "White"; 
} 

как объект элемента доступен и не является член статического класса: W [ «Black»]

, если я хочу, чтобы получить доступ к член в статическом классе M, как это сделать?

+1

Мне нравится метод 'meth' не принимает вас нигде. Однако очень длинный цикл может быть более уместным. – thatidiotguy

+0

@thatidiotguy: Или что-то, что повторяется, пока оно не ударит стек. –

+0

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

ответ

2

Chapter 6 of the Java Language Specification (особенно Section 6.5) излагает ужасные подробности того, как Java сортирует, что означает, что конкретный идентификатор в определенном контексте. Правила довольно сложны, но, грубо говоря, Java имеет шесть пространств имен:

  • имена пакетов
  • имена типов
  • имена полей (переменных)
  • имена методов
  • имена локальных переменных (включая параметры)
  • этикетки

и тот же идентификатор может быть U sed для объектов в каждом из этих пространств имен. Обратите внимание, что имена типов (классов) и имена полей живут отдельно, что объясняет, почему ваш код является законным.

Унаследованные имена в том же названии также могут быть затенены или замаскированы. Иногда идентификатор неоднозначен; тогда ему необходимо каким-то образом квалифицировать (например,, с именем пакета), или компилятор будет жаловаться.

Код обфускаторы использовать это большое преимущество, до точки, где вы можете в конечном итоге с пакетом под названием a.a и класс с именем a в пакете a (который также будет идентифицирован как a.a). Не говоря уже о том, что ключевые слова Java, такие как do и for, являются юридическими именами в файлах .class (но не в источнике Java). Это помогает сделать реверсирование настоящим медведем.

0

В вашем конкретном случае, когда M может быть обработан, вы можете использовать тот факт, что статика может быть доступна в нестатической образом:

public class Amazed{ 
    @SuppressWarnings("static-access") 
    public static void main(String[] args) { 
     B.M val = new B.M(); 
     System.out.println(val.W); 
    } 
} 

class B { 
    public static class M {  
     static String W = "Black"; 
    } 

    static C M = new C(); 
} 

class C { 
    String W = "White"; 
} 

выше напечатает «Black», потому что снято неоднозначность идентификатор по ссылаясь на него через экземпляр B.M. Разумеется, это не хорошая идея в производственном коде, поскольку статические поля не должны быть доступны нестационарным образом. Аналогично, для этого требуется создать экземпляр B.M.

1

Переменная затеняет тип с тем же именем. Если имя может быть интерпретировано как переменная или тип, переменная является предпочтительной.

Вы можете избежать этого, не давая им то же имя.

Из спецификации языка Java, section 6.4.2: Obscuring:

6.4.2. Obscured

Простые имена могут возникать в контекстах, где это потенциально можно интерпретировать как имя переменной, типа или пакета. В этих ситуациях в правилах раздела 6.5 указывается, что переменная будет выбрана в предпочтении для типа и что тип будет выбран в предпочтении к пакету. Таким образом, иногда бывает невозможно ссылаться на объявление видимого типа или пакета через его простое имя. Мы говорим, что такая декларация скрыта.

+0

как он выбран? Какой порядок предпочтений? – Dineshkumar

+1

1) Переменная 2) Тип 3) Название пакета –

+0

. Тип здесь означает что-либо, кроме класса? – Dineshkumar

0

После каждой помощи и небольшой игры я обнаружил, что даже без создания объекта для внутреннего класса мы можем получить доступ к члену W «Черный».

просто используя эту инструкцию

M.W 

Но я не могу понять уровень доступа. [потому что его публика?] даже без публики это сработало. как это?

Смежные вопросы