-1

I am attempting to understand java generic wildcards.I came across a basic program.It appears to me that the only thing that can be added to the list s is "null". You cannot add for example

s.add(new Integer (4)); 

OR

s.add(new Char(a));

Before reading a lot of material and confusing my mind,I am attempting to understand where the Java designers are going with introducing wildcards in generics.From my point of view I cannot see any useful feature coming from Generic wildcards.It is possible that it appears so due to my lack of experience and since I am new to java.It would be good if people could share their thoughts on the matter.

import java.util.LinkedList;
import java.util.Iterator;

public class WildCardExampleOne {

    public static void main(String[] args)
    {
        LinkedList<?> s = new LinkedList<Integer>();
        s.add(null);

        Iterator<?> x = s.iterator();

        Object o = x.next();

        System.out.println(o);

        /* note that LinkedList<?> is NOT the same type as LinkedList<Object>
         * here are some statements that wouldn't compile:
         */
        // s.add(new Integer(3)); 
        // Iterator<Object> x = s.iterator();
    }
}
Roman C
  • 48,723
  • 33
  • 63
  • 158
liv2hak
  • 13,641
  • 48
  • 139
  • 250
  • 7
    *"Before reading a lot of material and confusing my mind, I am attempting to understand where the Java designers are going with introducing wildcards in generics. From my point of view I cannot see any useful feature coming from Generic wildcards"* **That statement confuses my mind**. – Steve P. Aug 09 '13 at 01:55
  • 2
    If you do ever want to read material, I highly suggest reading [Java Generics FAQ](http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html). – Steve P. Aug 09 '13 at 01:57
  • 3
    We prefer that you read a lot of material and confuse your mind, attempting to understand where the Java developers were going with ... before you come and ask for help ;-) Some folks here are pretty good at un-confusing people! – Richard Sitze Aug 09 '13 at 02:27
  • These are good references for a start http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html http://stackoverflow.com/questions/252055/java-generics-wildcards http://www.javacodegeeks.com/2011/04/java-generics-quick-tutorial.html It is highly recommended that you attempt to research the material on your own before posting to this site. – Jeremy Johnson Aug 09 '13 at 02:30

4 Answers4

6

It appears to me that the only thing that can be added to the list s is "null".

Yes, this is correct. However, you often receive a list that you don't need to (and aren't supposed to) add any elements to. For example, consider a simple method that prints a list's elements to standard output, one per line:

public static void printAll(final List<?> list) {
    for (final Object elem : list) {
        System.out.println(elem);
    }
}

This method doesn't need to know what the list's element-type is; it can be called on a List<String>, an ArrayList<Integer>, a LinkedList<Object>, or any other List<?>.

ruakh
  • 166,710
  • 24
  • 259
  • 294
2

You don't directly instantiate a generic class with a wildcard; you use is in conjunction with extends or super.

chrylis -cautiouslyoptimistic-
  • 72,004
  • 20
  • 117
  • 147
2

@chylis is right, just to complement his/her comment, I'll try to put it in simple words: Granted, wildcard won't allow you to use methods like setters, but they will allow you to do something like this:

public void doSomethingWithList(List<? extends Number> list) {

    for(Number number: list) {

        // do something with number

    }

}

You can use a List<Integer>, List<Long>, List<Float>, etc. with this method doSomethingWithList() and you'll know for sure that you're dealing with a Number (and use methods like compareTo(), etc.), if you just use generics without the wildcards you would have to do something like this with the same method:

public void doSomethingWithList(List<?> list) {

    for(Object number: list) {
        Number myNumber = (Number)number; // UNSAFE
    }

}
morgano
  • 16,937
  • 9
  • 46
  • 54
1

Check out the java docs for generics: http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

The idea is that you can use them for method types: Collection<?> (pronounced "collection of unknown") is the super type for methods.

It lets you go from this:

void printCollection(Collection<Object> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}

To this:

void printCollection(Collection<?> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}

Where Collection<?> lets you safely READ elements from it, but doesn't let you safely store elements into it.

Where it really gets you an advantage is taking something like this:

public void drawAll(List<Shape> shapes) {
    for (Shape s: shapes) {
        s.draw(this);
    }
}

And rewriting it to something like this:

public void drawAll(List<? extends Shape> shapes) {
    ...
}

Which would work on a class Cicle if class Circle extends Shape.

Hope this is helpful for you in understanding generics.

anonymous
  • 639
  • 1
  • 7
  • 21