2010-11-13 112 views
1

我想找到一種方法來動態檢查字符串是否可以解析爲給定類型。 換句話說,反射式檢查?

public boolean canBeParsed(String type, String val) { 
    // use reflect to check if val can be parsed into type 
} 

清楚,我想能夠檢查不同類型有着不同的價值觀..

類型就會像字符串:java.lang.Integer中

- --------除了-------------

因此,舉例來說,如果我調用該函數,

canBeParsed("Java.lang.Integer", "1"); //returns true 

canBeParsed("Java.lang.Integer", "HelloWorld"); //returns false 

canBeParsed("Java.lang.String", "HelloWorld"); //returns true 

canBeParsed("Java.lang.Boolean", "false"); // returns true 

canBeParsed("Java.lang.Boolean", "HelloWorld"); //returns false 
+0

你能舉一個更好的例子嗎?目前還不清楚你在問什麼。 – skaffman 2010-11-13 19:07:42

+0

正在做作業嗎?如果是這樣,請標記爲這樣。 – 2010-11-13 19:08:18

回答

1

此方法適用於聲明靜態valueOf方法的類。沒有這個的任何類將返回false。爲了保持代碼簡潔,省略了一些例外。

Class<?> cls = Class.forName(type); 
//Get a converter method, String to type 
//Requires static method valueOf 
Method converter; 
try{ 
converter = cls.getDeclaredMethod("valueOf",new Class[]{String.class}); 
}catch(NoSuchMethodError ex){ 
    //No conversion method found 
    return false; 
} 
if(!Modifier.isStatic(converter.getModifiers()){ 
    //the method has to be static in order to be called by us 
    return false; 
} 
if(!cls.isAssignableFrom(converter.getReturnType()) 
    //The conversion method has the wrong return type 
    return false; 
try{ 
    //try to parse the value 
    Object o = converter.invoke(null,new Object[]{value}; 
    if(o == null)return false;//false if method returned null 
    else return true;//success 
}catch(Exception ex) 
{ 
    //could not parse value 
    return false; 
} 

的的valueOf(String)方法存在於包裝類短,長,整數,浮點,雙精度,布爾所以它支持這些和具有這種方法的任何其他類。

+0

謝謝!效果很好。當然,不得不提出明顯的例子:「if(type.equals(」java.lang.String「))return true;」對於可能會發現此代碼有用的人 – 2010-11-13 21:22:34

1

動態類型檢查與您要求的不同。通過動態檢查,您可以檢查對象是否爲特定類型的實例(基本上允許使用同一類型或更窄的類型),您可以使用instanceof運算符來執行此操作。但是這涉及到對象層次結構,而不是「你可能會轉換成」的概念,你想擁有。您可以嘗試使用string instanceof Integer,但這將始終是錯誤的。

在你的情況,你要檢查,如果字符串rapresents一個整數,你應該做它用不同的方式:

try { 
    int number = Integer.parseInt(string); 
} 
catch (NumberFormatException e) { 
    System.out.println("String is not an integer string!"); 
} 

否則,你可以定義一個正則表達式爲每個類型和檢查什麼字符串包含通過它:

if (string.matches("[1-9][0-9]*")) 
    ... 

在anycase,因爲String只是一個字符串類型,不出意外,RTTI不會幫助你在這裏。字符串本身與其他類型(int,float,whatever)正交,如果它表示另一種類型的文本版本。

一個解決方案,可以發現,如果你可以修改源字符串類型,在這種情況下,你可以定義例如

class IntString extends String { 
    IntString(int i) { 
    super(Integer.toString(i)); 
    } 
} 

,那麼你可以檢查是否string instanceof IntString但這隻有在字符串建工作與他們的具體類型,例如String s = new IntString(20)

+0

應該是'整數。parseInt()'(靜態方法)。 – 2010-11-13 19:12:20

+0

我想要的功能不僅限於整數解析,還有許多其他類型。換句話說,作爲參數,我可能有Java.lang.String,Java.lang.Integer,Java.lang.Float,Java.lang.Boolean等 – 2010-11-13 20:10:52

0

您最簡單的解決方案可能是switch聲明,其中一個case適用於您想要支持的每種類型。

public boolean canBeParsed(String type, String val) 
{ 
    switch(type) { 
     case "Java.lang.Integer" : return(tryParseInteger(val) != null); 
     case ... 
} 


public static Integer tryParseInteger(String text) { 
    try { 
    return new Integer(text); 
    } catch (NumberFormatException e) { 
    return null; 
    } 
} 

在C#,這將是更容易,因爲存在用於每個數字類型的實際的TryParse()方法,這是沒有必要捕捉異常進行測試。

+1

這隻適用於Java SE7(切換字符串) 。 – helpermethod 2010-11-13 19:32:07

+0

對於類型枚舉使用開關,這將在JDK6中起作用。 – TheWolf 2010-11-13 19:46:40