Is there any way to instantiate a class defined in anonymous inner class?
Asked Answered
T

1

3

I was randomly writing a code & encountered a problem: how to instantiate class E (shown below) which is defined within an anonymous inner class; like:

 A c = new A() {
   class E{ //Statements
     }
 };
Thormora answered 23/3, 2017 at 18:34 Comment(6)
Why not declare the anonymous class outside of A? You'd be able to use it inside A in that case.Someway
no because IT IS AN INNER ANONYMOUS CLASS to instanciate something he must be seen ( let say outer ) and it must be know (not really but perhaps all the time ) but is anonymous , So NOMucker
@MohammedHousseynTaleb: please, be more clear.Thormora
sorry for my bad english, but what I tried to say is about logic, instantiation is About visibility, an inner Anonymous class is not visible ( let say scoop ) outside his parent class in your case A, more we have to pay attention that your example is more harder because your anonymous inner class is only a property ( mathematically said ) of your instance new A(). so try to be humanly a class and you want to call for my inner class that is hiden in my pocket knowing that this class somebody unknown has made it there ... this is somehow philosophical so try read more about OO paradigm.Mucker
@SuyashJain as answered below it needs a work around since to acces it it needs an identifier, thus i proposed a solution in my answer below for accesing it by using an interface insteadHogback
Update: you got me curious; I updated my answer ... with some reflection code that instantiates an inner class of an anonymous inner class.Elide
E
2

You can't write a program that uses an ordinary call to new to do that: in order for a class to be instantiated, it must have a name. Anonymous inner classes, as that term implies, do not have a name.

Thus a class that exists within that anonymous inner class also has no name; thus it can not be instantiated outside of that anonymous inner class.

But you can use reflection. See my Test.java:

import java.util.*;
import java.lang.reflect.*;

class B { 
  B() { System.out.println("B"); }
  void foo() { System.out.println("B.foo"); }
}

public class Test{
  B b;
  void bar() {
    b = new B() {
          class C { C() { System.out.println("inner C"); } }
          void foo() { System.out.println("inner foo"); }
    };
    b.foo();
}
public static void main(String[] args) throws Exception {
    Test test = new Test();
    test.bar();

    Class<?> enclosingClass = Class.forName("Test$1");
    Class<?> innerClass = Class.forName("Test$1$C");

    Constructor<?> ctor = innerClass.getDeclaredConstructor(enclosingClass);
    Object innerInstance = ctor.newInstance(test.b);
  }
}

This prints:

B
inner foo
inner C

So, yes, given the fact that we can use the mangled class name Test$1$C at runtime, and that reflection allows us to instantiate objects at runtime, too (see here for details), the final answer is: yes, it is possible.

But just for the record: that doesn't mean at all that one should ever do something like this in real code. This is a nice little puzzle to train creativity; but not suited for anything in the real world.

In the real world, an inner class within an anonymous inner class is a design bug. End of story.

Elide answered 23/3, 2017 at 18:47 Comment(3)
So. there is no way to instantiate a class defined in Anonymous inner class??Thormora
Funny anecdote along the way: I actually thought about "I never run into a JonSkeet answer when searching SO myself". And I just realize that the answer I got that "how to instantiate an inner class using reflection" ... from a JonSkeet answer. Very cool. Now I just two more updates to hit the daily limit, to end this kewl day ;-)Elide
@Elide +1 deleted my answer since this solves the problem in a more direct and better way :)Hogback

© 2022 - 2024 — McMap. All rights reserved.