Навчившись протягом моїх днів C ++ про злини оператора лиття в стилі C, я спочатку був радий виявити, що в Java 5 java.lang.Class
придбали cast
метод.
Я подумав, що, нарешті, у нас є спосіб OO, що стосується кастингу.
Виходить Class.cast
не те саме, що static_cast
в C ++. Це більше схоже 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()
слід виганяти на землю Generics? Там він має досить багато законних цілей. - Чи повинні компілятори генерувати помилки компіляції при
Class.cast()
використанні, а незаконні умови можна визначити під час компіляції? - Чи повинна Java надавати оператор литових структур як мовну конструкцію, схожу на C ++?
Class.cast()
коли незаконні умови можуть бути визначені під час компіляції. У цьому випадку всі, окрім вас, просто використовують стандартний оператор кастингу. (3) У Java є оператор передачі як мовна конструкція. Він не схожий на C ++. Це тому, що багато мовних конструкцій Java не схожі на C ++. Незважаючи на поверхневу схожість, Java і C ++ досить різні.