The above code gives a compiler error. If I try the code below i get an error which says
WildcardsTest.java:11: non-static class Integer cannot be referenced from a static context Set<Integer> d = new HashSet<Integer>(); ^ WildcardsTest.java:11: non-static class Integer cannot be referenced from a static context Set<Integer> d = new HashSet<Integer>();
1.Firstly, wild cards are not allowed in generic class declarations.
2. Your second error is also new to me at least. But i found the following writeup in the sun generics tutorial. Hope this helps.
A Generic Class is Shared by all its Invocations What does the following code fragment print? List <String> l1 = new ArrayList<String>(); List<Integer> l2 = new ArrayList<Integer>(); System.out.println(l1.getClass() == l2.getClass());
You might be tempted to say false, but you�d be wrong. It prints true, because all instances of a generic class have the same run-time class, regardless of their actual type parameters. Indeed, what makes a class generic is the fact that it has the same behavior for all of its possible type parameters; the same class can be viewed as having many different types. As consequence, the static variables and methods of a class are also shared among all the instances. That is why it is illegal to refer to the type parameters of a type declaration in a static method or initializer, or in the declaration or initializer of a static variable.
Well harvider what you told was the case where you create your own generic classes. Then you cannot use the generic type in static context. Eg
This is the same reason Santiago is facing problems. Santiago you have used the name <Integer> as the type of your class. You have to use an identifier there. like WildcardsTest<T>. But by using Integer there, you are declaring it as your own type. So now when you right Integer, it means the typed Integer of your class. If you change your code to
Set<String> d = new HashSet<String>();
Then it will compile fine even if String is a final class. So basically you will have to change your class to
public class WildcardsTest<Identifier>
Then you will not get any errors...
[Edit: corrected the spelling of Harvinder ] [ November 28, 2008: Message edited by: Ankit Garg ]
Ankit, I got till there..... but i was looking for little bit more insight as to what possible errors the compiler takes care of by putting in that restriction. Anyways, I'll get back once i find something....
then what is the use of it. I mean what is the use of the type. The typing information is useless. You cannot use it in any way whatsoever. Let's take an example
Now you can use the T in your class. But if we would have used ?, then what??
So basically if you were allowed to declare a class with wildcards, then the type of the class will be useless. I hope that this will clear it a bit.
Anyways this is my view on this. Let's see if any of the moderators have to say something on this...
Joined: Jun 10, 2008
Thanks a lot for the explanation Ankit My doubt was regarding the second part. Let me explain my query a little more clearly.
Firstly, i was confused about the generic type named as "Integer". Here, "Integer" is identified by compiler as another type and not the Integer class. So it is clear to me now.
So had i used <T> or <X> instead of <Integer> i would have got a compiler error.
Now the generics tutorial gives the reason as follows:
Indeed, what makes a class generic is the fact that it has the same behavior for all of its possible type parameters; the same class can be viewed as having many different types. As consequence, the static variables and methods of a class are also shared among all the instances. That is why it is illegal to refer to the type parameters of a type declaration in a static method or initializer, or in the declaration or initializer of a static variable.
So, since a static variable and method is shared across all the instances hence the Class's Generic Type parameter is prohibited from being used in there.
But if you say,
then it is not a compile time error.
I hope i have understood the reason which is as follows:
if i say,
Now on instantiating an object of type Generic as :
Generic <String> gen1 = new Generic<String>();
would replace all the T's with "String". Similarly, if i said :
Generic <Integer> gen2 = new Generic<Integer>();
would replace all the T's with "Integer".
If i were using *gen1* and *gen2* in the same code block then the compiler would be at a loss as to which <GENERIC TYPE> do i replace the <T>'s in static methods of class Generic: <Integer> or <String> because static means only single method or variable is shared by all the instances.