Java如何检查字符串值是否是给定Class 的类型

好吧,这是一个复杂的问题,我完全迷失了。

假设您有一个字符串和一个generics类。 像这样。

String string; Class clazz; 

您将如何检查String是否表示类可以相等的值。

例如,让我们说:

 String string = "true"; Class clazz = Boolean.class; 

我如何检查并看到字符串“true”实际上是一个布尔值?

这是另一个例子。 让我们说:

 String string = "true"; Class clazz = Integer.class; 

我如何检查并看到字符串“true”不是整数?

鉴于你只想在包装类型中使用它,你可以在这里使用一些reflection黑客(为了简洁,这里忽略了对不相关代码的exception处理):

 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类型的值。 如果参数不能转换为相应的包装器类型,则抛出exception。

因此,在上面的情况下,如果抛出exception,则string值不是clazz类型。

PS:请注意,对于Boolean.class ,任何非"true"字符串都将被视为false

我假设你正在实现某种规范/协议或类似的。

  1. 看看Spec。
  2. 定义有效输入的语法
  3. 解析那个语法。

这类似于Programming Languages在文字方面做的事情。

在javascript中你可以eval()字符串。 在Java中,你没有这样的手段。 您必须为此检查实施自己的启发式方法。

但是,您可以做的一件事是尝试使用给定的类解析字符串。 喜欢:

 Iteger.parseInt(stringValue); 

如果解析成功,则该字符串可用作该类型的值。 如果失败,那么你会得到一个例外。 实施这些检查,然后扣除一些结论。

我现在无法测试这个解决方案,但为什么不能这样呢? 如果您可以自己枚举所有可能的类,只需在类上创建一些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; } 

当然,您需要知道所有可能的类,并且您需要知道属于该类的方法,该方法能够解析String并返回其类型。 对于将是valueOf的原始包装器。

如果您打算只转换包装纸,Rohit的解决方案将是更好的选择。 但是,如果您没有这样做并且无法将valueOf方法添加到此新类中,则这可能是您唯一的选择。

我会考虑使用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; } 

这避免了显式reflection的需要,如果您决定需要测试除原始包装之外的类,则可以使用PropertyEditorManager.registerEditor()注册新的编辑器。

不幸的是,这仍然存在Rohit的解决方案存在的问题test("1", Number.class)将失败。