48

I have this Java code.

public <T> T readObjectData(ByteBuffer buffer, Class<T> type) {
...
T retVal = (T) summaries;
return retVal;

How to interpret this code? Why do we need public <T> T instead of public T?

How to give the parameter to the 2nd argument (Class<T> type)?

Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
prosseek
  • 182,215
  • 215
  • 566
  • 871

5 Answers5

61

This declares the readObjectData method generic, with one type parameter, T.

public <T> ...

Then the return type is T.

... T readObjectData(...

Without the initial <T>, which is the generic type declaration, the symbol T will be undefined.

In the parameter list, Class<T> type is one of the parameters. Because the return type and this parameter both reference T, this ensures that if you pass in a Class<String>, then it will return a String. If you pass in a Class<Double>, then it will return a Double.

To pass in the parameter, pass in any Class object, e.g. String.class.

rgettman
  • 176,041
  • 30
  • 275
  • 357
35

The <T> part is declaring a generic type argument T. If you were to omit this part, the compiler would likely complain that the type T doesn't exist.

In this case, T serves as a placeholder for an actual type, which will only be determined when the method is actually called with non-generic type arguments.

public <T> T readObjectData(...
        ^  ^
        |  + Return type
        + Generic type argument
cdhowie
  • 158,093
  • 24
  • 286
  • 300
21

<T> is a parameter class. There is no class named T. You can use this method with any class specified via second method argument named type.

since method is defined as following:

public <T> T readObjectData(ByteBuffer buffer, Class<T> type)

You can call it as written below:

MyClass obj = o.readObjectData(buffer, MyClass.class);

Please pay attention that you do not have to cast return value of readOjectData() to MyClass. Once upon a time, before java 5 this method would be defined as:

public Object readObjectData(ByteBuffer)

and its usage looked like:

MyClass obj = (MyClass)o.readObjectData(buffer);

Since casting may cause ClassCastException this is a bad practice. This was a reason for invention of generics.

AlexR
  • 114,158
  • 16
  • 130
  • 208
14

You are probably confused by a similar and more common declaration:

class MyClass<T> {
   private  T myMethod(T a){
       return  a;
   }
}

In above case, there is no need for "<T>" after private ( private <T> T myMethod(T a) )

because the T it's using is the same than the one defined in the class MyClass<T>

Even more, if you write

class MyClass<T> {
   private <T> T myMethod(T a){
       return  a;
   }
}

then the meaning is that the myMethod return type is (potentially) different than the MyClass type. As if you wrote this instead:

class MyClass<T1> {
   private <T2> T2 myMethod(T2 a){
       return  a;
   }
}

Credits: Took the example from "Kanagavelu Sugumar"'s longer answer to How to use Class<T> in Java?

Community
  • 1
  • 1
rafahoro
  • 1,237
  • 13
  • 19
0

This is the pattern used by JsonPath and it lets you use semantics such as:

String author        = JsonPath.read(json, "$.store.book[0].author");
List<String> authors = JsonPath.read(json, "$.store.book[*].author");

It's the closest thing to duck typing used in dynamic programming languages such as Javascript, which can currently be done with Java.

James McGuigan
  • 7,542
  • 4
  • 26
  • 29