19

In Java when casting from an Object to other types, why does the second line produce a warning related to the cast, but the first one doesn't?

void a(Object o) {
  Integer i = (Integer) o;
  List<Integer> list = (List<Integer>) o;
}

/*Type safety: Unchecked cast from Object to List<Integer>*/
1
  • The second line produces a warning because only generics generate such a warning. The first contains no generic, hence no warning. Commented Jul 15, 2014 at 12:17

3 Answers 3

27

It's because the object won't really be checked for being a List<Integer> at execution time due to type erasure. It'll really just be casting it to List. For example:

List<String> strings = new ArrayList<String>();
strings.add("x");
Object o = strings;

// Warning, but will succeeed at execution time
List<Integer> integers = (List<Integer>) o;
Integer i = integers.get(0); // Bang!

See Angelika Langer's Java Generics FAQ for more info, particularly the type erasure section.

Sign up to request clarification or add additional context in comments.

Comments

9

Jon's answer is the right one, but occasionally you can't get around that warning (like when you're working with a legacy API). In those cases you can suppress the warning like so:

@SuppressWarnings("unchecked")
List<Integer> list = (List<Integer>) someApiThatReturnsNonGenericList();

Comments

9

For clarity, let me slightly rewrite the examples...

I would say, the cruxial difference between:

void a(Object o) {
  Integer i = (Integer) o;
  ...
}

and

void a(Object o) {
  List<Integer> list = (List<Integer>) o;
  ...
}

is that, given that there is a type-error, the first cast will always immediately throw a RuntimeException (specifically, a ClassCastException) when executed.

While the second one might not -- as long as the input parameter o is any kind of List<?>, execution will just proceed, in spite of an incorrect cast.

Whether the code will somewhere later throw an exception or not, depends upon what you do with the list.

But regardless, an Exception might not be thrown at the line where the cast was made, but somewhere else (which might be a difficult bug to trace down) or not at all.

That's what I understand, is the reason the compiler-designers considered a warning appropriate in the second case only.

2 Comments

The first will not always throw a CastClassException. The incoming object could very well be an Integer. The first line MIGHT throw an exception, just as the second might if o is not a List.
@Hot Licks : yeah, that's why I wrote "given that there is a type-error" above -- I even put in bold ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.