The 3 classes (Dumb, Dumber, Dummy) in my example are both non-static
& non-public
.
So it’s very possible to find such classes as my example already demonstrates.
I’ve split up getDumb() into 2 functions in a separate tab:
- getSketchInnerClassConstructor() → returns a Class’ Constructor.
- instantiateSketchInnerClass() → returns an instance from a Constructor.
Also made 2 functions to find nested classes:
- findAllSketchInnerClasses() → returns an array of all inner classes.
- findSketchNestedClassByName() → returns the nested class of a given name.
Here’s the whole sketch. Just ask again for further questions about it:
“Reflective_Inner_Class_Instantiation_Parameters.pde”:
/**
* Inner Class Instantiation w/ Parameters (v1.0.1)
* GoToLoop (2022/Jul/16)
*
* https://Discourse.Processing.org/t/
* java-lang-nosuchmethodexception-from-a-class-forname-instantiation/37961/6
*/
static final String[] INNER_CLASS_NAMES = { "Dumb", "Dumber", "Dummy" };
static final int CLASSES = INNER_CLASS_NAMES.length;
static final Class<?>[] PARAM_TYPES = { String.class, int.class };
final Class<?>[] innerClasses = new Class<?>[CLASSES];
final Constructor<?>[] innerConstructors = new Constructor<?>[CLASSES];
final Dumb[] innerInstances = new Dumb[CLASSES];
void setup() {
printArray(findAllSketchInnerClasses());
println();
for (int i = 0; i < CLASSES; ++i) innerClasses[i] =
findSketchNestedClassByName(INNER_CLASS_NAMES[i]);
printArray(innerClasses);
println();
for (int i = 0; i < CLASSES; ++i) innerConstructors[i] =
getSketchInnerClassConstructor(innerClasses[i], PARAM_TYPES);
printArray(innerConstructors);
println();
for (int i = 0; i < CLASSES; ++i) innerInstances[i] =
(Dumb) instantiateSketchInnerClass(innerConstructors[i], "abc", 50);
printArray(innerInstances);
exit();
}
class Dumb {
String name;
int age;
Dumb(final String name, final int age) {
this.name = name;
this.age = age;
}
@Override String toString() {
return getClass().getSimpleName() + ": " + name + ", " + age;
}
}
class Dumber extends Dumb {
Dumber(final String name, final int age) {
super(name, age << 1);
}
}
class Dummy extends Dumb {
Dummy(final String name, final int age) {
super(name, age >> 1);
}
}
“Inner_Class_Reflective_Functions.pde”:
import java.util.List;
import static java.util.Arrays.asList;
import java.lang.reflect.Constructor;
import static java.lang.reflect.Modifier.isStatic;
final Class<?>[] findAllSketchInnerClasses() {
final List<Class<?>> nested = new ArrayList<Class<?>>(
asList(getClass().getDeclaredClasses()));
int len = nested.size(), i = len;
while (i-- > 0) if (isStatic(nested.get(i).getModifiers())) {
nested.set(i, nested.get(--len));
nested.remove(len);
}
return nested.toArray(new Class<?>[len]);
}
final Class<?> findSketchNestedClassByName(final String name) {
try {
return Class.forName(getClass().getName() + '$' + name);
}
catch (final ClassNotFoundException ex) {
System.err.println(ex);
return null;
}
}
@SafeVarargs final <T> Constructor<T> getSketchInnerClassConstructor(
final Class<T> inner, final Class<?>... types)
{
final Class<?>[] params = (Class[]) splice(types, getClass(), 0);
try {
return inner.getDeclaredConstructor(params);
}
catch (final NoSuchMethodException ex) {
System.err.println(ex);
return null;
}
}
@SafeVarargs final <T> T instantiateSketchInnerClass(
final Constructor<T> inner, final Object... args)
{
final Object[] params = (Object[]) splice(args, this, 0);
try {
return inner.newInstance(params);
}
catch (final ReflectiveOperationException ex) {
System.err.println(ex);
return null;
}
}