• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Question #1 from Doug's book

 
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Will this code compile? If it does, what happens when it runs?

[ August 07, 2003: Message edited by: Thomas Paul ]
 
Ranch Hand
Posts: 270
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Thomas Paul:
Will this code compile? If it does, what happens when it runs?

[ August 07, 2003: Message edited by: Thomas Paul ]


compiles but runtime exceptions
The code compiles because Test.s maybe actually refers to an object of Superclass's subclass which implements the Printable interface ...... that's why p = (Printable) Test.s; is legal. But actually the code here is not the case as supposed, that's why runtime error arises.
is this the case?
 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
But if we change the Printable interface to Printable class ..then compile time error of inconvertible types occurs ..
class Test {
static Superclass s = new Superclass();
static Printable p;
public static void main(String[] args) {
p = (Printable) s;
}
}
class Superclass { }
class Printable {
void print() {};
}
So does this mean that Type casting in case of interfaces are checked at run time ..and in case of class , Type casting is checked at compile-time..
 
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The compiler objects or suggests to casting when the operands variables involve primitive types. In other cases it assumes that the programmer is aware of what he is doing. Therefore, the code in question, will pass the compiler but will throw a reuntime exception (ClassCastException) since Superclass does not implement Printable.

Casting a class 'C' to an interface 'I' is legal only when class 'C' or any of its superclasses implement 'I'.
 
Ranch Hand
Posts: 106
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Yi Meng

I cannot see implements clause anywhere in the code. So how did you make out that class Superclass implements Printable. I tried compiling the code and it compiled.
Infact i didn't understood how the code compiled coz as per the code the Interface Printable is not related to any class, so how did compiler parsed the statement
p = (Printable) Test.s;
successfully. Can we type cast any class to any interface ?
[ August 08, 2003: Message edited by: Manish Sachdev ]
 
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 Thomas Paul:
Will this code compile? If it does, what happens when it runs?



Yes, it would compile.
It is allowed to cast any class to an interface because the subclass of that class may implement that interface:

[ August 08, 2003: Message edited by: Alton Hernandez ]
 
Thomas Paul
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It compiles and gets a runtime exception.
What change can I make to this line: class Superclass { }
that will cause this line: p = (Printable) Test.s; to produce a compile error?
For more cool stuff like this: http://www.javarules.com
 
Alton Hernandez
Ranch Hand
Posts: 443
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Make it final ?
In that case, the compiler knows that you cannot subclass Superclass anymore.
 
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I�d like to have a go at explaining this one, if I may.
p = (Printable) Test.s;
1. Compile-time
From a class type to an interface type is a narrowing conversion if the class does not implement the interface and the class is not final. (Some subclass might implement the interface.)
The type of Test.s is Superclass. The type of p is Printable. From Superclass to Printable is a narrowing conversion.
2. Cast conversion context
A cast conversion context allows a narrowing conversion and requires a run-time check.
3. Run-time
From a class type to an interface type is a widening conversion if the class implements the interface.
From Superclass to Printable is not a widening conversion, because Superclass does not implement Printable. Therefore, a ClassCastException is thrown.
[ August 08, 2003: Message edited by: Marlene Miller ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I really like this way of thinking about, analyzing and explaining conversions, even if no one else does.
1. Decide whether a conversion from one type to another is a widening or a narrowing conversion. (For example, subclass to superclass is a widening conversion, superclass to subclass is a narrowing conversion.) Anything else is surely a compiler-error.
2a. An assignment conversion context allows widening conversions, and also narrowing conversions of some compile-time constants.
2b. A cast conversion context allows both widening conversions and narrowing conversions with a run-time check.
2c. A method invocation conversion context allows only widening conversions.
This way of thinking will help you with conversions between classes and interfaces and conversions to and from array types. Of course, the key is knowing what are the widening and narrowing, primitive and reference conversions.
[ August 08, 2003: Message edited by: Marlene Miller ]
 
Thomas Paul
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Marlene, you would definitely like Doug's book. He thinks exactly the same way you do!
By the way, making the SuperClass final is the correct answer.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you to Thomas and Jim for the reading recommendation. Now, would you please add just one more hour to each day for reading.
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


So does this mean that Type casting in case of interfaces are checked at run time ..and in case of class , Type casting is checked at compile-time.


Not at all. Both classes and intefaces are checked by the compiler and Java Virtual Machine as specifies JLS 5.5 Casting Coversion
 
Thomas Paul
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I missed the comment that Jose responded to. Jose is correct. Both interfaces and classes have compile time validation. The difference is that the possibilities are much wider for interfaces. But, they are not limitless. If it is impossible for a class reference to point to a class that implements the interface then the ast is not allowed at compile time.
For example:

Will give an error for inconvertible types.
However, this will compile:

The only difference is that String is final therefore there is no possibility of someone writing a class that extends String and implements the AudioClip interface. I could do that with Button though since Button is not final. Therefore the Button example compiles cleanly although it is an unsafe cast that will cause a runtime exception:
java.lang.ClassCastException at ABC.main(ABC.java:6)
Exception in thread "main"
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[Marlene]: Thank you to Thomas and Jim for the reading recommendation. Now, would you please add just one more hour to each day for reading.

If only we could...
[ August 10, 2003: Message edited by: Jim Yingst ]
 
Screaming fools! It's nothing more than a tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic