有没有办法在Java中按名称实例化类?
我正在寻找的问题是: 从它的string名称实例化一个类,它描述了如何实例化一个类时,它的名字。 有没有办法在Java中做到这一点? 我将有包名和类名,我需要能够创build具有该特定名称的对象。
两种方式:
方法1 – 仅用于具有无参数构造函数的类
如果你的类有一个无参数的构造函数,你可以使用Class.forName()
来获得一个Class
对象,并使用newInstance()
方法来创build一个实例(不过要注意,这个方法通常被认为是邪恶的,因为它可以打败Java的检查exception)。
例如:
Class<?> clazz = Class.forName("java.util.Date"); Object date = clazz.newInstance();
方法2
如果类没有任何无参数构造函数,另一种更安全的方法是查询类对象以获取其Constructor
对象,并在此对象上调用newInstance()
方法:
Class<?> clazz = Class.forName("com.foo.MyClass"); Constructor<?> constructor = clazz.getConstructor(String.class, Integer.class); Object instance = constructor.newInstance("stringparam", 42);
这两种方法都被称为reflection 。 您通常必须捕获可能发生的各种exception,包括以下内容:
- JVM无法find或无法加载您的课程
- 你正在尝试实例化的类没有正确的构造函数
- 构造函数本身抛出一个exception
- 你试图调用的构造函数是不公开的
- 已经安装了一个安全pipe理器并阻止了reflection的发生
MyClass myInstance = (MyClass) Class.forName("MyClass").newInstance();
使用Class.forName(“类的string名称”)。newInstance();
Class.forName("A").newInstance();
这将导致名为A的类初始化。
为了使得使用Class.forName(...)
创build一个实例更容易得到一个类的全名,可以使用Class.getName()
方法。 就像是:
class ObjectMaker { // Constructor, fields, initialization, etc... public Object makeObject(Class<?> clazz) { Object o = null; try { o = Class.forName(clazz.getName()).newInstance(); } catch (ClassNotFoundException e) { // There may be other exceptions to throw here, // but I'm writing this from memory. e.printStackTrace(); } return o; } }
然后,您可以将您返回的对象转换为您传递给makeObject(...)
任何类:
Data d = (Data) objectMaker.makeObject(Data.class);
使用javareflection
创build新的对象对于构造函数来说,没有等价的方法调用,因为调用构造函数等同于创build一个新的对象(最精确的是创build一个涉及内存分配和对象构造的新对象)。 所以与前面的例子最近的等价是说:
import java.lang.reflect.*; public class constructor2 { public constructor2() { } public constructor2(int a, int b) { System.out.println( "a = " + a + " b = " + b); } public static void main(String args[]) { try { Class cls = Class.forName("constructor2"); Class partypes[] = new Class[2]; partypes[0] = Integer.TYPE; partypes[1] = Integer.TYPE; Constructor ct = cls.getConstructor(partypes); Object arglist[] = new Object[2]; arglist[0] = new Integer(37); arglist[1] = new Integer(47); Object retobj = ct.newInstance(arglist); } catch (Throwable e) { System.err.println(e); } } }
它find一个构造函数来处理指定的参数types并调用它来创build对象的新实例。 这种方法的价值在于它纯粹是dynamic的,在构造函数的查找和调用的时候,而不是在编译时。
Class.forName(“ClassName”)将解决您的目的。
Class class1 = Class.forName(ClassName); Object object1 = class1.newInstance();
String str = (String)Class.forName("java.lang.String").newInstance();
像这样的东西应该工作…
String name = "Test2";//Name of the class Class myClass = Class.forName(name); Object o = myClass.newInstance();