Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does public<T> void run (T object ) { } means? [duplicate]

Tags:

java

generics

I am reading generics and tried writing the below code. There are no compilation error.

import java.util.*;

public class JavaApplication14 {

    public<T>  void run (T obj ) {
        //Do Something
    }

  public static void main(String[] args) {     
      JavaApplication14  m= new JavaApplication14();
      m.run(new ArrayList<>());  
      m.run(new Interger(5);
      m.run(5);
     }
}

If the function is

 public<T extends Number>  void run (T obj) {
            //Do Something
        }

It makes sense as we can restrict the arguments of this function to a Number and its subtypes. But am terribly confused what the function 'run' without any bound mean? Can it now take any object as the argument ? In what scenario do i need to use such a function with generics ?

like image 338
Rahul Kurup Avatar asked Aug 09 '15 11:08

Rahul Kurup


2 Answers

Part of your confusion may stem from the fact that there is no point in having run be a generic method in this case. You normally use a type parameter to create a relationship between two parameter types and/or between parameter type and return type. In your example run could just as well have been declared as requiring an Object parameter (a type parameter without a declared bound effectively has Object as its bound).

There is one case I know of where you might usefully use a type parameter in a single parameter type: when you want to be able to manipulate a collection in a way that doesn't depend on the element type, but which does require inserting elements into the collection. Consider for example a hypothetical "reverse list" method:

<T> void reverse(List<T> list)
{
    List<T> reversed = new ArrayList<T>();
    for (int i = list.size(); i > 0; i--) {
        reversed.add(list.get(i - 1));
    }
    list.clear();
    list.addAll(reversed);
}

It would be difficult to write this in a way that didn't require a type parameter, i.e. that takes a List<?> parameter. The only way to do it without casts is to do:

void reverse2(List<?> list)
{
    reverse(list);  // call reverse as defined above!
}

But again, this doesn't apply in the example you discuss.

So in summary:

A type parameter without an explicit bound effectively has an Object bound.

There are two reasons why a method might need a type parameter (either with or without an explicit bound):

  • Specify a relationship between parameter types and/or return type
  • Capture a potential wildcard as a type parameter to allow operations that wouldn't otherwise be possible (as in the reverse example).

The example method you discussed:

public<T>  void run (T obj )

... does neither of these, and so the type parameter is pointless. The method might just as well have been declared as public void run(Object obj).

like image 175
davmac Avatar answered Oct 23 '22 09:10

davmac


It allows you to avoid any cast.

public class SomeClass {
      void doStuff();    
}

public<T extends SomeClass>  void run (T obj) {
    //can call doStuff without any casting
    obj.doStuff();
}

public<T>  void run (T) {
    //Here, there's no clue to perform the implicit cast.
    obj.doStuff();  //won't compile
}
like image 33
Mik378 Avatar answered Oct 23 '22 10:10

Mik378