เทคนิคการโยนสามารถทำได้ ไม่สามารถพิสูจน์ได้อย่างง่ายดายโดย javac ว่าไม่ใช่ในกรณีของคุณและ JLS กำหนดว่านี่เป็นโปรแกรม Java ที่ถูกต้องดังนั้นการตั้งค่าสถานะข้อผิดพลาดจะไม่ถูกต้อง
นี่เป็นเพราะListเป็นอินเทอร์เฟซ ดังนั้นคุณอาจมีคลาสย่อยของDateที่ใช้จริงListปลอมตัวเป็นListที่นี่ - แล้วหล่อมันDateจะตกลงอย่างสมบูรณ์ ตัวอย่างเช่น:
public class SneakyListDate extends Date implements List<Foo> {
...
}
แล้ว:
List<Foo> list = new SneakyListDate();
Date date = (Date) list; // This one is valid, compiles and runs just fine
การตรวจจับสถานการณ์ดังกล่าวอาจไม่สามารถทำได้เสมอไปเนื่องจากต้องใช้ข้อมูลรันไทม์หากอินสแตนซ์นั้นมาจากตัวอย่างเช่นเมธอดแทน และถึงแม้ว่ามันจะต้องใช้ความพยายามมากขึ้นสำหรับคอมไพเลอร์ คอมไพเลอร์ป้องกันการปลดเปลื้องที่เป็นไปไม่ได้อย่างแน่นอนเนื่องจากไม่มีวิธีใดที่ทรีคลาสจะจับคู่ได้เลย ซึ่งไม่ใช่กรณีที่นี่ตามที่เห็น
โปรดทราบว่า JLS ต้องการให้รหัสของคุณเป็นโปรแกรม Java ที่ถูกต้อง ใน5.1.6.1 การแปลงอ้างอิงที่อนุญาตให้แคบลงนั้นระบุว่า:
การแปลงอ้างอิงกวดขันอยู่จากชนิดอ้างอิงSกับประเภทอ้างอิงTถ้าทั้งหมดต่อไปนี้เป็นจริง :
- [ ... ]
- กรณีใดกรณีหนึ่งต่อไปนี้ :
- [ ... ]
Sเป็นประเภทอินเตอร์เฟสTเป็นประเภทคลาสและTไม่ตั้งชื่อfinalคลาส
ดังนั้นแม้ว่าคอมไพเลอร์สามารถเข้าใจว่ากรณีของคุณเป็นไปไม่ได้จริง ๆ แล้วมันไม่ได้รับอนุญาตให้ตั้งค่าสถานะข้อผิดพลาดเพราะ JLS กำหนดว่าเป็นโปรแกรม Java ที่ถูกต้อง
มันจะได้รับอนุญาตเท่านั้นที่จะแสดงคำเตือน
Listที่นี่Date d = (Date) new Object();