Abdull
Abdull

Reputation: 27822

Instantiating a Java local class reflectively

In Java, is there a way or hack to instantiate a local class reflectively?

This is my test class:

package com.example.localclass;

import org.junit.Test;

public class LocalClassInstantiationTest {

    @Test
    public void testInstantiateLocalClassReflectively() {
        System.out.println("About to define local class");
        class LocalClass {
            void print() {
                System.out.println("Hello world");
            }
        }

        System.out.println("--------------------Direct instantiation------------------------");
        LocalClass localClassInstance;
        localClassInstance = new LocalClass();
        localClassInstance.print();

        System.out.println("--------------------Reflective instantiation--------------------");
        Class<LocalClass> localClazz = LocalClass.class;
        System.out.println("Local class name: " + localClazz.getName() );
        System.out.println("Local class canonical name: " + localClazz.getCanonicalName() );
        System.out.println("Local class constructors array length: " + localClazz.getConstructors().length);
        System.out.println("About to create local class instance reflectively");

        try {
            localClassInstance = localClazz.newInstance();
            localClassInstance.print();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }

    }

}

When I run it, I get the following result:

About to define local class
--------------------Direct instantiation------------------------
Hello world
--------------------Reflective instantiation--------------------
Local class name: com.example.localclass.LocalClassInstantiationTest$1LocalClass
Local class canonical name: null
Local class constructors array length: 0
About to create local class instance reflectively
java.lang.InstantiationException: com.example.localclass.LocalClassInstantiationTest$1LocalClass
    at java.lang.Class.newInstance0(Class.java:357)
    at java.lang.Class.newInstance(Class.java:325)
    at com.example.localclass.LocalClassInstantiationTest.testInstantiateLocalClassReflectively(LocalClassInstantiationTest.java:32)

Upvotes: 1

Views: 1149

Answers (1)

Peter Lawrey
Peter Lawrey

Reputation: 533492

In your case, the problem is that there is no empty constructor for your class. The newInstance() assumes you have one and fails if you don't.

If you run this in a static method such as main, you don't get this error.

This is because you have a non-static anonymous class and implicitly requires a reference to your outer class LocalClassInstantiationTest whether you use it or not.

You could try this instead.

System.out.println("Local class constructors array length: " + 
                   localClazz.getDeclaredConstructors().length);
System.out.println("About to create local class instance reflectively");

try {
    localClassInstance = localClazz
            .getDeclaredConstructor(LocalClassInstantiationTest.class)
            .newInstance(this);
    localClassInstance.print();
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
    e.printStackTrace();
}

and your program prints

About to define local class
--------------------Direct instantiation------------------------
Hello world
--------------------Reflective instantiation--------------------
Local class name: LocalClassInstantiationTest$1LocalClass
Local class canonical name: null
Local class constructors array length: 1
About to create local class instance reflectively
Hello world

Upvotes: 4

Related Questions