简体   繁体   中英

Generic method java 6 <T> before return type

What is the difference between:

public <T> void createArray(T sample){
    ArrayList<T> list = new ArrayList<T>();
    list.add(sample);
}

and

public void createArray(T sample){
    ArrayList<T> list = new ArrayList<T>();
    list.add(sample);
}

I read that the method signature for using types should have <T> before the return type but how come I am still able to create the method without the <T> ? What is the implication if I do or do not put it?

In the second method, the type parameter would be typically defined in the class declaration to which the method belongs:

class MyClass<T> {
   public void createArray(T sample){
      ArrayList<T> list = new ArrayList<T>();
      list.add(sample);
   }
   ...
}

So the second method belongs to a generic type. The first method is a generic method because it defines its own type parameter.

In the first case, the generic parameter T is defined for the method. Other methods may have a different T .

In the second case, the generic parameter T is defined for the class or interface. All methods within that class or interface must have the same T .

Defining a class-wide generic allows you to enforce the same type parameter on many methods. You can also have fields of the generic type. See ArrayList<t> for an example.

From the second example, I am guessing this method is defined in a generic class something like this:

class SomeClass<T> {
  public void createArray(T sample){ ... }
}

The difference between the first and second example is that in the first example, the T is effectively a "local" type variable. You could give it a different name, eg S , to make it a little bit clearer:

class SomeClass<T> {
  public <S> void createArray(S sample){ ... }
}

So, S and T are both type variables, but are unrelated. T is defined at class scope, and so can be used to refer to the same type amongst all methods in the class; S is defined only at method scope.

By using the name T instead of S , you are hiding the class-level type variable, T . This means that, for example, the following would not work:

class SomeClass<T> {
  public T getWotsit() { ... }
  public <T> void createArray(T sample){
    T wotsit = getWotsit();
  }
}

because the T in the signature of getWotsit and the T in the variable declaration T wotsit potentially refer to different types; this is more clear if you use the name S to write the equivalent code:

class SomeClass<T> {
  public T getWotsit() { ... }
  public <S> void createArray(S sample){
    S wotsit = getWotsit();
  }
}

As far as I'm aware, there is no way to refer to the class-level type variable if you've defined a method-level type variable with the same name.

However, both of the following would be fine:

class SomeClass<T> {
  public T getWotsit() { ... }
  // No additional type variable, so T is the class-level type variable.
  public void createArray(T sample){  
    T wotsit = getWotsit();
  }
}

class SomeClass<T> {
  public T getWotsit() { ... }
  // Type variable has different name, so `T` is the class-level
  // type variable.
  public <S> void createArray(T sample){
    T wotsit = getWotsit();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM