MyObject myObject = MyObject.class.cast(object)
编辑:编译时的错误
总而言之,Java仅在运行时执行转换检查。 但是,编译器可以发出错误,如果它可以证明这样的强制转换永远不会成功(例如,将一个类强制转换为另一个不是超类型的类,并将最终类类型转换为类/接口而不是 在其类型层次结构中)。 这里,因为Foo和Bar是不在每个其他层次结构中的类,所以演员表永远不会成功。
尝试翻译语言之间的结构和概念总是存在问题并且经常会产生误导。 铸造也不例外。 特别是因为Java是一种动态语言而且C ++有些不同。
无论如何操作,所有Java中的转换都是在运行时完成的。 类型信息在运行时保存。 C ++有点混合。 您可以将C ++中的结构转换为另一个结构,它只是对表示这些结构的字节的重新解释。 Java不会那样工作。
Java和C ++中的泛型也是截然不同的。 不要过分关注你如何用Java做C ++事情。 您需要学习如何以Java方式执行操作。
Class.cast()在Java代码中很少使用。 如果使用它,那么通常使用仅在运行时已知的类型(即通过它们各自的dynamic_cast<>()对象和某些类型参数)。 它只对使用泛型的代码非常有用(这也是之前没有介绍过的原因)。
它与dynamic_cast<>()不相似,因为它不允许你在运行时打破类型系统,而不是正常的转换(即你可以&#34;打破&#34;泛型类型参数,但可以&#39; t& #34;打破&#34;&#34;真实&#34;类型)。
C风格演员的弊端通常不适用于Java。 看起来像C样式转换的Java代码最类似于带有Java引用类型的dynamic_cast<>()(请记住:Java具有运行时类型信息)。
通常将C ++强制转换操作符与Java转换进行比较非常困难,因为在Java中,您只能转换引用,并且对象不会发生任何转换(只能使用此语法转换原始值)。
除了最常提到的删除丑陋的强制转换警告之外,Class.cast是运行时强制转换,主要用于通用转换,因为通用信息将在运行时被删除,而某些通用将如何被视为对象,这导致不会 抛出早期的ClassCastException。
例如,serviceLoder在创建对象时使用此技巧,检查S p = service.cast(c.newInstance()); 这将抛出一个类强制转换异常当S P =(S)c.newInstance(); 赢了,并且可能会显示警告&#39;类型安全:未选中从对象转换为S&#39;。(与对象P =(对象)相同c.newInstance();)
- 只是它检查铸造对象是否为铸造类的实例,然后它将使用强制转换操作符通过抑制它来强制转换和隐藏警告。
动态强制转换的java实现:
@SuppressWarnings("unchecked")
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException(cannotCastMsg(obj));
return (T) obj;
就个人而言,我之前使用过它来构建一个JSON到POJO转换器。 在使用函数处理的JSONObject包含数组或嵌套的JSONObjects(暗示此处的数据不是基本类型或class.cast())的情况下,我尝试以这种方式使用class.cast()调用setter方法:
public static Object convertResponse(Class> clazz, JSONObject readResultObject) {
for(Method m : clazz.getMethods()) {
if(!m.isAnnotationPresent(convertResultIgnore.class) &&
m.getName().toLowerCase().startsWith("set")) {
m.invoke(returnObject, m.getParameters()[0].getClass().cast(convertResponse(m.getParameters()[0].getType(), readResultObject.getJSONObject(key))));
不确定这是否非常有用,但如前所述,反射是我能想到的极少数合法用例class.cast()之一,至少你现在有另一个例子。