java.lang.NoSuchMethodException from a Class.forName instantiation

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:

  1. getSketchInnerClassConstructor() → returns a ClassConstructor.
  2. instantiateSketchInnerClass() → returns an instance from a Constructor.

Also made 2 functions to find nested classes:

  1. findAllSketchInnerClasses() → returns an array of all inner classes.
  2. 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;
  }
}