Question

I'm experiment with Generic Classes, and I've run into a hurdle which I cannot overcome. In short, I'm encountering an error which I do not understand why it is being thrown: InstantiationException

In the documentation it defines this exception as:

Thrown when an application tries to create an instance of a class using the newInstance method in class Class, but the specified class object cannot be instantiated because it is an interface or is an abstract class.

Now the problem that has me scratching my head is that I do not use the abstract or interface keyword. I've also heard that it could be due to not having a default constructor (which I have). Just to be sure, I reduced my code to the minimal possible, but still gives an error:

package Sandbox;

public class Sandbox {


    public static void main(String[] args) {
        Sandbox box = new Sandbox();
    }

    public Sandbox() {
        aMethod(subThread.class);
    }

    public void aMethod(Class<? extends superThread> type) {
        try {

            System.out.println("isInterface: "+type.isInterface());
            System.out.println("isAssignableFrom of subThread: "+type.isAssignableFrom(subThread.class));

            superThread t = type.newInstance();

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private class superThread { // implements Runnable {

        public superThread() {}

        public void run() {}
    }

    private class subThread extends superThread {

        public subThread() {
            super();
        }

        public void run() {
            // more stuff
        }
    }
}

The Output:

isInterface: false
isAssignableFrom of subThread: true
java.lang.InstantiationException: Sandbox.Sandbox$subThread
    at java.lang.Class.newInstance0(Unknown Source)
    at java.lang.Class.newInstance(Unknown Source)
    at Sandbox.Sandbox.aMethod(Sandbox.java:20)
    at Sandbox.Sandbox.<init>(Sandbox.java:11)
    at Sandbox.Sandbox.main(Sandbox.java:7)

I'm sure it's quite simple, but I cannot figure this one out. I've tried several things, but nothing has helped. Any and all help is appreciated.

Thanks, Jon

Was it helpful?

Solution

It's because your inner classes are private. Simple fix:

public static class superThread { // implements Runnable {

    public superThread() {}

    public void run() {}
}

public static class subThread extends superThread {

    public subThread() {
        super();
    }

    public void run() {
        // more stuff
    }
}

The reasoning is because Class.newInstance must be able to access the constructor for the class you want to create.

Since the class is private, it's not accessible. Also, in order to access a non-static inner class, you essentially have to have an existing instance of the outer class (Sandbox), which newInstance doesn't have. As a result, having either public non-static or private static wouldn't work.

OTHER TIPS

After zjagannatha pointed to the real problem, I also found a fix to my own code that allows me to keep the methods as non-static... essentially I discovered that even though the constructor had zero parameters, Constructor treated it as if it had one. I got it to list the parameter and found it odd that it needed a Sandbox class (I assume the one I'm currently working in) To allow a non-static class, I would need to change my newInstance code to this:

type.getConstructor(this.getClass()).newInstance(this);

and this works as well

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top