vertti
vertti

Reputation: 7879

Difference between SomeClass and SomeClass<?>

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

Answers (3)

Paul Bellora
Paul Bellora

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

anshulkatta
anshulkatta

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

anm
anm

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

Related Questions