2013-08-07 110 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)将会失败。

相关问题