19

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

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

String string;
Class<?> clazz;

您将如何检查字符串是否表示该类可以相等的值。

例如让我们说:

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

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

这是另一个例子。可以这么说:

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

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

4

5 回答 5

19

鉴于您只希望Wrapper Types使用此功能,您可以在此处使用一些反射技巧(为简洁起见,此处忽略无关代码的异常处理):

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类型。

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

于 2013-08-07T08:13:30.873 回答
1

我假设您正在实施某种规范/协议或类似的东西。

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

这类似于编程语言对文字所做的事情。

于 2013-08-07T08:16:37.620 回答
0

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

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

Iteger.parseInt(stringValue);

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

于 2013-08-07T07:59:30.290 回答
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这个新类添加方法,那么这可能是您唯一的选择。

于 2013-08-07T08:10:05.107 回答
0

我会考虑PropertyEditor为此使用 JavaBeans 机制。

@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)会失败的问题。

于 2013-08-07T09:37:15.687 回答