Home > Back-end >  Java Reflection: how can you get constructor of a class you don't know?
Java Reflection: how can you get constructor of a class you don't know?

Time:03-22

Let's say you're making a general reflection class. You're given the name of the class in string format: So you do Class.forName(class_name) to get the class name.

Next step would be to get the constructor and you can do Class.forName(class_name).getConstructor(null) assuming that there isn't any args.

How do you now get an instance of this? You would have to downcast but what do you downcast to? class_name name = (what goes here) Class.forName(class_name).getConstructor(null).newInstance(null)

I tried to put in the class_name in the parenthesis class_name name = (class_name) Class.forName(class_name).getConstructor(null).newInstance(null) but getting an error. Well not compiling.

Update: Only thing known is that the constructor doesn't have any args, and instance doesn't have parameters. So you can pass null to both.

CodePudding user response:

What you're asking for is impossible.

If you load the class using Class.forName(someClassName), it means you do not know at compile time what the class will be, you will only know it at runtime (when the value of someClassName will be defined).

That means, you can't code based on that specific type (because if you want to have typed code at compile time, then you should know the exact type at compile time and that's not your case).

However, even though you can only declare your instance as Object obj = ... instead of SomeClassName obj = ... (which I understand is what you wanted to do), be reassured that your obj will actually be an instance of SomeClassName at runtime, even if the compiler doesn't know it yet.

If you add more details about what you're trying to do (I mean why do you need to cast the reflected instance to the specific type), then I can complete my answer to address your exact concern.

CodePudding user response:

The classes Class and Constructor provide everything you need to accomplish your goal.

  1. From Class.forName(String) you get the Class object.
  2. By calling its getConstructors() method you get an array of Constructor objects (representing the declarations of the constructors).
    See the javadoc of Class.getConstructors().
  3. Then by calling the getParameterTypes() method of any of these Constructors you get an array of Class objects (the types of the formal parameters of a constructor).
    See the javadoc of Constructor.getParameterTypes().
  4. Now you know what types of parameters any constructor needs. Then you can actually invoke the constructor with such parameters by calling constructor.newInstance(param1, param2, ...).

Example: with this code

Class<?> clazz = Class.forName("java.util.HashMap");
System.out.println(clazz);
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor<?> constructor : constructors) {
    System.out.println("  constructor: "   constructor);
    Class<?>[] parameterTypes = constructor.getParameterTypes();
    for (Class<?> parameterType : parameterTypes) {
        System.out.println("    parameterType: "   parameterType);
    }
}

you get all constructors of java.util.HashMap and their parameter types:

class java.util.HashMap
  constructor: public java.util.HashMap(int)
    parameterType: int
  constructor: public java.util.HashMap(int,float)
    parameterType: int
    parameterType: float
  constructor: public java.util.HashMap(java.util.Map)
    parameterType: interface java.util.Map
  constructor: public java.util.HashMap()
  • Related