java анонимный внутренний класс недоступный код - PullRequest
2 голосов
/ 21 января 2011

Компилятор Java жалуется, когда вы пишете код, который недоступен. Например

public void go()
{
    return;
    System.out.println("unreachable");
}

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

class A
{
   public void go()
   {
     System.out.println("reachable - A");
   }
}
class B
{
   public static void main(String [] args)
   {
     A a = new A() {
              public void go()
              {
                System.out.println("reachable - B");
              }
              public void foo()
              {
                System.out.println("unreachable - B");
              }
           };
     a.go(); // valid
     a.foo(); // invalid, compiler error
  }
}

Ответы [ 4 ]

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

Это равносильно тому, что вы можете создавать приватные методы, которые нигде в классе не вызываются.Это не недостижимый код в том же смысле - и к нему можно получить доступ путем отражения.

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

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

Прежде всего: Eclipse уведомляет , что foo() никогда не используется локально.Это предупреждение, а не ошибка, однако по причинам, указанным другими anserws.

Обратите внимание, что есть способ достичь foo():

new A() {
      public void go()
      {
        System.out.println("reachable - B");
      }
      public void foo()
      {
        System.out.println("unreachable - B");
      }
}.foo();

Это работает, потому чтотип выражения new A() {} не A, а фактически анонимный подкласс A.И у этого подкласса есть общедоступный метод foo.

Поскольку вы не можете иметь переменную того же типа, вы не можете получить доступ к foo() таким образом из переменной.

4 голосов
/ 21 января 2011

В принципе, вы можете вызвать метод foo() для a с помощью отражения, поэтому он не всегда недоступен.

Попробуйте это после a.go();:

Method m = a.getClass().getDeclaredMethod("foo");
m.invoke(a);
0 голосов
/ 21 января 2011
public void go()
{
   foo();
   System.out.println("reachable - B");
}

public void foo()
{
   System.out.println("unreachable - B");
}

Просто еще один способ получить доступ к методу foo, это использовать другой метод класса. Я должен был понять это, прежде чем спрашивать. К сожалению.

...