หลังจากได้รับการสอนในช่วงวัน C ++ ของฉันเกี่ยวกับความชั่วร้ายของตัวดำเนินการแบบ C-style ฉันรู้สึกยินดีในตอนแรกที่พบว่าใน 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 ควรจัดเตรียมตัวดำเนินการ cast เป็นภาษาที่สร้างคล้ายกับ C ++ หรือไม่
Class.cast()
เมื่อเงื่อนไขที่ผิดกฎหมายสามารถกำหนดเวลาที่รวบรวม ในกรณีนี้ทุกคน แต่คุณใช้แค่ตัวดำเนินการหล่อมาตรฐาน (3) Java มีตัวดำเนินการ cast เป็นโครงสร้างภาษา มันไม่คล้ายกับ C ++ นั่นเป็นเพราะโครงสร้างภาษาของ Java จำนวนมากไม่คล้ายกับ C ++ แม้จะมีความคล้ายคลึงกันเพียงผิวเผิน Java และ C ++ ก็แตกต่างกันมาก