This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Beginning Java and the fly likes Unchecked cast Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Unchecked cast" Watch "Unchecked cast" New topic
Author

Unchecked cast

vijay shanker
Ranch Hand

Joined: Oct 26, 2007
Posts: 88
Type safety: Unchecked cast from Object to Set<Item>

what is this warning and how can i check this cast in my programs
Marco Ehrentreich
best scout
Bartender

Joined: Mar 07, 2007
Posts: 1280

Hi vijay,

this error occurs when you try to cast an Object reference variable to some other type like this Set. Because of polymorphism a reference to Object could also be a reference to any other object because all classes implicitly are derived from Object. Therefore the compiler complains and you as a programmer have to confirm that you know what you're doing and confirm that the reference variable of type "Object" really contains a Set<Item>.

You could use the @SuppressWarnings("unchecked") annotation to suppress this warning but generally it's better to rethink your code which causes this unsafe cast. Perhaps there's a better way to solve this issue

Marco
[ May 29, 2008: Message edited by: Marco Ehrentreich ]
vijay shanker
Ranch Hand

Joined: Oct 26, 2007
Posts: 88

Perhaps there's a better way to solve this issue



hi Marco Ehrentreich,

this is great that answer but above line does not make any head start to me

would you like to clarify some more about this

thanks

Vijay
Rodrigo Tomita
Ranch Hand

Joined: Apr 28, 2008
Posts: 70
Vijay,

Let's try with an example. You probably have something like:



So, this is what I believe Marco meant: in your class A, the Set is declared to contain Object. So, any type of objects can be inserted there, it can be instances of Item or not.

In your class B, you would get the warning because you are expecting the set to contain only instances of Item. However there may be other types in it. The compiler has no way to check that, so it gives you the warning. It is up to the developer to make sure it works in run time.

Hope this clarifies it.
Marco Ehrentreich
best scout
Bartender

Joined: Mar 07, 2007
Posts: 1280

Hi vijay,

of course I can try to explain in a little more detail. The basic problem with your code is the same as Rodrigo gave you with his example. As I already said it has to do with the concept of polymorphism. In fact this is a very fundamental concept of object oriented programming. So I think you don't have very much experience with object orientation?!? This is definitely something you'll have to learn if you want code in Java (or any other OO language).

I'll try to give you a short explanation on this. In Java all classes are implicitly inherited from Object (note the capital letter). So every class and object (no capital!) ranging from String to Set or to your own classes in Java is a child of Object.

The other thing are reference variables which "point" to an object of any specified class like

But because of polymorphism it's not only possible to assign objects of class Shape to this variable shape! It's also allowed to assign any object of any classes which are childre of Shape because they extend shape (inheritance). If you have children of Shape like class Rectangle or Circle it's absolutely legal to use the above variable as follows:

To come back to your problem, you have a reference variable of type Object (which was Shape in my example) and you want to downcast it to type Set<Item>. Because of polymorphism like I described above this variable isn't restricted to point to an object of type Object. No, it could even point to a String object, a List object, a Shape object, a House object or a Set<Item> object because this classes are all children of class Object.

And the point here is that even if you're sure that your reference variable of type Object is pointing to a Set<Item> the compiler doesn't know that!!! For the compiler this could be an object of type Object or any class type derived from Object. For this reason you explicitly have to tell the compiler that you really, really know that it's a variable of type Object but it points to a an object of type Set<Item> and it's safe to do the cast!

I hope now you understand the problem a little bit better. Unfortunately it's very hard to explain such topics in a few sentences here and of course I don't know how familiar you are with OOP. Just let me know if something is still unclear!

Marco
Johnny Phan
Greenhorn

Joined: Jan 11, 2009
Posts: 1
Hello OOP experts,

Here's the real question:

Object x;
Calendar k = (Calendar) x;
List<String> j = (List<String>) x;

Why does the 3rd line throw the "Unchecked cast" warning and not the 2nd?
Why do I have to use @suppressWarning for the 3rd line and not the 2nd? Why, why, why?
Michal Pomorski
Greenhorn

Joined: Aug 10, 2011
Posts: 1
Johnny Phan wrote:Hello OOP experts,

Here's the real question:

Object x;
Calendar k = (Calendar) x;
List<String> j = (List<String>) x;

Why does the 3rd line throw the "Unchecked cast" warning and not the 2nd?
Why do I have to use @suppressWarning for the 3rd line and not the 2nd? Why, why, why?


That's because the reason for unchecked cast is not polymorphism as earlier indicated, but java's implementation of generics, i.e. the type parameters to classes such as List<String>.
For non-parameterized types, the actual type of each object is known to the vm. So if you do

The vm will know that o is actually a String and will be able to verify (during runtime) that you made a correct cast.

The thing is that the vm does not hold the actual type of the parameters for parametrized (generic) types during runtime - the information that the List is holding Strings is removed.
The vm knows only that it is a List, but does not know if it is List<String> or List<Integer>, so it cannot verify that you are making the correct cast, hence the warning:

Observe, that if you try to do:

It is the compiler, not the vm that will stop you. The compiler sees the full types of the variables and will prevent the program from being compiled due to illegal cast.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Unchecked cast
 
Similar Threads
Class and generics
access data inside Object
Compiler warnings
Filter Problem
Xlint Compiler Warnings from the Command-Line