Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > why not compile error on "incompatible interface cast"?

Reply
Thread Tools

why not compile error on "incompatible interface cast"?

 
 
gg9h0st
Guest
Posts: n/a
 
      07-26-2008
simeple code here

-----------------------------------------------------------
class IncompInterfaceTest {
void doTest() {
ClassB b = new ClassB();
InterfaceA a = (InterfaceA)b;
}
}

interface InterfaceA{}
class ClassB{}
-----------------------------------------------------------

javac issues "ClassCastException" on runtime rather than compile
error.

as i know incompatible type casting may be caught at runtime and
compiler shows the error.

but why compiler doesn't do it's job for interfaces? it's just so
clear to be compile error to me.
 
Reply With Quote
 
 
 
 
Patricia Shanahan
Guest
Posts: n/a
 
      07-26-2008
gg9h0st wrote:
> simeple code here
>
> -----------------------------------------------------------
> class IncompInterfaceTest {
> void doTest() {
> ClassB b = new ClassB();
> InterfaceA a = (InterfaceA)b;
> }
> }
>
> interface InterfaceA{}
> class ClassB{}
> -----------------------------------------------------------
>
> javac issues "ClassCastException" on runtime rather than compile
> error.
>
> as i know incompatible type casting may be caught at runtime and
> compiler shows the error.
>
> but why compiler doesn't do it's job for interfaces? it's just so
> clear to be compile error to me.


In theory, the compiler could apply flow analysis in your test case to
conclude that b references the new ClassB() result at the point of the
cast.

Without flow analysis, the compiler only knows that you are casting a
ClassB reference to InterfaceA. Its value might be a pointer to a ClassC
object, where extends ClassB and implements InterfaceA

In general, given a non-final class and an interface, the compiler has
to allow for the possibility that the class has a subclass that
implements the interface.

Patricia
 
Reply With Quote
 
 
 
 
gg9h0st
Guest
Posts: n/a
 
      07-26-2008
> In theory, the compiler could apply flow analysis in your test case to
> conclude that b references the new ClassB() result at the point of the
> cast.
>
> Without flow analysis, the compiler only knows that you are casting a
> ClassB reference to InterfaceA. Its value might be a pointer to a ClassC
> object, where extends ClassB and implements InterfaceA
>
> In general, given a non-final class and an interface, the compiler has
> to allow for the possibility that the class has a subclass that
> implements the interface.
>
> Patricia


I think I saw you a year ago here too lol

by the way :S I modified this reply so many time while I'm
understanding what you told. still unclear ^^;

so it is about implementing interface is not like extending a class.
right?

I may need abit time more to think right now.

thanks patricia
 
Reply With Quote
 
gg9h0st
Guest
Posts: n/a
 
      07-26-2008
> In theory, the compiler could apply flow analysis in your test case to
> conclude that b references the new ClassB() result at the point of the
> cast.
>
> Without flow analysis, the compiler only knows that you are casting a
> ClassB reference to InterfaceA. Its value might be a pointer to a ClassC
> object, where extends ClassB and implements InterfaceA
>
> In general, given a non-final class and an interface, the compiler has
> to allow for the possibility that the class has a subclass that
> implements the interface.
>
> Patricia


Another Qeustion along this.

Doesn't "cast operator" know it's actuall object?

em... cast operator test it's operand as a refernce variable, not far
to the object in compile stage.

and extending a class should be clear to test whle implementing a
interface is not.

is that right?

 
Reply With Quote
 
Joshua Cranmer
Guest
Posts: n/a
 
      07-26-2008
gg9h0st wrote:
> Doesn't "cast operator" know it's actuall object?
>
> em... cast operator test it's operand as a refernce variable, not far
> to the object in compile stage.
>
> and extending a class should be clear to test whle implementing a
> interface is not.
>
> is that right?
>


I don't totally understand what you're trying to say, but I'll take a
gander.

In principle, there is sufficient information at compile time to be
determine that the cast will fail. Such analysis, though, is impractical
or even impossible in all cases. I am not certain, but I believe that if
ClassB were final, the cast would be a compiler error.

A compiler sees the statement as "cast reference of type T1 to a
reference of type T2"; it would need additional information to be stored
to be able to prove that the object cannot, in fact, be type T2. Tools
which perform such analysis do exist, and fall under the heading of
"static analysis," which retains more information about statements in
order to detect which ones could be or are problematic. FindBugs is a
classic example of such a tool for Java.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
 
Reply With Quote
 
gg9h0st
Guest
Posts: n/a
 
      07-27-2008
On 7월27일, 오전9시03분, Lew <com.lewscanon@lew> wrote:
> gg9h0st wrote:
> >> class IncompInterfaceTest {
> >> void doTest() {
> >> ClassB b = new ClassB();
> >> InterfaceA a = (InterfaceA)b;
> >> }
> >> }

>
> >> interface InterfaceA{}
> >> class ClassB{}
> >> javac issues "ClassCastException" on runtime rather than compile
> >> error.

>
> >> as i [sic] know incompatible type casting may be caught at runtime and
> >> compiler shows the error.

> Patricia Shanahan wrote:
> > In general, given a non-final class and an interface, the compiler has
> > to allow for the possibility that the class has a subclass that
> > implements the interface.

>
> From the JLS section 5.5:
>
> > The detailed rules for compile-time legality of a casting conversion of a
> > value of compile-time reference type S to a compile-time reference type T
> > are as follows:

> ...
> > If S is a class type:

> ...
> > * If T is an interface type:
> > o If S is not a final class (§8.1.1), then, if there exists a supertype X of
> > T, and a supertype Y of S, such that both X and Y are provably distinct
> > parameterized types, and that the erasures of X and Y are the same, a
> > compile-time error occurs. Otherwise, the cast is always legal at compile time
> > (because even if S does not implement T, a subclass of S might).

>
> Take S as ClassB and T as InterfaceA.
>
> --
> Lew


ooooooooowwwww~~ I still don't get it :S
that "a subclass of S might" part.

so compiler doesn't know what variable 'b' hold? that is oviously
ClassB.

if where ClassC extends ClassB implements InterfaceA

b = new ClassC();
means b hold ClassC object in a ClassB variable.
It CAN BE ClassB, It IS NOT ClassB.
 
Reply With Quote
 
gg9h0st
Guest
Posts: n/a
 
      07-27-2008
On 7월27일, 오후12시17분, "Peter Duniho" <(E-Mail Removed)>
wrote:
> On Sat, 26 Jul 2008 20:07:55 -0700, gg9h0st <(E-Mail Removed)> wrote:
> > ooooooooowwwww~~ I still don't get it :S
> > that "a subclass of S might" part.

>
> > so compiler doesn't know what variable 'b' hold? that is oviously
> > ClassB.

>
> There are things that are obvious to a human reader that are not obvious
> to the compiler.
>
> The case you're talking about is a degenerate case, but there are similar
> situations in which analysis of the execution of the code _could_ prove
> that the cast would succeed or fail, but such analysis would be _much_
> more complicated than simply looking at the initialization of the variable.
>
> For a variety of reasons, but I think mainly just to keep things
> consistent (consistent, predictable compiler behavior is always a nice
> thing ), the compiler is simply going to assume that all such casts are
> valid. It's not feasible to verify them in all cases, and so rather than
> provide inconsistent behavior, the compiler doesn't bother to verify them
> in any case. It's up to you, the author of the code, to not perform casts
> that will fail.
>
> Basically: pretend you're a compiler. Look at _just_ the statement being
> compiled. Based solely on that statement and _statically_ known things
> (e.g. the types of the identifiers in the statement), can you prove that
> the cast is valid or invalid?
>
> The answer to that question is "no". And that's exactly why the compiler
> can't prove it either.
>
> Pete


yea T_T

I spend so much time to digging it.

what you explained me makes me somehow easy. need to sleep lol

I just found that doesn't make an error while casting class on an
incompatible hierarchy makes an error.
and wanted to know.
( ClassB extends ClassA, ClassD extends ClassC,
casting ClassD to ClassB issues an error.
while ClassB implements InterfaceA, ClassD implements InterfaceD,
casting ClassD to ClassB doesn't.)

I better leave it to "compiler does like this" and move to the other
studies as a newbie.

thanks
 
Reply With Quote
 
Daniel Pitts
Guest
Posts: n/a
 
      07-27-2008
gg9h0st wrote:
> On 7월27일, 오후12시17분, "Peter Duniho" <(E-Mail Removed)>
> wrote:
>> On Sat, 26 Jul 2008 20:07:55 -0700, gg9h0st <(E-Mail Removed)> wrote:
>>> ooooooooowwwww~~ I still don't get it :S
>>> that "a subclass of S might" part.
>>> so compiler doesn't know what variable 'b' hold? that is oviously
>>> ClassB.

>> There are things that are obvious to a human reader that are not obvious
>> to the compiler.
>>
>> The case you're talking about is a degenerate case, but there are similar
>> situations in which analysis of the execution of the code _could_ prove
>> that the cast would succeed or fail, but such analysis would be _much_
>> more complicated than simply looking at the initialization of the variable.
>>
>> For a variety of reasons, but I think mainly just to keep things
>> consistent (consistent, predictable compiler behavior is always a nice
>> thing ), the compiler is simply going to assume that all such casts are
>> valid. It's not feasible to verify them in all cases, and so rather than
>> provide inconsistent behavior, the compiler doesn't bother to verify them
>> in any case. It's up to you, the author of the code, to not perform casts
>> that will fail.
>>
>> Basically: pretend you're a compiler. Look at _just_ the statement being
>> compiled. Based solely on that statement and _statically_ known things
>> (e.g. the types of the identifiers in the statement), can you prove that
>> the cast is valid or invalid?
>>
>> The answer to that question is "no". And that's exactly why the compiler
>> can't prove it either.
>>
>> Pete

>
> yea T_T
>
> I spend so much time to digging it.
>
> what you explained me makes me somehow easy. need to sleep lol
>
> I just found that doesn't make an error while casting class on an
> incompatible hierarchy makes an error.
> and wanted to know.
> ( ClassB extends ClassA, ClassD extends ClassC,
> casting ClassD to ClassB issues an error.
> while ClassB implements InterfaceA, ClassD implements InterfaceD,
> casting ClassD to ClassB doesn't.)
>
> I better leave it to "compiler does like this" and move to the other
> studies as a newbie.
>
> thanks

The real reason is that the compiler can easily prove that two classes
are not castable to each-other, but interfaces are trickier, because any
Object might be implementing an interface.

In your example, ClassD to ClassC actually would cause compiler error,
where ClassD to InterfaceA would not. The compiler can not disprove the
existance of ClassE extends ClassD implement InterfaceA. ClassE might
not have been written yet, but it might be available at run-time, and
the cast need not know about it at compile time to succeed.

--
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to compile the following source code in VC6// I have error inVC++6 but compile ok in GCC fAnSKyer C++ 2 06-07-2009 07:57 AM
Why oh why does this NOT give a compile error? Paul Melis C Programming 13 11-07-2007 12:06 AM
cant compile on linux system.cant compile on cant compile onlinux system. Nagaraj C++ 1 03-01-2007 11:18 AM
why why why why why Mr. SweatyFinger ASP .Net 4 12-21-2006 01:15 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM



Advertisments