0

I need to create instances from each statically defined inner classes, but I get java.lang.ClassNotFoundException.

First, I collect the declared inner classes:

public String[] getInnerClassNames(Class<?> p_class) {
    Class<?>[] declaredClasses = p_class.getDeclaredClasses();
    String[] innerClassNames = new String[declaredClasses.length];
    for (int i = 0; i < declaredClasses.length; i++) {
        innerClassNames[i] = declaredClasses[i].getCanonicalName();
    }
    return innerClassNames;
}

where the p_class is the outer class.

Second, I do the class loading and instantiation for the given inner class name:

public Object createObjectByClassName(String p_className)
        throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    Class<?> clazz = Class.forName(p_className);
    return clazz.newInstance();
}

This inner class name has the form: PACKAGE.OUTER_CLASS_NAME.INNER_CLASS_NAME.

What I am missing here?

  • 2
    Does this answer your question? [How to instantiate an inner class with reflection in Java?](https://stackoverflow.com/questions/17485297/how-to-instantiate-an-inner-class-with-reflection-in-java) – Oleg Mar 01 '20 at 17:16
  • @Oleg I think that answers the obvious follow up question rather than the original. – Tom Hawtin - tackline Mar 01 '20 at 17:18
  • @TomHawtin-tackline Alright, retracted. – Oleg Mar 01 '20 at 17:21

1 Answers1

3

You are missing Class.getName.

Class.getCanonicalName will return the name according to the Java Language Specification. You want the name that the JVM/bytecode is using.

The names differ because the JVM roughly matches the Java 1.0 language. The approach made to compatibility makes everything new look like a bit of a hack at the bytecode level.

Also, the constructor may well be different, as the inner class requires a reference to its context.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
  • *"the name according to the Java Language Specification"* - this is misleading; all kinds of names in Java are "according to the JLS", because the JLS defines the language. What you're referring to is the *binary name*, as opposed to the *simple name* or the *canonical name*. – kaya3 Mar 01 '20 at 17:19