我正在阅读泛型,并尝试编写以下代码。没有编译错误。
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);
     }
}如果函数是
 public<T extends Number>  void run (T obj) {
            //Do Something
        }这是有意义的,因为我们可以将这个函数的参数限制在一个数字及其子类型上。但我非常困惑,没有任何约束的函数“运行”意味着什么?现在可以用任何物体作为论据吗?在什么情况下,我需要在泛型中使用这样的函数?
发布于 2015-08-09 11:06:19
您的部分困惑可能源于这样一个事实:在这种情况下,让run成为一个通用方法是没有意义的。通常使用类型参数在两个参数类型和/或参数类型与返回类型之间创建关系。在您的示例中,run可以被声明为需要一个Object参数(一个没有声明的绑定的类型参数实际上将Object作为其绑定)。
有一种情况我知道,您可以在单个参数类型中有效地使用类型参数:当您希望能够以不依赖于元素类型但确实需要将元素插入到集合中的方式操作集合时。例如,考虑一个假设的“反向列表”方法:
<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);
}要以不需要类型参数(即接受List<?>参数)的方式编写它是很困难的。没有强制转换的唯一方法是这样做:
void reverse2(List<?> list)
{
    reverse(list);  // call reverse as defined above!
}但同样,这并不适用于您讨论的示例。
因此,总结如下:
没有显式边界的类型参数实际上具有Object界。
方法可能需要类型参数(有或没有显式约束)有两个原因:
reverse示例中所示)。您讨论的示例方法:
public<T>  void run (T obj )..。这两个都不做,所以类型参数是没有意义的。该方法可能与public void run(Object obj)一样被声明。
发布于 2015-08-09 11:12:41
它允许你避免任何的演员.
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
}发布于 2015-08-09 11:11:30
在这种情况下,函数也可以使用Object,但对您来说有意义的变体也等同于public void run(Number obj) { ... }。例如,缺少绑定是有意义的,考虑返回类型提到T:public <T> List<T> singletonList(T obj)的情况。
https://stackoverflow.com/questions/31903492
复制相似问题