【发布时间】:2009-10-12 15:47:47
【问题描述】:
在我的 C++ 时代,我被教导 C 风格强制转换运算符的弊端,起初我很高兴地发现在 Java 5 中 java.lang.Class 获得了 cast 方法。
我认为我们终于有了一种面向对象的方式来处理强制转换。
原来Class.cast 与 C++ 中的static_cast 不同。它更像reinterpret_cast。它不会在预期的地方产生编译错误,而是会推迟到运行时。这是一个简单的测试用例来演示不同的行为。
package test;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class TestCast
{
static final class Foo
{
}
static class Bar
{
}
static final class BarSubclass
extends Bar
{
}
@Test
public void test ( )
{
final Foo foo = new Foo( );
final Bar bar = new Bar( );
final BarSubclass bar_subclass = new BarSubclass( );
{
final Bar bar_ref = bar;
}
{
// Compilation error
final Bar bar_ref = foo;
}
{
// Compilation error
final Bar bar_ref = (Bar) foo;
}
try
{
// !!! Compiles fine, runtime exception
Bar.class.cast( foo );
}
catch ( final ClassCastException ex )
{
assertTrue( true );
}
{
final Bar bar_ref = bar_subclass;
}
try
{
// Compiles fine, runtime exception, equivalent of C++ dynamic_cast
final BarSubclass bar_subclass_ref = (BarSubclass) bar;
}
catch ( final ClassCastException ex )
{
assertTrue( true );
}
}
}
所以,这些是我的问题。
- 应该将
Class.cast()放逐到泛型领域吗?它有很多合法用途。 - 当使用
Class.cast()并且可以在编译时确定非法条件时,编译器是否应该产生编译错误? - Java 是否应该将强制转换运算符作为类似于 C++ 的语言结构提供?
【问题讨论】:
-
简单回答:(1)“泛型之地”在哪里?这与现在使用 cast 运算符有什么不同? (2) 大概。但在 99% 的所有 Java 代码中,如果在编译时可以确定非法条件,那么任何人极不可能使用
Class.cast()。在这种情况下,除了您之外的每个人都只使用标准转换运算符。 (3) Java 确实有一个强制转换运算符作为语言结构。它与 C++ 不同。这是因为 Java 的许多语言结构与 C++ 不同。尽管有表面上的相似之处,Java 和 C++ 却大不相同。 -
本教程优雅地解释了泛型中 cast() 方法的必要性:baeldung.com/java-type-casting
标签: java generics casting compiler-warnings