/**
* 看看下面的代码,使用类型参数T定义了一个max局部变量,这就意味着max可以是任意类型的
* 那么max.compareTo(array[i])方法的调用的前提是T所属的类中有compareTo方法
* 可以对这个代码进行改善
*/
public class WildCard {
public static <T>T max(T[] array) {
if ( null == array || 0 == array.length) {
return null;
}
T max = array[0];
for (int i = 1; i < array.length; i++) {
if (max.compareTo(array[i]) < 0) {max = array[i];}
}
return max;
}
}
/**
* 看看下面的代码,使用类型参数T定义了一个max局部变量,这就意味着max可以是任意类型的
* 那么max.compareTo(array[i])方法的调用的前提是T所属的类中有compareTo方法
* 我们定义类型参数的变化,<T extends Comparable<T>>这里将T类型限定在Comparable
* 及其所有的子类,可是这里Comparable是一个interface,为什么这里用extends呢?
*
* <T extends Bounding type>表示T类型应该是绑定类型及其子类型subtype,T和绑定类型可以是类或者接口
* 使用extends是因为它更接近子类的概念
*/
public class WildCard {
public static <T extends Comparable<T>>T max(T[] array) {
if ( null == array || 0 == array.length) {
return null;
}
T max = array[0];
for (int i = 1; i < array.length; i++) {
if (max.compareTo(array[i]) < 0) {max = array[i];}
}
return max;
}
}
import java.io.Serializable;
import java.util.ArrayList;
/**
* 如果限定T为class的时候,就有一个非常严格的规则,这个class智能放在第一个,最多只能有一个class
* 这样一来就能够严格控制T类型是单继承的,遵循Java规范
*
* 1) 类型限定只能限定某个类型及其子类,使用关键字extends;
* 2) 多个类型参数用逗号分隔,多个限定类型用&隔开
* 3) 限定interface的时候,对interface的个数和顺序无严格要求,限定class的时候,则需要
* 将class类型置于第一个位置,且最多只能存在一个class类型
*
*/
public class WildCard {
public static <T extends ArrayList &Runnable &Serializable> T max(T[] array) {
return null;
}
}
/**
* 面向接口编程,而非面向过程编程,这个设计原则,方法调用通过高层的抽象类或者接口来进行,具体调用的方法体
* 就是我们实际运行时期传递的具体实现类的实例,这也是多态的一种体现,我们就需要通过子类来调用方法,而调用
* 的方法体现这个类的超类的实例,继承结构越往上就可能是abstract的,或是interface,抽象类和接口是无法
* 实例化的,这种反设计让调用面临失败,一旦限定的这个类就是抽象的或是接口,这个会造成这个泛型类或泛型方法
* 无法使用,导致设计失败;
*
* 所以public static <T super Runnable> void test(T runner) 这是行不通的
* 这种功能可以通过泛型中的通配符来得到解决;
* 通配符类型,相比于固定的泛型类型,它是一个巧妙的解决方案::
*
* 表示Couple的泛型类型是Employee或者子类,Couple<Manager>满足,而Couple<File>不满足
* 使用同配置?来表示::
*/
public class WildCard {
// The type T is not generic; it cannot be parameterized with arguments <? extends Employee>
// ? extends Employee 自身不能单独使用,可以理解为只能寄生在其他泛型类中,作为泛型类一个具体的类型参数,通常用于定义阶段
// public class Couple<T>
// public static ? extends Employee {....} (错误)
// 使用通配符来定义方法返回值和方法的参数类型在Java中是不允许的!!!
// 和前面子类型的限定一样,用?表示通配符,它的存在必须存在泛型类的类型参数中Couple<? super Manager>
public static <T extends ArrayList &Runnable &Serializable> T max(Couple<? extends Employee> couple) {
Employee wife = couple.getWife();
return null;
}
}
/**
* 泛型参数的限定,使用extends 关键字,限定多个类型时候用&隔开,如<T extends Runnable& Serializable>
* 泛型参数限定中,如果限定的类型是class而不是interface,则class必须放在限定类表中的第一个,且最多只能存在一个class
* 通配符只能用在泛型类的泛型参数中,不能单独使用
* Couple<?> Couple<? extends Employee> Couple<? super Manager>
* 通配符的超类型限定适用于写入,通配符的子类型限定适用于读取,无限定通配符使用一些非null判断等简单操作
*/
public class WildCard {
public static <T extends ArrayList &Runnable &Serializable> T max(Couple<? extends Employee> couple) {
Employee wife = couple.getWife();
return null;
}
public void callWildcard()
{
WildCard.max(null);
}
}