问题
Is it possible to construct a List<Object>
wherein the elements are uninstantiated classes, with the intention of getting one of the list elements and running a static method from that class or instantiating a new instance of that class? Also, how might one do this and how inadvisable is it (and why)?
To add some context: I want to make an application which generates a randomized city, placing buildings in the city, where each building is an instance of one of the many building classes, each inheriting from an abstract base class. To choose a building appropriate for a certain piece of land, the program may iterate over a list of all possible building classes, checking whether the required parameters can be met for that building (minimum / maximum height, footprint, shape, etc.) or these classes may be stored in some other manner, possibly using maps or some other structures. The bottom line is that I need to store (refferences?) to uninstantiated classes.
回答1:
You cannot store types, but you can store the Class object for each class loaded by the JVM. When the JVM loads and initializes a class on the classpath, it creates a single Class
object for that class.
The Class
class gives you access to a number of instance methods for performing reflection on your program.
Also, how might one do this and how inadvisable is it (and why)?
For example
List<Class<?>> classes = new ArrayList<>();
classes.add(Example.class);
Now you can go through the elements and call different methods depending on what you want to do. If you want to create a new instance (and your class has a no-arg constructor), you can do
classes.get(0).newInstance();
If you don't have a no-argument constructor, you will need to get Constructor references from the Class
object.
If you need to invoke methods (whether static
or not), you need to get a Method reference. Read through the javadoc.
how inadvisable is it (and why)?
There are some things you cannot do without reflection, but it is generally discouraged.
- What is reflection and why is it useful?
- Java Reflection Performance
- Why should I use reflection?
- Java Reflection: Why is it so slow?
- Why is Java's reflection package considered the dark side of the force?
You should try to minimize using Reflection when you can very well use the Factory
pattern to achieve your goals in this situation.
User user2864740 suggests
I would have a list of "factories that know how to create the appropriate object", if practical - really depends upon where this data comes from and what role it has.
回答2:
You can instantiate instances of a Class<?>
like this -
List<Class<?>> al = new ArrayList<>();
al.add(java.util.Date.class);
for (Class<?> cls : al) {
try {
Constructor<?> ctor = cls.getConstructor(null);
Object o = ctor.newInstance(null);
System.out.println(o);
} catch (Exception e) {
e.printStackTrace();
}
}
Which, when I just ran it, output
Sun Dec 22 00:56:06 EST 2013
来源:https://stackoverflow.com/questions/20726652/java-list-of-uninstantiated-classes