aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Wildcards in Class declaration Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Wildcards in Class declaration" Watch "Wildcards in Class declaration" New topic
Author

Wildcards in Class declaration

Santiago Bravo
Ranch Hand

Joined: Jul 25, 2008
Posts: 226
Hi All,

Why cant wildcards be used in class declarations?



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>();




Thanks


Santiago
My Path to SCJP Certification My Path to SCWCD Certification
victor kamat
Ranch Hand

Joined: Jan 10, 2007
Posts: 247
This is because Integer is a final class and cannot be sub-classed.
Santiago Bravo
Ranch Hand

Joined: Jul 25, 2008
Posts: 226
Hi

I get the same error if I try with ? extends Number or even ? extends Object

Is this mentioned in the JLS somewhere?

or can anyone explain why these errors occur?


Thanks
Markus Klein
Greenhorn

Joined: Aug 29, 2008
Posts: 19
you can't use wildcards in class declarations.

perhaps this can help you to understand why wildcards are not allowed in class declarations:

http://www.coderanch.com/t/269984/java-programmer-SCJP/certification/extends-Animal-VS-extends-Animal
[ November 27, 2008: Message edited by: Markus Klein ]
Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231
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.


The link to the tutorial is link

Honestly speaking, i am still trying to figure out the inner workings of the above explanation.
:roll:


thanks
Harvinder
Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231
Hey maybe i am being a bit lazy but can the experts please clarify this with an elaborate example. Henry, Marc, Jesper, Bert or anyone.
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9321
    
  17

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 ]

SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231
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....
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9321
    
  17

harvinder if you declare a class like this

class MyClass<? extends Integer>

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...
Harvinder Thakur
Ranch Hand

Joined: Jun 10, 2008
Posts: 231
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.

Therefore, the compiler does not allow it at all.

Please correct me if i am wrong.
Santiago Bravo
Ranch Hand

Joined: Jul 25, 2008
Posts: 226
Thanks Ankit and Harvinder for your explanations
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9321
    
  17

harvinder you got it right!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Wildcards in Class declaration