Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic instance creation without generics

Tags:

java

I would like to understand why the following doesn't work:

public class HelloClass {

    private class MyClass
    {
        public MyClass() 
        {
           System.out.println ("Oh heck this is me!");   
        }
    }

    public Object newInstance (Object o)
    {
        try {
            // java.lang.InstantiationException here
            return o.getClass().newInstance();        
        } catch (Exception e) {
            e.printStackTrace(System.out);
            return null;
        }
    }

    public void run()
    {
        MyClass m = new MyClass();  
        Object o = newInstance(m);
    }

    public static void main(String[] args) 
    {
        HelloClass hd = new HelloClass();
        hd.run();
    }
}

I know of the correct way to achieve this via declaring the newInstance argument as Class<T>, but would like to understand why it cannot be done like the above.

UPD: Here is the exception I'm getting:

java.lang.InstantiationException: HelloClass$MyClass
    at java.lang.Class.newInstance0(Class.java:340)
    at java.lang.Class.newInstance(Class.java:308)
    at HelloClass.newInstance(HelloClass.java:14)
    at HelloClass.run(HelloClass.java:24)
    at HelloClass.main(HelloClass.java:30)
like image 242
azerole Avatar asked Feb 06 '10 18:02

azerole


2 Answers

Constructors to inner classes have a hidden first argument that you need to provide when you use reflection. Pass an instance of the outer class.

Instead of

return o.getClass().newInstance();

use:

return o.getClass().getConstructor(getClass()).newInstance(this);
like image 111
Kevin Avatar answered Oct 02 '22 19:10

Kevin


The problem seems to be that it's a non-static member class, as it works both if you declare MyClass as static and if you make it a top-level class. Not quite sure why, though.

like image 29
Fabian Steeg Avatar answered Oct 02 '22 21:10

Fabian Steeg