3

I have the following code working and I'm not sure why it doesn't throw an exception:

List[] x=new ArrayList[2];
x[0]=new ArrayList<Integer>();
x[1]=new ArrayList<String>();
x[0].add("test");
x[1].add(5);
System.out.println(x[0]);
System.out.println(x[1]);

This prints:

[test]
[5]

x[0] is array of integer and it add String without any issue. x[1] is array of String and it add integer without any issue.

How does that work?

1
  • A good example of why you should never use raw types. Note that generics are erased at runtime. So if it compiles, it will also run through. Generics only provide safety at compile time. Using the raw types, you effectively bypassed all the safety. Commented Jul 8, 2019 at 17:41

2 Answers 2

4

First of all, this has nothing to do with arrays. The following exhibits the same behaviour:

List x = new ArrayList();
x = new ArrayList<Integer>();
x.add("test");
System.out.println(x);

The key reason this behaves the way it does is that x is declared to have the raw List type. For a comprehensive discussion, see What is a raw type and why shouldn't we use it?

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

Comments

2

You have declared an array of raw typed lists. Generic values do not exist at runtime, after you have compiled your code. So basically your lists are of type List<Object>.

  • "test" is a String, which is basically an Object
  • 5 gets autoboxed to an Integer which is also an Object

So your compiler will not throw any error. If you are using an IDE it might be warn you:

Unchecked call to 'add(E)' as a member of raw type `java.util.List'

(From IntelliJ)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.