2

Java compiler complains when you write a code that is unreachable. For example

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

However, when you define a new method in an anonymous class which cannot be reached from anywhere, compiler does not complain. It allows you to do that, why? For example,

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
  }
}
Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
kioto
  • 93
  • 1
  • 4
  • You're missing parenthesis `()` after `new A` and a brace `};` to end the declaration of the anonymous inner class. – Jesper Jan 21 '11 at 08:11
  • Your example code does not compile at all. Please correct. – PeterMmm Jan 21 '11 at 08:12
  • I just copied it to B.java file and commented the line a.foo(), then compiled it and ran it. Sorry, but I couldn't see any error in the code except a.foo() part which I already mentioned that it causes a compile error. – kioto Jan 21 '11 at 12:28
  • Another way of calling the method not yet mentioned, is that it might be run with an updated version of `A` that provides a `foo` method. – Tom Hawtin - tackline Jan 21 '11 at 16:07

4 Answers4

5

That's only equivalent to allowing you to create private methods which aren't called anywhere in the class, really. It's not unreachable code in quite the same sense - and it could be accessed by reflection.

It's the kind of thing which might reasonably give a warning (particularly on IDEs which allow very fine-grained tweaking of warnings) but I don't think it should be an error.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thank you, you are also right. One can access that method within another method of the inner class. I see now. – kioto Jan 21 '11 at 12:33
5

First of all: Eclipse does notify my that foo() is never used locally. It's a warning and not an error, however, for reasons pointed out by the other anserws.

Note that there is a way to reach foo():

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

This works, because the type of the expression new A() {} is not A, but actually the anonymous subclass of A. And that subclass has a public foo method.

Since you can't have a variable with the same type, you can't access foo() this way from a variable.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • Thank you. A very nice way to invoke the method. Inner classes have very interesting propertiesç – kioto Jan 21 '11 at 12:35
4

In principle you could call the foo() method on a via reflection, so it is not always unreachable.

Try this after a.go();:

Method m = a.getClass().getDeclaredMethod("foo");
m.invoke(a);
Jesper
  • 202,709
  • 46
  • 318
  • 350
  • 1
    As well as the EL-language in JSP/Facelets. – Thorbjørn Ravn Andersen Jan 21 '11 at 08:10
  • Thank you. You are right. But I think it doesn't make sense to reach a method of anonymous inner class via reflection. However, as mentioned in other answer, there are other ways to reach it. – kioto Jan 21 '11 at 12:32
  • @kioto, it doesn't matter if it makes *sense* or not, what matters is that it's *possible*. Joachim's answer is indeed good. – Jesper Jan 24 '11 at 09:39
0
public void go()
{
   foo();
   System.out.println("reachable - B");
}

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

Simply another way to reach the foo method it to use it another method of the class. I should have understood this before asking. Sorry.

kioto
  • 93
  • 1
  • 4