Java Reflection question...

jman19

Lifer
Nov 3, 2000
11,225
664
126
Assuming I correctly understand some things I've read about using Java's refelction package, it is possible to create an object of a certain type at runtime, using a variable containing the name of said object amongst other things (the types required by the objects constructor). However, since the object type is determined at runtime, it isn't possible to call a method from that object... the compiler won't allow this (due to type checking I assume). Is there any way to get around this problem? (Sorry if I'm not clear, I might add an example later.) Thanks!
 

lozina

Lifer
Sep 10, 2001
11,711
8
81
Are you referring to creating an instance of an existing class or creating a class during runtime and then instantiating it?
 

statik213

Golden Member
Oct 31, 2004
1,654
0
0
Try Class.forName("package.classname"); Look at the Class class for more info.

forName(String className) Returns the Class object associated with the class or interface with the given string name
 

jman19

Lifer
Nov 3, 2000
11,225
664
126
OK, here is an example of what I'm trying to do...

limport java.io.*;
import java.lang.reflect.*;

public class ReflectionTest {

public static void main(String[] argv) {
String name = argv[0];

try{
Class[] paramTypes = new Class[]{String.class};
Class stringer = Class.forName(name);
Constructor ctr = stringer.getDeclaredConstructor(paramTypes);

System.out.println("Value is: " + ctr.newInstance(new Object[]{argv[1]}));
} catch(Exception e) {e.printStackTrace();}
}
}

Now, when I run this code with the arg[0] = "Integer" and arg[1] = "5", the printout says "Value is: 5" as is expected. However, if I wanted to use a function of this new instance that is native only to the class being created, there is a compile error. In this case, I can use the toString method of Integer as it is a method of Object as well. Is there any way to create an object and use a method on it that doesn't belong to a supertype of said object?
 

lozina

Lifer
Sep 10, 2001
11,711
8
81
That's because you have to use the special Method class to invoke methods on reflected objects...

for example, if you did this:

Method[] methods = stringer.getMethods();
for (int x = 0; x < methods.length; x++) {
System.out.println(methods[x].getName());
}

You'll see all the methods for that class, so for Integer you'll see:

hashCode
compareTo
compareTo
equals
toString
toString
toString
toHexString
valueOf
valueOf
decode
byteValue
shortValue
intValue

etc...


notice some are repeated because of overloaded methods.

Now to actually invoke a method go like this (let's try the longValue() method of Integer):



 

jman19

Lifer
Nov 3, 2000
11,225
664
126
Originally posted by: lozina
That's because you have to use the special Method class to invoke methods on reflected objects...

for example, if you did this:

Method[] methods = stringer.getMethods();
for (int x = 0; x < methods.length; x++) {
System.out.println(methods[x].getName());
}

You'll see all the methods for that class, so for Integer you'll see:

hashCode
compareTo
compareTo
equals
toString
toString
toString
toHexString
valueOf
valueOf
decode
byteValue
shortValue
intValue

etc...


notice some are repeated because of overloaded methods.

Now to actually invoke a method go like this (let's try the longValue() method of Integer):

Yeah, you know, I just talked to a colleague about this and he told me pretty much what you just said. I guess I didn't take a close enough look at the Reflection API. Thanks for the example, it's a big help :thumbsup: