views:

1048

answers:

4

In a bunch o' places in my code, I have something like this:

public Class mySpecialMethod() {
  return MySpecialClass.class;
}

which causes the warning

Class is a raw type. References to generic type Class should be parameterized.

But, if I replace

Class

with

Class<? extends Object>

the warning goes away.

Is this simple practice ok, or could it cause trouble later?

+5  A: 

Yes, it's totally right.

It's a requirement that you specify the type. And if you can't, you have to specify the wildcard.

Further reading: Java Language Specification: Parameterized Types

furtelwart
+4  A: 

Depending on what you want to achieve, you can be even more precise :

public Class<MySpecialClass> mySpecialMethod() {
  return MySpecialClass.class;
}
Guillaume
+2  A: 

Not really a Java programmer here, but read some good papers about generics.

Yes, you should add some wildcard or the exact type (Class<MySpecialClass>) to add safety. The reason is that Class is a generic. So, Class<Bar> and Class<Foo> are the same after erasure of their generic type parameter. They all become Class, the so-called raw type. That erasure happens when compiling. Some example to illustrate this where the compiler helps you with automatic casting (exception handling omitted for brevity):

class Mine { }

class Vara {
    public static void main(String... args) {
        { // works. translated to Mine m = (Mine) c.newInstance();
            Class<Mine> c = Mine.class;
            Mine m = c.newInstance();
        }
        { // doesn't work. need a cast: Mine m = (Mine) c.newInstance();
            Class c = Mine.class; // also Class<?> or Class<? extends Object>
            Object o = c.newInstance(); // but this works. pointing to a Mine
            Mine m = (Mine) c.newInstance(); // needs a manual cast
        }
    }
}

Saying Class<?> (and the equivalent Class<? extends Object>), you tell the compiler you really wanted a Class whose T is Object, and didn't accidentally used the raw type. But it won't add any convenience casts. All that generics do is to insert automatic casts for you, to cast from Object to the destination type. Generics are the same whether used with type U or with type T at runtime for compatibility reasons with older java versions.

Johannes Schaub - litb
+8  A: 

It's the correct thing to do only if there really is no common base class or interface that the Class object needs to represent.

Also Class<?> is effectively the same as Class<? extends Object>.

Joachim Sauer