-1
  1. I dont understand a strong defenition of type parameter in generic class or method. It's a reference type such that... what? Does it just non reifiable type? Is it true that all reference type for compiler is reifiable or not reifiable?

2.Consider the well known code:

List<? extends String> strs= new ArrayList<String>();
? extends String str;//error
strs.add("sd");//error

Why ? extends String str; does not valid? I thinked that if we declare a reference to a generic type, for example List<E> strs; for some type E then compiler define type parameter to a specific type E.

I dont understand what occur in the case List<? extends String> strs? Does List<? extends String> and , for example List<String> parsing similarly at compile time or List<? extends String> parsing different from List<E> for some reifiable type E?

Johan
  • 71,222
  • 23
  • 174
  • 298
St.Antario
  • 23,179
  • 26
  • 96
  • 243
  • 2
    You question is confused. It would benefit from a code example where you show us what you want to achieve and to code you tried to do that with. – Johan Oct 09 '13 at 17:13
  • 1
    [look to the Generics Tutorial oracle doc.](http://docs.oracle.com/javase/tutorial/java/generics/index.html) – Husam Oct 09 '13 at 17:16
  • @Johan When we trying to add a some string to `strs` we have compile error. In the error descriptoin compiler cant find a method with signature `add(CAP#1,int)`. I dont understand completely how compiler does work. – St.Antario Oct 09 '13 at 17:43

2 Answers2

1

Generics are used to specify a type.

Consider the following class def:

public interface List<E> extends Collection<E>  

This tells us there we have a List that can hold elements of any type.
Notice how there are no restrictions on E.

If we define a class like so:

public class MyList<T extends String> implements List<T>

We now have a MyList that implements List, but only accepts Strings (or decedents).

Inside this class we can refer to T.

public class MyList<T extends String> implements List<T> {
  private ArrayList<T> internalStorage;

Key point
In the class definition we have defined what T is; it's any class based on String.
Inside the class T can thus be referenced.
However the flavor of T does not get fixed until the class actually gets instantiated:

MyList<MyStringType> test = new MyList<MyStringType>(parameters);  //java 6
MyList<MyStringType> test = new MyList<>(parameters);  //java 7, same but shorter.

Now Java knows what T means inside the MyList class T is a MyStringType.
Armed with is knowledge Java compiles the class and replaces all references to T with references to the actual class MyStringType.
It completely forgets about T.

Now inside the class note that everywhere T is mentioned it will get replaced by MyStringType.
But what if I want to handle a string, but not necessarily the MyStringType.

Solution:
I define a member like so:

List<? extends String> strs;  //Will fill the data in later

Now we have a List called strs that will only accept strings, but that will not be forced to use strings of type MyStringType.
This list is not bound to the definition of T that was fixed when MyList was instantiated.
When we assign a value to the strs, the flavor of the List if fixed. In your example it will be a List of String.

? extends String str;//error 

The variable cannot be fixed, because its type cannot be nailed down when the class that holds it gets created.

Johan
  • 71,222
  • 23
  • 174
  • 298
0

Generics is designed for read and not for write. This is why you can use generics in parameters for a method, but cannot use it for declare a variable that you can use after for read/write from it :-)

angel_navarro
  • 1,747
  • 10
  • 11