2012-06-07 137 views
1

假設我有這樣的如何在運行時創建指定類類型的對象?

public void readAndInitialize(StringReader reader, Class className) 
    { 
    // Here, I want to to something like this - 

    // obj = new (object of the specified className) 

     obj.readAndInitialize(reader); 
    } 

的方法如何在Java中做到這一點?

回答

4

雖然每個人都很快指出Class.forName("com.myorg.MyClass");和相關的newInstance()方法,但重要的是要記住它只會調用一個不帶參數的默認構造函數。

如果您發現需要調用該類的特定構造函數,則需要使用反射來查找正確的構造函數,然後調用它。

import java.lang.reflect.Constructor; 
import java.lang.reflect.Type; 
import static java.lang.System.out; 

public class ConstructorSift { 
    public static void main(String... args) { 
    try { 
     Class<?> cArg = Class.forName(args[1]); 

     Class<?> c = Class.forName(args[0]); 
     Constructor[] allConstructors = c.getDeclaredConstructors(); 
     for (Constructor ctor : allConstructors) { 
     Class<?>[] pType = ctor.getParameterTypes(); 
     for (int i = 0; i < pType.length; i++) { 
      if (pType[i].equals(cArg)) { 
      out.format("%s%n", ctor.toGenericString()); 

      Type[] gpType = ctor.getGenericParameterTypes(); 
      for (int j = 0; j < gpType.length; j++) { 
       char ch = (pType[j].equals(cArg) ? '*' : ' '); 
       out.format("%7c%s[%d]: %s%n", ch, 
         "GenericParameterType", j, gpType[j]); 
      } 
      break; 
      } 
     } 
     } 

     // production code should handle this exception more gracefully 
    } catch (ClassNotFoundException x) { 
     x.printStackTrace(); 
    } 
    } 
} 

列出了所有構造函數and a tutorial is available here

一旦你找到所需的構造函數,你可以調用它像這樣

import java.lang.reflect.Constructor; 
import java.lang.reflect.Field; 
import java.lang.reflect.InvocationTargetException; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.Set; 
import static java.lang.System.out; 

class EmailAliases { 
    private Set<String> aliases; 
    private EmailAliases(HashMap<String, String> h) { 
    aliases = h.keySet(); 
    } 

    public void printKeys() { 
    out.format("Mail keys:%n"); 
    for (String k : aliases) 
     out.format(" %s%n", k); 
    } 
} 

public class RestoreAliases { 

    private static Map<String, String> defaultAliases = new HashMap<String, String>(); 
    static { 
    defaultAliases.put("Duke", "[email protected]"); 
    defaultAliases.put("Fang", "[email protected]"); 
    } 

    public static void main(String... args) { 
    try { 
     Constructor ctor = EmailAliases.class.getDeclaredConstructor(HashMap.class); 
     ctor.setAccessible(true); 
     EmailAliases email = (EmailAliases)ctor.newInstance(defaultAliases); 
     email.printKeys(); 

     // production code should handle these exceptions more gracefully 
    } catch (InstantiationException x) { 
     x.printStackTrace(); 
    } catch (IllegalAccessException x) { 
     x.printStackTrace(); 
    } catch (InvocationTargetException x) { 
     x.printStackTrace(); 
    } catch (NoSuchMethodException x) { 
     x.printStackTrace(); 
    } 
    } 
} 

這又是,from the tutorial about reflection

2

注意,在你的榜樣,你正在傳遞的className爲Class對象,所以你可以這樣做:

className.newInstance(); 

但我懷疑,你正在尋找一種方式來傳遞類名作爲String,在這種情況下,程序(這裏classNameString):

​​

請注意,您還需要處理由兩個呼叫拋出的Exceptions

這是最簡單的情況,不包括,例如,具體的構造函數。

請參閱the docs for Class。

1
public void readAndInitialize(StringReader reader, String className) //className changed to String 
    { 
    // Here, I want to to something like this - 
    // obj = new (object of the specified className) 

     //try this: 
     Class myclass = Class.forName(className); 
     Object obj = myclass.newInstance(); 

     obj.readAndInitialize(reader); 
    } 
1

如果我正確理解這個問題。從給定的類的對象應該是這樣創建:

if (yourClass != null) { 
    Object yourObject = null; 
    try { 
     yourObject = yourClass.newInstance(); 
    } catch (InstantiationException e) { 
     LOGGER.error("", e);    
    } catch (IllegalAccessException e) { 
     LOGGER.error("", e); 

    } 
} 
0

你可以做你想要使用Class.newInstance(什麼)(僅適用於零參數的構造函數)或Constructor.newInstance()。有關工作示例,請參閱here

0

取決於如果你得到一個對象已經或只是一個類名字符串,我將做到以下幾點:

  1. 實例化對象如同上述,使用反射,你的類名的字符串;如果你得到一個對象已經,您可以跳過這一步
  2. 確保你的對象從一個類或者接口,用於通過的instanceof
  3. 投你的對象類,你檢查的一個步驟的公共方法readAndAnalyze(...)繼承以上通過instanceof
  4. 調用方法並繼續
相關問題