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.
- From
Class.forName(String)
you get theClass
object. - By calling its
getConstructors()
method you get an array ofConstructor
objects (representing the declarations of the constructors).
See the javadoc ofClass.getConstructors()
. - Then by calling the
getParameterTypes()
method of any of theseConstructor
s you get an array ofClass
objects (the types of the formal parameters of a constructor).
See the javadoc ofConstructor.getParameterTypes()
. - 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()