好吧,这是一个复杂的问题,我完全迷失了。
假设您有一个字符串和一个泛型类。像这样。
String string;
Class<?> clazz;
您如何检查String是否表示该类可以相等的值。
例如,让我们说:
String string = "true";
Class<?> clazz = Boolean.class;
我如何检查并看到字符串“true”实际上是一个布尔值?
这是另一个例子。让我们说:
String string = "true";
Class<?> clazz = Integer.class;
我如何检查字符串“true”不是整数?
答案 0 :(得分: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
类型。
P.S。:请注意,对于Boolean.class
,任何非"true"
的字符串都将被视为false
。
答案 1 :(得分:1)
我假设你正在实施某种规范/协议或类似的。
这类似于Programming Languages在文字方面做的事情。
答案 2 :(得分:0)
在javascript中你可以eval()字符串。在Java中,你没有这样的手段。您必须为此检查实施自己的启发式方法。
然而,您可以做的一件事是尝试使用给定的类解析字符串。像:
Iteger.parseInt(stringValue);
如果解析成功,则该字符串可用作该类型的值。如果失败,那么你会得到一个例外。实施这些检查,然后扣除一些结论。
答案 3 :(得分: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;
}
当然,您需要知道所有可能的类,并且您需要知道属于该类的方法,该方法能够解析String并返回其类型。对于原始包装器valueOf
。
如果您打算只转换包装纸,Rohit的解决方案将是更好的选择。但是,如果您没有这样做并且无法向此新类添加valueOf
方法,则可能是您唯一的选择。
答案 4 :(得分: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)
将失败。