Reputation: 7879
In Java 6 something like MyClass
and MyClass<?>
were considered equal but in Java 7 they are not.
With Java 7, as an example I stumble to problems with for example Hamcrest matchers that are given an instance of MyClass
and a matcher that expects to match MyClass<?>
, and they get compilation error saying
no suitable method found for assertThat(MyClass,Matcher<MyClass<?>>)
[ERROR] method Assert.<T#1>assertThat(T#1,Matcher<? super T#1>) is not applicable
[ERROR] (actual argument Matcher<MyClass<?>> cannot be converted to Matcher<? super MyClass> by method invocation conversion)
Why the change? What's the difference here between a rawtype and a generics type that has unspecified type argument?
Suggested answer does not really explain what I wonder here. One of the comments says "use of unbound wildcard (e.g. in a method signature) signals a promise that the method in question is aware of generics and will honor the generic type of that object." Here, again, I feel if it's just a "signal" it should not cause problems at compilation time.
I feel that MyClass<?>
is just MyClass
with information on what it contains or operates on, but while it's <?>
, there's no added information and so they should be considered equal?
Upvotes: 2
Views: 472
Reputation: 55213
This seems to be related to a compiler bug that was fixed in Java 7.
The compiler error that you now receive is correct. It looks like you're calling the method with wildcarded generic types, e.g. MyClass<?>
and Matcher<MyClass<?>>
. Note that a wildcard type argument means "some unknown type", so those arguments could really be MyClass<String>
and Matcher<MyClass<Integer>>
, which is obviously incorrect.
Using a raw type, e.g. plain MyClass
opts out of generic type checking, which is why a call with raw types will compile (but likely fail at runtime with a ClassCastException
).
Upvotes: 3
Reputation: 2064
EDIT
MyClass
and MyClass<?>
in Java 6 are not same ,
see this link
For backward compatibility, assigning a parameterized type to its raw type is allowed:
MyClass<String> stringBox = new MyClass<>();
MyClass rawBox = stringBox; // OK
But if you assign a raw type to a parameterized type, you get a warning:
MyClass rawBox = new MyClass();
// rawBox is a raw type of MyClass<T>
MyClass<Integer> intBox = rawBox;
// warning: unchecked> conversion
MyClass
is not a Generic Type , MyClass<?>
is a generic type class which means , MyClass
is a containing a type of another class ,
for eg , it is common in Java , we do like this
List<String> listofString = new ArrayList<String>();
here it means variable listofString is a object of List will restrict it contents to only String type of objects. <String>
tells generic .
Upvotes: 1
Reputation: 545
As Jon Skeet said, they were not considered equal, that would be incorrect in my opinion. I cannot see any difference if I try in Java 6 and Java 7 - how do you tried this?
To understand the difference between a raw- and generics-type just have a look at this posting (scroll down to "How's a raw type different from using as a type parameter?"): What is a raw type and why shouldn't we use it?
Upvotes: 1