关于通配符 Pair 的疑问

口香糖先森 2014-06-19 12:15:41
先上两个JAVA文件:
Pair.java

public class Pair<T>
{
public Pair() { first = null; second = null; }
public Pair(T first, T second) { this.first = first; this.second = second; }

public T getFirst() { return first; }
public T getSecond() { return second; }

public void setFirst(T newValue) { first = newValue; }
public void setSecond(T newValue) { second = newValue; }

private T first;
private T second;
}

PairTest3.java

public class PairTest3
{
public static void main(String[] args)
{
Manager ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15);
Manager cfo = new Manager("Sid Sneaky", 600000, 2003, 12, 15);
Pair<Manager> buddies = new Pair<Manager>(ceo, cfo);
printBuddies(buddies);

ceo.setBonus(1000000);
cfo.setBonus(500000);
Manager[] managers = { ceo, cfo };

Pair<Employee> result = new Pair<Employee>();
minmaxBonus(managers, result);
System.out.println("first: " + result.getFirst().getName()
+ ", second: " + result.getSecond().getName());
maxminBonus(managers, result);
System.out.println("first: " + result.getFirst().getName()
+ ", second: " + result.getSecond().getName());
}

public static void printBuddies(Pair<? extends Employee> p)
{
Employee first = p.getFirst();
Employee second = p.getSecond();
System.out.println(first.getName() + " and " + second.getName() + " are buddies.");
}

public static void minmaxBonus(Manager[] a, Pair<? super Manager> result)
{
if (a == null || a.length == 0) return;
Manager min = a[0];
Manager max = a[0];
for (int i = 1; i < a.length; i++)
{
if (min.getBonus() > a[i].getBonus()) min = a[i];
if (max.getBonus() < a[i].getBonus()) max = a[i];
}
result.setFirst(min);
result.setSecond(max);
}

public static void maxminBonus(Manager[] a, Pair<? super Manager> result)
{
minmaxBonus(a, result);
PairAlg.swapHelper(result); // OK--swapHelper captures wildcard type
}
}

class PairAlg
{
public static boolean hasNulls(Pair<?> p)
{
return p.getFirst() == null || p.getSecond() == null;
}

public static void swap(Pair<?> p) { swapHelper(p); }

public static <T> void swapHelper(Pair<T> p)
{
T t = p.getFirst();
p.setFirst(p.getSecond());
p.setSecond(t);
}
}

class Employee
{
public Employee(String n, double s, int year, int month, int day)
{
name = n;
salary = s;
GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
hireDay = calendar.getTime();
}

public String getName()
{
return name;
}

public double getSalary()
{
return salary;
}

public Date getHireDay()
{
return hireDay;
}

public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}

private String name;
private double salary;
private Date hireDay;
}

class Manager extends Employee
{
/**
@param n the employee's name
@param s the salary
@param year the hire year
@param month the hire month
@param day the hire day
*/
public Manager(String n, double s, int year, int month, int day)
{
super(n, s, year, month, day);
bonus = 0;
}

public double getSalary()
{
double baseSalary = super.getSalary();
return baseSalary + bonus;
}

public void setBonus(double b)
{
bonus = b;
}

public double getBonus()
{
return bonus;
}

private double bonus;
}

我将PairTest3.java的第14行代码
Pair<Employee> result = new Pair<Employee>();

中的类型换成Manager, 为何也不报错,而且能正常运行呢? 它不是要求的是Manager的父类么
...全文
323 13 打赏 收藏 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
lliiqiang 2014-06-26
  • 打赏
  • 举报
回复
要看本质,关键在于它是语法糖果,是转换为需要类型时强制类型转换才做类型验证.
口香糖先森 2014-06-23
  • 打赏
  • 举报
回复
引用 11 楼 qqhw123 的回复:
[quote=引用 8 楼 sparic 的回复:] [quote=引用 6 楼 qqhw123 的回复:] 你理解下面这个,你就清楚了。 Employee ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15);
这个不就是让一个Employee对象的指针指向它的子类Manager的一个对象么,跟我那个问题有什么联系,求大师点拨下[/quote] 你定义的 public static void maxminBonus(Manager[] a, Pair<? super Manager> result) 后面的参数的 Manager的父类 也就是Employee 。 如果调整一下这样方法定义,可以是:public static void maxminBonus(Manager[] a, Pair<Employee > result) 而我说的Employee ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15) 定义的对象ceo类型为Employee,所以这样是可以作为参数调用maxminBonus方法。 而实际new的为Manager,所以ceo的实际类型为Manager。而ceo是可以作为参数调用maxminBonus方法。 因此一个Manager的对象是可以作为参数调用maxminBonus方法的,所以你上面的都没问题。 [/quote] 我明白你的意思了,不过感觉你只是讲出了结果,并没有讲为什么会这样,我觉得10楼的兄弟讲出了原因。
shine333 2014-06-19
  • 打赏
  • 举报
回复
泛型中的super 还有 extends关键字,类似>= / <= 而不是你理解的 >/<,也就是包括自身的 这两个关键字的作用super往往是让你传数据给他,extends往往是让你从中获得数据 以List举例: List<? super Child> list通常是用来往里面放东西,由于具体类型可能是Child或者某一个Child的父类型(Parent, GrandParent, ... Object),所以必定能够得出这样结论list.add(new Child());(至少在语法上)是合法,安全的。 List<? extends Parent> list通常是从中读取,由于具体类型可能是Parent或者任何一个它的子类型(Child或者GrandChild...),所以必定能够得出这样的结论:Parent x = list.get(0);(至少在语法上)是合法,安全的。
口香糖先森 2014-06-19
  • 打赏
  • 举报
回复
引用 7 楼 lliiqiang 的回复:
是子类没有问题啊。这是语法糖果,真正对应着一个语法规则.
你的意思是说<? super Manager>这个语法规则是既可以放Manager的父类也可以放Manger本身的是么
口香糖先森 2014-06-19
  • 打赏
  • 举报
回复
引用 6 楼 qqhw123 的回复:
你理解下面这个,你就清楚了。 Employee ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15);
这个不就是让一个Employee对象的指针指向它的子类Manager的一个对象么,跟我那个问题有什么联系,求大师点拨下
lliiqiang 2014-06-19
  • 打赏
  • 举报
回复
是子类没有问题啊。这是语法糖果,真正对应着一个语法规则.
qqhw123 2014-06-19
  • 打赏
  • 举报
回复
你理解下面这个,你就清楚了。 Employee ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15);
口香糖先森 2014-06-19
  • 打赏
  • 举报
回复
引用 4 楼 zhouren1314 的回复:
只要编译能通过,那么这种方式就是可行的,没有为什么。。
乔不思 2014-06-19
  • 打赏
  • 举报
回复
只要编译能通过,那么这种方式就是可行的,没有为什么。。
乔不思 2014-06-19
  • 打赏
  • 举报
回复
实践才是真理,
口香糖先森 2014-06-19
  • 打赏
  • 举报
回复
引用 1 楼 zhouren1314 的回复:
就是啊,就是Manage的父类啊,你写的 class Manage extends Employee{ ..... }
你没理解我意思啊 我写的是Manager 是 Employee的子类 但在
Pair<Employee> result = new Pair<Employee>();
里,我把Employee换成Manager
Pair<Manager> result = new Pair<Manager>();
也没有任何问题,不是应该只能用Employee的么,为什么用Manger自己本身也可以啊
乔不思 2014-06-19
  • 打赏
  • 举报
回复
就是啊,就是Manage的父类啊,你写的 class Manage extends Employee{ ..... }
qqhw123 2014-06-19
  • 打赏
  • 举报
回复
引用 8 楼 sparic 的回复:
[quote=引用 6 楼 qqhw123 的回复:] 你理解下面这个,你就清楚了。 Employee ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15);
这个不就是让一个Employee对象的指针指向它的子类Manager的一个对象么,跟我那个问题有什么联系,求大师点拨下[/quote] 你定义的 public static void maxminBonus(Manager[] a, Pair<? super Manager> result) 后面的参数的 Manager的父类 也就是Employee 。 如果调整一下这样方法定义,可以是:public static void maxminBonus(Manager[] a, Pair<Employee > result) 而我说的Employee ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15) 定义的对象ceo类型为Employee,所以这样是可以作为参数调用maxminBonus方法。 而实际new的为Manager,所以ceo的实际类型为Manager。而ceo是可以作为参数调用maxminBonus方法。 因此一个Manager的对象是可以作为参数调用maxminBonus方法的,所以你上面的都没问题。

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧