2011-08-24 19 views
1

我有一個類類型,我有一個字符串值:一個字符串值轉換到一個未知的(在編譯時)對象類型

Class<?> type = Integer.class // <-- in reality, that type is 
           // determined at runtime 
String value = "3";   // <-- same here, actually read from a file 

我的目標就是實例「類型」的一個實例,與「價值」的價值填充它。所以,我有

Integer i = new Integer(value); 

相當於是唯一可能的方式做到這一點很長的鏈if語句:

if (type == Integer.class) { 
    // do this 
} 

還是有另一種聰明/正確的方法來做到這一點?可能的類類型也能像整數/日期等完全不同的......

EDIT1

這裏是一些更多的上下文:

我有一個數值的文件,該文件的文本表示不同數據類型的實例:

1|3.4|2011-08-24 

在我的計劃,我得到一個類的類型,並在該類這兩者都是在編譯時未知的我的方法。

我想在該類型的實例上調用該方法,並將文件中的值作爲參數。但爲此,我必須有相應的對象,該值可以是Integer/int,float/double和Date。 我可以通過反射得到這些數據類型的方法的形式參數,但我不知道最好的方式來進行從字符串到對象的轉換...

也許這個僞程序將清除事情了:

String[] values = getValuesFromFile; 
Class<?> type = getType(); 
Method method = getMethod(); 
Class<?>[] formalParameterTypes = getMethodParameterTypes(); 
Object[] objects; 
for(int i; i < values.length; i++) 
    objects[i] = convert(values[i],formalParameterTypes[i]); 
method.invoke(objects); 
+0

請出示各地使用更多的上下文。 – Bohemian

回答

1

據我瞭解,你想是這樣的:

Object instance = createMagically(getClass(), getString()); 

其中getClass()可能返回Integer.classgetString()"42"。但預計價值對Date.class"15 Apr 2011"也是如此。

在某一時刻,您必須使用條件(if/else if),因爲一般而言,每種類型都有自己的轉換規則。沒有通用構造函數來從String創建實例。

所以你可以實現這樣的「工廠」的方法:

public static Object createInstance(Class<?> type, String content) { 
    if (type.equals(Integer.class)) return new Integer(content); 
    else if // ... 
    return content; // just an idea for a default if the type can't be handled 
} 

再然後,到使用返回值,你可能需要一些更多的if/else,如果確定實際(if (value instancof Integer) ...)

所以,從我的角度來看 - 你做了很多檢查,但是你可以在實用類中隱藏醜陋的魔法。

+0

是的,這就是我想要做到的方式......我只是覺得可能有一種我不知道的更好的方式...... – dertoni

1

發明了動態類加載和反射來解決這些問題。例如。

Class<?> type = Class.forName("MyClassName"); 
Object obj = type.newInstance(); 

現在,如果你想在對象中設置字段,你有兩個選擇:

  • 如果潛在的類共享一個共同的基類/接口,可以把對象到該接口並通過接口方法對其進行處理,如果潛在類不通過繼承關聯但具有相同的方法/字段,則可以通過bean introspection設置字段值,或者可以使用反射來調用該方法。
+0

如果你嘗試'Integer.class.newInstance()'會發生什麼? – jarnbjo

+0

@jarnbjo,當然你會得到一個例外。以上是一個指向正確方向的例子,而不是生產代碼。 –

+0

@jarnbjo - 這將要求該類在編譯時已知。但實際上並非如此。 –

1

如果您的類型僅限於原始數據類型的包裝類,則所有類都有一個靜態的valueOf(String)方法,該方法可用於解析String並返回有效的實例。

我會用反射來查找和調用的方法和使用結果:

public static void main(String[] args) throws Exception { 
    int i = parse(Integer.class, "4711"); 
    double d = parse(Double.class, "47.11"); 
    boolean b = parse(Boolean.class, "true"); 
    System.out.println(i); 
    System.out.println(d); 
    System.out.println(b); 
} 

public static <T> T parse(Class<T> type, String value) { 
    try { 
     return (T)type.getDeclaredMethod("valueOf", String.class).invoke(null, value); 
    } 
    catch(Exception e) { 
     throw new RuntimeException(e); 
    } 
} 
+1

該類型不限於包裝,他已經提到了'Date'。 –

0

使用JSON可以轉換成字符串在運行時爲對象,不知道在開始的原始類型。

0

如果值只有字符串表示,你可以這樣做:

String typeName = ... 
String value = ... 
Class<?> type = Class.forName(typeName); 
Constructor<?> constructor = type.getConstructor(String.class); 
Object instance = constructor.newInstance(value); 
// cast the instance to actual class 
相關問題