簡體   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