繁体   English   中英

有没有办法在Java中按名称实例化一个类?

[英]Is there a way to instantiate a class by name in Java?

我正在寻找一个问题: 从它的字符串名称实例化一个类,它描述了如何在拥有它的名称时实例化一个类。 有没有办法在Java中做到这一点? 我将拥有包名和类名,并且我需要能够创建一个具有该特定名称的对象。

两种方式:

方法 1 - 仅适用于具有无参数构造函数的类

如果你的类有一个无参数构造函数,你可以使用Class.forName()获取一个Class对象并使用newInstance()方法来创建一个实例(尽管要注意这个方法通常被认为是邪恶的,因为它可以击败 Java 的检查异常)。

例如:

Class<?> clazz = Class.forName("java.util.Date");
Object date = clazz.newInstance();

方法二

如果类没有任何无参数构造函数,另一种更安全的方法也适用,它是查询类对象以获取其Constructor对象并在该对象上调用newInstance()方法:

Class<?> clazz = Class.forName("com.foo.MyClass");
Constructor<?> constructor = clazz.getConstructor(String.class, Integer.class);
Object instance = constructor.newInstance("stringparam", 42);

这两种方法都称为 反射 您通常必须捕获​​可能发生的各种异常,包括:

  • JVM 找不到或无法加载您的类
  • 您尝试实例化的类没有正确类型的构造函数
  • 构造函数本身抛出异常
  • 您尝试调用的构造函数不是公开的
  • 已安装安全管理器并防止发生反射
MyClass myInstance = (MyClass) Class.forName("MyClass").newInstance();

为了使用Class.forName(...)创建实例更容易获得类的完全限定名称,可以使用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);

从 Java 8 开始,不推荐直接使用newInstance() 。您需要使用Class.getDeclaredConstructor(...).newInstance(...)以及相应的例外。

使用Class.forName("String name of class").newInstance();

Class.forName("A").newInstance();

这将导致名为 A 的类被初始化。

使用java反射

创建新对象 没有等同于构造函数的方法调用,因为调用构造函数等同于创建一个新对象(最准确地说,创建一个新对象涉及内存分配和对象构造)。 所以与前面的例子最接近的等价物是:

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);
         }
      }
   }

它找到处理指定参数类型的构造函数并调用它,以创建对象的新实例。 这种方法的价值在于它是纯动态的,在执行时而不是在编译时进行构造函数查找和调用。

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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM