6

I would like to know the use of ? in java generics. By studying placeholder T and the wildcard ? , I wondered about ?, gone through several websites/pages and books but failed to understand it. So I created the below class to study the differences.

import java.util.List;

public class Generics2 {

    public <T> void method1(List<T> list){
        System.out.println(list);
    }

    public <T extends Number> void method2(List<T> list){
        System.out.println(list);
    }

    /*public <T super Integer> void method3(List<T> list){

    }*///super does not work.

    public void method4(List<?> list){
        System.out.println(list);
    }

    public void method5(List<? extends Number> list){
        System.out.println(list);
    }

    public void method6(List<? super Integer> list){
        System.out.println(list);
    }

    public <T> void copy1(List<T> list1, List<T> list2){
        //copy elements from list1 to list2

    }//It does not span well with copy of one type of elements from list1 to other type elements in list2, where the list elements 
    //between the two are not same but are related through inheritance.

    public <T1,T2> void copy2(List<T1> list1,List<T2> list2){
        //copy elements from list1 to list2, right now we do not bother about the exceptions or errors that might generate.
    }//Our intention here is not to copy elements with relation between T1 and T2. We intend to explore the differences on T and ?

    public void copy3(List<?> list1,List<?> list2){
        //copy elements from list1 to list2, right now we do not bother about the exceptions or errors that might generate.
    }//Our intention here is not to copy elements with relation between T1 and T2. We intend to explore the differences on T

    public <T1 extends Object, T2 extends Object> void copy4(List<T1> list1, List<T2> list2){
        //copy elements from list1 to list2
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}

Here in one case , There might be several scenarios missing from my class so what I have written is incomplete, in this case can anyone please help me to realize more scenarios. Or I found ? as redundant from , except it provides features like , use of super keyword and lesser characters in a method signature along with return type.

EDIT: Basically my question is to know the reasons behind, the purpose of introducing ? wildcard where a generic type can replace it everywhere. It is not the question of how to use ? or T types. Ofcourse, knowing its usage will provide someanswers. For example , the things I have deduced:

  • ? makes the code more readable and less easy to code at certain places
  • It reduces the code bloating sometimes.
  • We can use super classes , which is not possible with T type.
  • Restricts the addition of new random elements to a list. Where casting(without classcastexception) is valid for T type sometimes.

Are there any more?

smslce
  • 416
  • 1
  • 5
  • 9
  • request to admin or moderator. It will take a somtime a day or two to go through these to understand . So please , let me go through every link provided for this question. – smslce May 18 '15 at 13:13
  • I don't know how deletion of duplicate questions works but I wouldn't expect it to happen that soon, if at all. – biziclop May 18 '15 at 13:23

3 Answers3

3

? means: the type is unspecified. Meaning: if there is no other reason in your code that requires that you have a "named" type parameter; you can/should use ? to express exactly that.

And actually, I asked that some time back, so you might find the answers here helpful: Java generics: wildcard<?> vs type parameter<E>?

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • I read the link provided, When I look at the answer you selected it started by saying sometimes there is no difference between ? and T . Later it explains placeholder generic is more usable than ? wildcard(refering to the error due to ?) which returns to question on use of ?. Also can you give more insight on the statement "if there is no other reason in your code that requires that you have a "named" type parameter". Does it mean no type parameter used in the entire class where it is implemented or just at the method where we need to pass something. – smslce May 18 '15 at 15:22
  • The point is: if you have a need to write "T"; then you should use "T". If the type is unknown and of no importance, than writing "?" makes that more explicit (but you could still use "T" instead of "?") – GhostCat May 18 '15 at 15:39
  • can you add anything to my list in the edited question. – smslce May 18 '15 at 16:23
2

You use the unbounded wildcards when the list (or the collection) is of unknown types.

You should never use it when you want for example to insert values to a list (since the only value you can insert is null).

It's used when you want to get information about some data structure, like printing its content, when you don't know what type it might be containing. For example:

public static void printList(List<?> list) {
    for (Object elem: list)
        System.out.print(elem + " ");
    System.out.println();
}
Maroun
  • 94,125
  • 30
  • 188
  • 241
  • Isn't this same as following.public static void printList(List list){ for (Object elem: list) System.out.print(elem + " "); System.out.println(); } – smslce May 18 '15 at 15:08
1

Somebody wrote up a good answer to this question here. The question mark basically means "any type", but it can be very useful when working with interfaces or abstract classes. For example,

List<? extends MyAbstract> myClasses = new ArrayList<? extends MyAbstract>();

This is useful because you still get type checking, to make sure that anything put into your list is a subclass of MyClass. If you had a particular method or field in the abstract class you needed to work with, you can work with it for all subclasses regardless of the specific implementation. For a more real-world example, I use this for URL routing:

Map<String, Class<? extends IJSONService>> routes = new HashMap<String, Class<? extends IJSONService>>(){
  {
    put("default", EmployeeFinderSearch.class);
    put("", EmployeeFinderSearch.class);
    put("reports", EmployeeFinderReports.class);
    put("me", Me.class);
    put("email", SendEmail.class);
    put("image", UploadImage.class);
    put("excel", ExportExcel.class);
  }};
Nathan
  • 2,093
  • 3
  • 20
  • 33