views:

2330

answers:

4

In Java, I'd like to have something as:

class Clazz<T> {
  static void doIt(T object) {
    // shake that booty
  }
}

But I get

Cannot make a static reference to the non-static type T

I don't understand generics beyond the basic uses and thus can't make much sense of that. It doesn't help that I wasn't able to find much info on the internet about the subject.

Could someone clarify if such use is possible, by a similar manner? Also, why was my original attempt unsuccessful?

+12  A: 

Java doesn't know what T is until you instantiate a type.

Maybe you can execute static methods by calling Clazz.doit(something) but it sounds like you can't.

The other way to handle things is to put the type parameter in the method itself:

static <U> void doIt(U object)

which doesn't get you the right restriction on U, but it's better than nothing....

Jason S
Then I'd call the method without specifying any constraints, ie Clazz.doIt(object) instead of Clazz<Object>.doIt(object), right? Do you consider that OK?
André Neves
The second syntax there is the more exact one, which you need if the compiler can't infer the type of the return value from the contaxt in which the method is called. In other words, if the compiler allows Clazz.doIt(object), then do that.
skaffman
I tried Clazz<Object>.doIt(object) and got a compile-time error! "Syntax error on token(s), misplaced construct(s)". Clazz.doIt(object) works fine though, not even a warning.
André Neves
A: 

When you specify a generic type for your class, JVM know about it only having an instance of your class, not definition. Each definition has only parametrized type.

Generics work like templates in C++, so you should first instantiate your class, then use the function with the type being specified.

Marcin Cylke
Java generics are quite different from C++ templates. The generic class is compiled by itself. In fact the equivalent code in C++ would work (calling code would look like `Clazz<int>::doIt( 5 )` )
David Rodríguez - dribeas
I like this answer better than the accepted one... apart from the C++ template reference, the comment about the generic type only being for one instance of the class instead of the entire class is spot on. The accepted answer doesn't explain this, and just provides a workaround which doesn't have anything to do with why you can't use the class's generic type in a static method.
Jorn
A: 

Others have answered your question already, but in addition I can thoroughly recomment the O'Reilly "Java Generics" book. It's a subtle and complex subject at times, and if often seems to have pointless restrictions, but the book does a pretty good job of explaining why java generics are the way they are.

skaffman
Would that be "Java Generics and Collections" (http://oreilly.com/catalog/9780596527754/)?
André Neves
Yup, that's the one.
skaffman
+2  A: 

You can't use a class's generic type parameters in static methods or static fields. The class's type parameters are only in scope for instance methods and instance fields. For static fields and static methods, they are shared among all instances of the class, even instances of different type parameters, so obviously they cannot depend on a particular type parameter.

It doesn't seem like your problem should require using the class's type parameter. If you describe what you are trying to do in more detail, maybe we can help you find a better way to do it.

newacct
Upvoted, this answer actually explains the poster's problem instead of just providing a workaround.
Jorn
I thought there would be a whole differente class for each type parameter, so Clazz<Integer>.doIt() wouldn't be the same method as Clazz<Long>.doIt(). I guess I was wrong. Really need to read something more in depth about generics.
André Neves