2011-01-21 5 views
2

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

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 
    } 
} 
+0

Вам не хватает скобки '()' после 'нового A' и скобки'}; 'для завершения объявления анонимного внутреннего класса. – Jesper

+0

Ваш код примера не компилируется вообще. Пожалуйста исправьте. – PeterMmm

+0

Я просто скопировал его в файл B.java и прокомментировал строку a.foo(), затем скомпилировал ее и запустил. Извините, но я не вижу никакой ошибки в коде, кроме части a.foo(), о которой я уже упоминал, что она вызывает ошибку компиляции. – kioto

ответ

5

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

Обратите внимание, что есть способ достичь 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() таким образом из переменной.

+0

Спасибо. Очень хороший способ вызвать метод. Внутренние классы имеют очень интересные свойства – kioto

4

В принципе можно было бы назвать метод foo() на a через отражение, так что это не всегда недостижим.

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

Method m = a.getClass().getDeclaredMethod("foo"); 
m.invoke(a); 
+1

А также EL-язык в JSP/Facelets. –

+0

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

+0

@kioto, это не имеет значения, если это делает * смысл * или нет, важно то, что это возможно *. Ответ Иоакима действительно хорош. – Jesper

5

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

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

+0

Спасибо, ты тоже прав. Можно получить доступ к этому методу в рамках другого метода внутреннего класса. Я вижу сейчас. – kioto

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

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

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