0

I'm studying for OCA certification and on the ArrayList topic, after making some tests, I came across the following issue:

import java.util.ArrayList;

public class ArrayLists{

    public static void main(String[] args) {

        ArrayList list = new ArrayList(); 

        list.add(1);
        list.add("hi");

        // Passing a non-Generics list to a Generics list
        ArrayList<String> list2 = new ArrayList<>(list); 

        for(int i = 0; i < list2.size(); i++) {
            System.out.println(list2.get(i));
        }

        // error, cannot cast Integer to string
        for(String s : list2) { 
            System.out.println(s); 
        }

    }
}

Why does Java compile this behavior, since I'll get a runtime error running the program?

Kedar Mhaswade
  • 4,535
  • 2
  • 25
  • 34
hlucasfranca
  • 260
  • 5
  • 11
  • 1
    Have you read http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it? – Tunaki Apr 23 '16 at 15:24
  • 1
    You would have got a warning which you ignored which is why you might get an exception. This is because of a process called Type erasure. Look it up or search the forum for that term. You will get a lot of related questions. – MS Srikkanth Apr 23 '16 at 15:25
  • @hlucasfranca - just look at the link that Tunaki posted – MS Srikkanth Apr 23 '16 at 15:28
  • This code compiles with many `javac` warnings. Perhaps looking at those warnings is instructive. See [here as well](http://programmers.stackexchange.com/questions/94754/how-do-i-convince-my-teammates-that-we-should-not-ignore-compiler-warnings) – Kedar Mhaswade Apr 24 '16 at 01:35

1 Answers1

1

This allows the legacy code (written before Java 5 existed) could still be used in newly written code without modification.
The declaration of the list uses Raw type

    ArrayList list = new ArrayList();

Raw types show up in legacy code because lots of API classes (such as the Collections classes) were not generic prior to JDK 5.0. When using raw types, you essentially get pre-generics behavior — a Box gives you Objects.

That is why it is possible to add Integer and String. It is similar to this declaration:

ArrayList<Object> list = new ArrayList<Object>();

but with type checking disabled and just a warning is shown:

Type Safety: The expression of type ArrayList needs uncheck conversion to conform to Collection < ? extends String>

for the line:

    ArrayList<String> list2 = new ArrayList<>(list); 
Anton Krosnev
  • 3,964
  • 1
  • 21
  • 37
  • 1
    It is not the same, refer to http://stackoverflow.com/a/2770692/1743880, section "How's a raw type different from using `` as type parameters?" – Tunaki Apr 23 '16 at 15:54