云南网站建设运营,北京网站开发公司电话,好的网站有哪些,微信小程序公众平台【0】README
0.1#xff09; 本文描述源代码均 转自 core java volume 1#xff0c; 旨在理解 java泛型程序设计 的 通配符类型通配符的超类型限定 的知识#xff1b; 【1】通配符类型相关
1.1#xff09;通配符类型#xff1a; Pair ? extends Employee 表示…【0】README
0.1 本文描述源代码均 转自 core java volume 1 旨在理解 java泛型程序设计 的 通配符类型通配符的超类型限定 的知识 【1】通配符类型相关
1.1通配符类型 Pair ? extends Employee 表示任何泛型Pair 类型 它的类型参数是 Employee的子类 如 Pair 但不是 Pair 1.2问题解决方法
1.2.1问题假设要编写一个打印雇员对的方法 如
public static void printBuddies(PairEmployee p)
{Employee first p.getFirst();Employee second p.getSecond();System.out.println(first.getName() second.getName());
}
正如前面讲到的 不能将 Pair Manager 传递给这个方法 这一点很受限制 因为 Pair Manager 不是 Pair Employee 的子类 它们两个根本就没有半毛钱关系的1.2.2解决方法使用通配符类型
public static void printBuddies(Pair? extends Employee p)
因为 类型 Pair Manager是 Pair ? extends Employee 的 子类型如下图
1.3使用通配符会通过Pair ? extends Employee 的引用破坏Pair Manger 吗
1.3.1看个荔枝
PairManager m new Pair(ceo, cfo);
Pair? extends Employee m2 m1; //OK
m2.setFirst(lowlyEmployee); // compile-time error
1.3.2 这可能不会引起破坏。 对 setFirst的调用有一个类型错误。 要了解其中的缘由 请仔细看一看类型 Pair ? extends Employee , 其方法似乎是这样的
? extends Employee getFirst()
void setFirst(? extends Employee)
1.3.3这样将不可能调用 setFirst 方法。 编译器只知道 需要某个 Employee 的子类型 但不知道具体是 什么类型。 它拒绝传递任何特定的类型 毕竟 不能用来匹配1.3.4使用 getFirst 就不存在这个问题将 getFirst 的返回值赋给一个 Employee 的引用完全合法。 这就是引入有限定的通配符的关键之处 【2】通配符的超类型限定
2.1超类型限定 如下所示
? super Manager 这个通配符限制为 Manager 的所有超类型。
2.1.1为什么要这样做呢 带有超类型的通配符行为可以为 方法提供参数 但不能使用 返回值
如 Pair? super Manger 有方法
void setFirst(? super Manager)
? super Manger getFirst();
编译器不知道setFirst 方法的确切类型 但是可以用任意Manger对象调用它 而不能用 Employee对象调用。 然而 如果调用 getFirst 返回的对象类型就不会得到保证 只能吧它赋给一个 Object
2.2看个荔枝 有一个经理的数组并且想把 奖金最高和最低的经理放在一个 Pair 对象中。
2.2.1Pair 的类型是什么 在这里 Pair Employee 是合理的 Pair Object 也是合理的 下面的方法将可以接收任何适当的Pair
2.3干货总结 直观地讲带有超类型限定的通配符可以向泛型对象写入 带有子类型限定的通配符可以从泛型对象读取
2.3.1看个荔枝 下面是超类型限定的另一种应用。 Comparable接口本身就是一个泛型类型如下
public interface ComparableT
{public int compareTo(T other);
}
2.3.2 由于 Comparable是一个泛型类型 也许可以吧 ArrayAlg 类的min 方法做的更好一些可以这样声明
public static T extends ComparableT T min(T[] a)
看起来 这样写比只使用T extends Comparable 更彻底 并且对于许多类来讲 工作得更好。例如 如果计算一个String 数组的最小值 T就是String 类型的 而 String 是 Comparable String 的子类型。 2.3.3出现的问题 当处理一个Gregorian Calender 对象的数组时 就会出现问题 GregorianCalendar 是 Calendar 的子类 并且 Calendar 实现了 Comparable Calendar 因此 GregorianCalendar实现的是Comparable Calendar 而不是 Comparable GregorianCalendar2.3.4解决方法使用超类型
public static T extends Comparable? super T T min(T[] a)
现在compareTo 方法写成 int compareTo(? super T)有可能被声明为 使用类型T的对象 也有可能使用T 的超类型如当T是 GregorianCalendar 无论如何 传递一个 T 类型的对象给 compareTo 方法都是安全的
Conclusion
C1对于新手来说 T extends Comparable ? super T 这样的声明看起来有点吓人C2因为 这一声明的意图在于帮助应用程序员排除调用参数上的不必要的限制C3对泛型没有兴趣的coders 很可能很快就学会掩盖这些声明了 想当然地认为库程序员做的都是正确的C4如果是一名库程序员 一定要习惯于通配符 否则 就会受到用户的责备 还要在代码中随意地添加强制类型转换直到代码可以编译