• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Reference Casting Rules (Compile & Run - time)

 
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi. Can anyone please explain to me why code in line4 compiles fine:

I've always thought that the rules for casting are these:
Compile-time: must be within same hierarchy, otherwise, compile-error
Runtime : casting an object down the hierarchy causes ClassCastException.
If so, why does line 4 work? Class A and Interface E are not in the same hierarchy, right? I feel as though there are many areas in Reference Casting that are gray to me... Can somebody please make my understanding of it crystal clear? Thanks.
[ March 28, 2004: Message edited by: nikki lorenzo ]
 
Ranch Hand
Posts: 225
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Considering line number 4,
E e=(E)a;
Inspecting different variables,
1>a--A a=new D();
It has a reference of A and a run-time object of type D
2>e--E e=(E)a;
It has a reference of E AND A run-time object of type [b]D[/
b] because that is the run-time object of a.
Also, D is a subclass of B and B implements E, therefore line number 4 compiles without error.
Thats how I try and figure out reference type questions.I am not sure whether thats the right way to go about it.
 
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Always keep in mind that you can use a child object anywhere a parent object is expected. Therefore, if you have a variable of type A, that variable can reference an object of type A or any type that is a descendent of A - that includes B, C, and D. Now, notice that B implements the interface E. That means that the variable of type A can reference an object that implements E. Because of that, we have no compiler error.
Because the variable 'a' references a D object, we can safely cast it to E at run-time. That's because D extends B (D "is a" B) and B implements E(B "is a" E). Therefore, the run-time cast is successful, as well.
I hope that helps,
Corey
 
nikki lorenzo
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thanks corey, but i still don't get it...


That means that the variable of type A can reference an object that implements E.


though i agree with your statement above if i interpret it this way:

but what i'm really confused at is this code:

does this work 'coz the object type of reference a is actually a D, and D Is-A E?
if so, should i change my style of looking ONLY at the reference types when spotting for a possible compile-time errors related to casting? 'coz when i look merely at the reference types without regard to the actual object, a of type A then it will seem wrong as A Is-Not-A E.
thanks.
[ March 29, 2004: Message edited by: nikki lorenzo ]
 
Ranch Hand
Posts: 5093
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your object instance a is of type D.
D itself is really a B with some added features.
B is itself an E therefore D is also an E.
You can therefore reference a as if it were an E, which means the cast is valid.
It might become clearer if you change the names around to not be all the same:


class Thing{};
class SomeThingie extends Thing implements Some{};//line 1class C class AnotherThing extends Thing{};
class SomeThingOrOther extends SomeThingie{};
interface Some{};
class Question07 {
public static void main(String[] args) {
Thing a = new SomeThingOrOther();//line 2
AnotherThing c = new AnotherThing();//line 3
Some e = (Some)a;//line 4
SomeThingie b = (SomeThingie)e;//line 5
}}

 
Ranch Hand
Posts: 443
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by nikki lorenzo:

If so, why does line 4 work? Class A and Interface E are not in the same hierarchy, right?


Simply put it, because E is an interface.
From JLS pp. 73


If T is an interface type:
- If S is not a final class (�8.1.1), then the cast is always correct at compile time (because even if S does not implement T, a subclass of S might).


To understand this, consider the following code.

The compiler could not flag line 1 as an error because the caller of m() might pass a subclass of A that implements E. For example, the following call to m() is valid:

So even though A is not on the same hierarchy as E, it's subclass might.
 
I will open the floodgates of his own worst nightmare! All in a tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic