Question

First some code (Java 7) created just to illustrate my questions.

import java.util.*;

class Generics101 {



    public static void addTrue(List list) {
        list.add(true);
    }

    public static void main(String[] args) {
        List<Integer> testList = new ArrayList<>();

        addTrue(testList);
        System.out.println(testList.get(0));

        // testList.add(true);  // will not compile when uncommented

    }
}

I have the following two questions:

  1. In addTrue method Eclipse hints that it does not like raw types. When I try to change method parameters to use a wildcard List<?> list it won't compile. I looked through Generics Tutorial but could not find the answer. What am I missing here and where should I read about it?

  2. The same tutorial states that "Generics were introduced to the Java language to provide tighter type checks at compile time..." I understand that due to type erasure such enforcement can't happen at run-time and so my above code compiles and runs. It will trigger compiling error if the commented line is uncommented, so I assume that tighter type checks are in force within the same method. What is the exact scope for such enforcement? How is it formally defined?

Was it helpful?

Solution

When I try to change method parameters to use a wildcard List list it won't compile.

It wouldn't compile, because you can't add anything in a List<?>. Because you don't know which type of List is actually coming. For example, take your current case only. You are passing a List<Integer>. It would successfully be passed to List<?>. No issues. But you are adding true, a boolean type to it. If compiler allowed that, it would throw ClassCastException at runtime. So, it isn't allowed.

so I assume that tighter type checks are in force within the same method. What is the exact scope for such enforcement?

No, it's not like that. It is not that the type checks are done under a certain scope. It's enforced wherever generics are used. Your current code won't compile if used with proper generics, because you are trying to add a boolean type to a List<Integer>. Why would you expect that to work?

Try changing your method to a generic method, and you'll see that it would fail to compile:

public static <T> void addTrue(List<T> list) {
    list.add(true);  // Won't compile
}

I looked through Generics Tutorial but could not find the answer. What am I missing here and where should I read about it?

Well, that is the standard tutorial from Oracle. And that is where you should read. Apart from that, you can also go through a really nice collection of tutorial on generics at Java Generics FAQs - Angelika Langer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top