Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics, passing wrong types?

Tags:

java

generics

What is the difference between the last two statements ? why does one statement work and the other doesn't ?

package Main;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {

    public static void printIt(List<Object> l)
    {
        System.out.println(l);
    } 

    public static void main(String[] args) {
        List<String> l =new ArrayList<>();
        l.add("A");

        //what is the differance between the following statments ? 

        printIt(Arrays.asList("A")); // it compiles successfully
        printIt(l); // it does not compile

    }
}

2 Answers

The problem is printIt() method expects List<Object> as parameter but we are passing List<String> to it, that's why there is compilation problem. Replace the parameter List in method printIt() as below:

    public static void printIt(List<? extends Object> l)
    {
        System.out.println(l);
    }

Now both will compile,

like image 194
pbajpai Avatar answered Sep 26 '26 21:09

pbajpai


This is because your method expects a List<Object> and you give it a List<String>.

As weird as it can appear the first time you read this, a List<String> is not a List<Object>.

In your example, you don't modify the content of the lists but let's imagine a method where you want to add a new element.

public static void addIt(List<Object> l, Object o)
{
    l.add(o);
} 
public static void main(String[] args) {
    List<String> l =new ArrayList<>();
    l.add("A");
    addIt(l, new Integer(1)); // What?! you want to add an Integer to a List<String>!!!!
}

You will have to use wildcards (?) or to solve your problem so your your List .

public static void printIt(List<?> l) //or printIt(List<? extends Object> l)
{
    System.out.println(l);
} 

The case of printIt(Arrays.asList("A")) is a bit different. It is due to the fact that the generic is determined dynamically, by type inference on a generic method.

List<Object> l = Arrays.asList("A"); //this is valid, the generic type is determined from the type we expect in this declaration.
like image 28
C.Champagne Avatar answered Sep 26 '26 21:09

C.Champagne



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!