2016-11-15 127 views
1

我想創建一個對象創建器,要求用戶輸入並創建一個對象。我有一個給定類的構造函數的數組,這些構造函數,我讓用戶選擇一個,如果該構造函數有參數,我希望用戶可以即時設置這些參數。使用Java創建原始類型/對象反射

使用java.lang.reflect.Constructor的構造函數列表;如下:

constructorList[0].getGenericParameterTypes()[0] 

這返回的「類型」

陣列是否可以創建這種類型的用戶給予一定的價值的一個實例?說其int類型,如果我想這個int爲10 - (我知道這不會工作,但理論上)

constructorList[0].getGenericParameterTypes()[0] intValue = 10; 

如果它的一個對象,我可以從類型獲取類和...我猜我可以對我正在創建的objectcreator進行遞歸調用,是否有一種簡單的方法來創建該對象的新實例,因爲我覺得這可以進入永無止境的遞歸循環。

回答

1

一般來說,我看不到任何基元問題。雖然你應該考慮,Type是一個非常抽象的聲明,所以它不僅包含具體類,還包括諸如參數變量,參數化類型等類似的東西。我想,記住這些將是有用的,原語是非常具體的類型類),並且它們沒有被明確地構造(因爲它們在代碼中被直接聲明爲在內存中被'按值'處理)。所以我猜,他們的'盒裝'版本將被用來代替。

雖然你應該考慮,那種類型檢查不會被應用,所以你需要手動確保所有輸入都是有效的,並且正確地施放方法結果。

這裏是一個示例代碼,這可能會激發你:

public static void main(String[] args) { 

    Scanner s = new Scanner(System.in); 
    String typeName = s.next(); 

    //ask for type 

    Class<?> type; 

    try { 
     type = Class.forName(typeName); 
    } catch (ClassNotFoundException e) { 
     System.out.printf("Class `%s` was not found%n", typeName); 
     return; 
    } 

    //discover constructors 

    Constructor<?>[] constructors = type.getConstructors(); 

    for (int i = 0; i < constructors.length; ++i) { 
     System.out.printf(" > %d %s%n", i, constructors[i]); 
    } 

    //select constructor and list its parameters 

    int constructorIndex = s.nextInt(); 
    Constructor<?> constructor = constructors[constructorIndex]; 

    Type[] parameterTypes = constructor.getGenericParameterTypes(); 
    for (Type parameterType : parameterTypes) { 
     System.out.println(parameterType); 

     //each type implementation requires a specific processing 

     if (parameterType instanceof Class) { 
      Class parameterClass = (Class) parameterType; 
      if ((parameterClass).isPrimitive()) { 

       //simple int primitive; which can be directly obtained from scanner 

       if (Integer.TYPE.isAssignableFrom(parameterClass)) { 
        System.out.println("\tinteger primitive > "); 
        int value = s.nextInt(); 
        System.out.println("\t you've entered " + value); 
       } 
      } else { 
       Stream.of((parameterClass).getConstructors()).forEach(c -> System.out.printf("\t%s%n", c)); 
       Stream.of((parameterClass).getDeclaredConstructors()).forEach(c -> System.out.printf("\t%s%n", c)); 
      } 
     } 
    } 

    // here we consider a sample java.lang.Integer class was requested with #0 constructor 

    if (Integer.class.isAssignableFrom(type) && constructorIndex == 0) { 

     System.out.println("Input an integer number: "); 

     String value = s.next(); 

     // since newInstance requires array of objects, we need to create an object (not primitive) 

     Object instance; 

     try { 
      instance = constructor.newInstance(Integer.valueOf(value)); 
     } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { 
      e.printStackTrace(); 
      return; 
     } 

     System.out.printf("%s %s%n", instance.getClass(), instance); 
    } 
}