0

May be this questions is already asked, but i didn't found any words about this,

Problem: I am not getting the working of below code. Could any one please add some points in order to understand this

public static void main(String[] args) {


   List list=new ArrayList<>(); 
   list.add("String");
   listOPt(list);
}
public static void listOPt(List<Integer> intList){
        intList.add(343);
        System.out.println(intList.toString());
}

output: [String, 343]

I am not getting how intList printing string also.

As per my understanding if we add any object before calling listOPt() it will insert into intList and after that function intList accept Integer only is it?

but how it is stored in memory?

Musaddique
  • 1,295
  • 1
  • 11
  • 28
  • 2
    reading about how generics work in java and type erasure might help you: http://stackoverflow.com/questions/313584/what-is-the-concept-of-erasure-in-generics-in-java – OH GOD SPIDERS Apr 28 '16 at 12:20
  • What you have shown here is an example of problems of using **raw types**. Search the web for *Java Generics Raw Type* you will get a lot of materials. – Blip Apr 28 '16 at 12:21
  • https://docs.oracle.com/javase/tutorial/java/generics/erasure.html https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html also the oList arraylist is not used in your code example, so for clarity I suggest you remove it. – kalvatn Apr 28 '16 at 12:24
  • does anyone please add your points on above scenario only. I just need how compiler behave on above scenario? – Musaddique Apr 28 '16 at 12:28
  • 1
    The above scenario is not a special scenario. The compiler and jvm behave as they always do with generics (The type information was erased by the compiler and at execution time, a List and a List are the same). – OH GOD SPIDERS Apr 28 '16 at 12:33

4 Answers4

1

Generics were implemented quite lately in the JDK so it was decided to use Type Erasure.

This means roughly that generics are checked at compile time but the information is lost at runtime. Casting a List<? extends Object> to a List<Integer> will certainly not remove the String item you added. In other cases you could have a compilation error (i.e. if oList was a List<String>).

C.Champagne
  • 4,706
  • 2
  • 21
  • 32
0

At below line,

List<? extends Object> oList=new ArrayList<>();

java will create a list which can take Object or any subclass of object.

At method listOPt(List<Integer> intList), you intend to use type inference, as you have used <> operator at instantiation. But type inference works at the time of instantiation, where it has created a list which can accept Object and subtype. So in method listOPt(..) it can accept integer.

Basically your List object is as good as List<Object>.

Amol Binwade
  • 149
  • 6
  • 1
    no the `List` object is as good as `List` is not correct. It basically of RAW TYPE. Like in the method `listOPt` it requires a parameter `List`. But if you try to pass an object of `List` It will show an error. But if pass an instance of `List` it will not give any error – Blip Apr 28 '16 at 12:45
  • @Amol Binwade...wrong!! oList will accept List of object who extends Object (oList.add("String") will give compile time error) like... List s=new ArrayList<>(); oList=s. – Musaddique Apr 28 '16 at 12:46
  • @Tipu I feel you have the basic understanding of **Type Erasures**. But Could you clarify what you are actually looking for? – Blip Apr 28 '16 at 12:51
0

Java compiler compiles with type erasure. Means when you compile code it will be compiled without your added generic.Please refer Java generics - type erasure - when and what happens and oracle Java compiler Type erasure

if you still want that your list should accept Integer then please declare it with generics

List list=new ArrayList();

Then you will not be able to add String in it.

Community
  • 1
  • 1
Shatayu Darbhe
  • 551
  • 1
  • 6
  • 12
0

Here in your code :

List list=new ArrayList<>();

You have not used any Type Erasures for the declaration of the variable list. So the compiler actually converts it to a RAW TYPE. Which practically means that now this list variable can be converted to any type of list like you have done List<Integer> and the compiler is unable to check the content of the the variable as you have not declared any Type Erasures.

So, immaterial of what has been earlier stored in the variable list the compiler simply treats list as an instance of List<Integer>. Now when you call intList.toString() it basically calls the toString method of all the objects that are contained in this list object and so you get that output.

This is basically the problem you run into while using Raw Type. In order that this kind of problem does not happen always use Type Erasures.

Blip
  • 2,711
  • 3
  • 17
  • 42