简体   繁体   English

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

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

I was looking as the question : Instantiate a class from its string name which describes how to instantiate a class when having its name.我正在寻找一个问题: 从它的字符串名称实例化一个类,它描述了如何在拥有它的名称时实例化一个类。 Is there a way to do it in Java?有没有办法在Java中做到这一点? I will have the package name and class name and I need to be able to create an object having that particular name.我将拥有包名和类名,并且我需要能够创建一个具有该特定名称的对象。

Two ways:两种方式:

Method 1 - only for classes having a no-arg constructor方法 1 - 仅适用于具有无参数构造函数的类

If your class has a no-arg constructor, you can get a Class object using Class.forName() and use the newInstance() method to create an instance (though beware that this method is often considered evil because it can defeat Java's checked exceptions).如果你的类有一个无参数构造函数,你可以使用Class.forName()获取一个Class对象并使用newInstance()方法来创建一个实例(尽管要注意这个方法通常被认为是邪恶的,因为它可以击败 Java 的检查异常)。

For example:例如:

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

Method 2方法二

An alternative safer approach which also works if the class doesn't have any no-arg constructors is to query your class object to get its Constructor object and call a newInstance() method on this object:如果类没有任何无参数构造函数,另一种更安全的方法也适用,它是查询类对象以获取其Constructor对象并在该对象上调用newInstance()方法:

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

Both methods are known as reflection .这两种方法都称为 反射 You will typically have to catch the various exceptions which can occur, including things like:您通常必须捕获​​可能发生的各种异常,包括:

  • the JVM can't find or can't load your class JVM 找不到或无法加载您的类
  • the class you're trying to instantiate doesn't have the right sort of constructors您尝试实例化的类没有正确类型的构造函数
  • the constructor itself threw an exception构造函数本身抛出异常
  • the constructor you're trying to invoke isn't public您尝试调用的构造函数不是公开的
  • a security manager has been installed and is preventing reflection from occurring已安装安全管理器并防止发生反射
MyClass myInstance = (MyClass) Class.forName("MyClass").newInstance();

To make it easier to get the fully qualified name of a class in order to create an instance using Class.forName(...) , one could use the Class.getName() method.为了使用Class.forName(...)创建实例更容易获得类的完全限定名称,可以使用Class.getName()方法。 Something like:就像是:

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

Then you can cast the object you get back to whatever class you pass to makeObject(...) :然后你可以将你得到的对象转换回你传递给makeObject(...)任何类:

Data d = (Data) objectMaker.makeObject(Data.class);

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

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

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

This will cause class named A initialized.这将导致名为 A 的类被初始化。

Use java reflection使用java反射

Creating New Objects There is no equivalent to method invocation for constructors, because invoking a constructor is equivalent to creating a new object (to be the most precise, creating a new object involves both memory allocation and object construction).创建新对象 没有等同于构造函数的方法调用,因为调用构造函数等同于创建一个新对象(最准确地说,创建一个新对象涉及内存分配和对象构造)。 So the nearest equivalent to the previous example is to say:所以与前面的例子最接近的等价物是:

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

which finds a constructor that handles the specified parameter types and invokes it, to create a new instance of the object.它找到处理指定参数类型的构造函数并调用它,以创建对象的新实例。 The value of this approach is that it's purely dynamic, with constructor lookup and invocation at execution time, rather than at compilation time.这种方法的价值在于它是纯动态的,在执行时而不是在编译时进行构造函数查找和调用。

Class.forName("ClassName") will solve your purpose. Class.forName("ClassName")将解决您的目的。

Class class1 = Class.forName(ClassName);
Object object1 = class1.newInstance();
String str = (String)Class.forName("java.lang.String").newInstance();

something like this should work...这样的事情应该工作......

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