2013-08-07 145 views
17

好吧,這是一個複雜的問題,我完全失去了。Java如何檢查字符串值是否爲給定類的類型<?>

假設你有一個字符串和一個泛型類。喜歡這個。

String string; 
Class<?> clazz; 

如何檢查字符串是否代表該類可能相等的值。

例如讓說:

String string = "true"; 
Class<?> clazz = Boolean.class; 

我將如何檢查,看看是字符串「true」,其實是一個布爾值?

這是另一個例子。可以這樣說:

String string = "true"; 
Class<?> clazz = Integer.class; 

如何檢查並看到字符串「true」不是整數?

+0

你想僅僅爲包裝類型做測試嗎? –

+0

我主要關注原始類型的包裝,是的 –

回答

17

既然你僅需要運用包裝類型,你可以使用一些反射亂砍這裏(異常處理不相關的代碼被忽略這裏爲簡便起見):

String string = "ABC"; 
Class<?> clazz = Integer.class; 

Method method = clazz.getDeclaredMethod("valueOf", String.class); 

if (method != null) { 
    try { 
     Object obj = method.invoke(null, string);  
     System.out.println("Success : " + obj); 

    } catch (InvocationTargetException ex) { 
     System.out.println("Failure : " + string + " is not of type " + 
              clazz.getName()); 
    } 
} 

我考慮到事實上,每個包裝類都有一個靜態的valueOf方法,它採用String類型的參數,並返回該類型的值wrapper。如果參數不能轉換爲相應的包裝類型,則會引發異常。

因此,在上述情況下,如果拋出異常,string值不是clazz類型。

附::請注意,對於Boolean.class,任何非"true"的字符串將被視爲false

0

在JavaScript中你可以eval()字符串。在Java中,你沒有這種方法。你必須實施你自己的啓發式檢查。

然而,你可以做的一件事是嘗試解析給定類的字符串。如:

Iteger.parseInt(stringValue); 

如果解析成功,則字符串可用作該類型的值。如果失敗,那麼你會得到一個異常。執行這些檢查,然後扣除一些結論。

+0

我不能只使用該方法,因爲我不知道該類是否是整數。它是一個通用類型。 –

+0

您的問題沒有單一線路解決方案。這就是爲什麼我說你需要阻止一系列檢查,然後推斷結論。 – allprog

+0

我不期待單線解決方案。我認爲必須有更好的方法來檢查它是否添加了任何基本類型或其他類,然後根據我添加的每個類來檢查它。 –

0

我現在無法測試這個解決方案,但爲什麼不是這樣?如果您可以自己枚舉所有可能的類,只需在該類上創建一些switch語句。

boolean isStringClass (Class clazz, String string) { 

    try { 
     if (Integer.class == clazz) { 
      Integer.valueOf(string); 
     } else if (Boolean.class = clazz) { 
      Boolean.valueOf(string); 
     } [...etc] 
    } catch (Exception e) { 
     return false; 
    } 

    return true; 
} 

當然,你需要知道所有可能的類,你需要知道,屬於這個類是能夠解析字符串,返回其類型的方法。對於原始包裝將是valueOf

如果你打算只轉換包裝,Rohit的解決方案將是一個更好的選擇。但是,如果您沒有這樣做,並且您無法將valueOf方法添加到此新類中,則這可能是您唯一的選擇。

1

我假設你正在實施某種規範/協議或類似的。

  1. 查看規格。
  2. 定義有效輸入的語法
  3. 解析語法。

這與編程語言使用文字所做的相似。

0

我會考慮使用JavaBeans PropertyEditor機制。

@Test 
public void testIsOfType() {   
    assertFalse(test("nope", Integer.class)); 
    assertFalse(test("nope", Boolean.class)); 

    assertTrue(test("1", Integer.class)); 
    assertTrue(test("true", Boolean.class)); 
} 

boolean test(String str, Class<?> clazz) { 
    PropertyEditor propertyEditor = PropertyEditorManager.findEditor(clazz); 
    if (propertyEditor != null) { 
     try {   
      propertyEditor.setAsText(str); 
      return true; 
     } catch (Exception ex) {} 
    } 
    return false; 
} 

這避免了明確反映的需要,如果你決定你需要測試比你能註冊PropertyEditorManager.registerEditor()一個新的編輯器的原始包裝其他類。

不幸的是,這仍然存在Rohit的解決方案存在的問題,即test("1", Number.class)將會失敗。

相關問題