But then I encountered this question:
(WGS-PREX-J055-Form2: Sun Certified Programmer for the Java 2 Platform, Standard Edition 5.0, question 44)
Given:
1. class Alpha { void m1() {} }
2. class Beta extends Alpha { void m2() { } }
3. class Gamma extends Beta { }
4.
5. class GreekTest {
6. public static void main(String [] args) {
7. Alpha [] a = {new Alpha(), new Beta(), new Gamma() };
8. for(Alpha a2 : a) {
9. a2.m1();
10. if (a2 instanceof Beta || a2 instanceof Gamma)
11. // insert code here
12. }
13. }
14. }
Which code, inserted at line 11, will compile but cause an exception to be thrown at runtime?
| |||
| |||
| |||
|
I picked option D, and here is my reasoning:
Both objects of type Beta and Gamma will pass the if test (the Alpha object will not), but in option D we are casting to a Gamma. We can legally cast a Gamma object to a Beta (A Gamma is-a Beta), but the revers is not true; not every Beta is-a Gamma. So though this code will compile (Gamma has a method m2() we can call), it will fail at runtime, throwing ClassCastException when we encounter the second, Beta object in the array.
Here is the official explanation (that you get when pressing the 'Reference' button):
Option D is correct. Options A and C will NOT compile, option B will compile and run. Option D throws an exception because type Alpha has no m2 method.
Look at the last sentence:
Option D throws an exception because type Alpha has no m2 method
I think this is incorrect? I think the last sentence should read:
Option D throws an exception because type Beta cannot be casted to type Gamma.
Why would it matter that Alpha has no m2 method? No objects of type Alpha can get past the if check:
if (a2 instanceof Beta || a2 instanceof Gamma)
So no Alpha object will ever be cast to Gamma or invoked the m2 method on?
Who is right here, me or Sun?
Anyone care to comment?