4

考虑以下 Employee 类和一个名为 Manager 的子类-

public class Employee
{
    private String name;

    public Employee(String name)
    {
        this.name = name;
    }

    public String getInfo()
    {
        return name;
    }
}

public class Manager extends Employee
{
    public Manager(String name)
    {
        super(name);
    }
}

在另一个类中,我定义了两个函数如下 -

import java.util.ArrayList;

public class WildCardsAndTypeVariables
{
    public static <T extends Employee> void displayInfo(ArrayList<T> employees)
    {
        for (int i=0; i<employees.size(); i++)
        {
                Employee employee = (Employee) employees.get(i);
                System.out.println(employee.getInfo());
        }
    }

    public static void displayInfo2(ArrayList<? extends Employee> employees)
    {
        for (int i=0; i<employees.size(); i++)
        {
                Employee employee = (Employee) employees.get(i);
                System.out.println(employee.getInfo());
        }
    }

    public static void main(String[] args)
    {
    Employee e1 = new Employee("John");
    Employee e2 = new Employee("Joe");
    Employee e3 = new Manager("Joseph");

    ArrayList<Employee> employees = new ArrayList<Employee>();
    employees.add(e1);
    employees.add(e2);
    employees.add(e3);

    displayInfo(employees);
    displayInfo2(employees);
   }
}

我从 displayInfo() 和 displayInfo2() 得到相同的输出。

那么,考虑到这个例子,通配符和类型变量有什么区别呢?

4

3 回答 3

3

在这种情况下,方法只接受一个参数并具有void返回类型,您不会获得任何好处,也不会在通配符类型版本和泛型方法版本之间的语义上产生任何差异。当您在方法签名(参数类型或返回类型)中多次使用类型变量时,泛型方法的真正威力就出现了,一个简单的例子是

public static <T extends Employee> T firstEmployee(ArrayList<T> employees) {
  return employees.get(0);
}

其中说“此方法采用一个 ArrayList,其成员都是Employee(或Employee自身)的某个子类的所有实例,并且它返回的值是同一类的实例”。这是您无法仅使用通配符表达的内容。

于 2012-08-29T21:57:55.633 回答
1

当您使用类型(例如 T)时,您将只能发送特定类型的具体对象。

但是,当您使用通配符时,您正在定义对象的边界。因此,您可以传递 T 类型的对象(或)任何 T 类型的对象。

在你的情况下,你只有 Empoylee,所以差别不大。但是,假设您有扩展 Employee 的类 Contractor。然后你会看到不同之处。

于 2012-08-29T21:28:28.973 回答
0

你的例子有很多问题。

displayInfo2中,您应该使用? extends Employee,因为您正在读取而不是写入Employee传递数组中的对象。例如,如果您想将一个数组传递Manager给该方法,则在您进行此更正之前它不会进行类型检查。

一旦解决了这个问题,您就不需要employees.get()在任何一种方法中都将调用转换为。

不同之处仅在于您TdisplayInfo. Java 中的某些情况要求您为类型命名(我将继续使用链接编辑这篇文章),但在这个特定的示例中,您只需使用通配符就可以了,因为您只关心Employee部分。

于 2012-08-29T21:32:13.200 回答