前面学习了java泛型类,这里再来说一下带有类型参数的简单方法:
泛型方法。。
public class ArrayAlg1 {
public static <T> T getMiddle(T...a)
{
return a[a.length/2];
}
String middle = ArrayAlg1.<String>getMiddle("John", "Q","Public");
String middle1 = ArrayAlg1.getMiddle("sdj", "asdjl","gsak");
// String middle2 = ArrayAlg1.getMiddle(3.14,1323,0);
}
这个方法是在普通类中定义的,不是在泛型类中定义的,
但它是一个泛型方法,从尖括号可以看出来,
类型变量放在修饰符(public static)的后面,返回类型的前面。
泛型方法可以定义在一个普通类里,也可以定义在泛型类里。
但调用一个泛型方法时,在方法名前的尖括号里放入具体的类型:
String middle = ArrayAlg1.<String>getMiddle("John", "Q","Public");
这种情况下<String>参数类型可以省略,编译器有足够的信息能够推断出所调用的方法:
String middle1 = ArrayAlg1.getMiddle("sdj", "asdjl","gsak");
还有错误情况:
String middle2 = ArrayAlg1.getMiddle(3.14,1323,0);
编译器将会自动打包参数为1个double和2个Integer,然后寻找这些共同的超类型。
找到2个这样的超类型:Number和Comparable接口,其本身也是泛型类,此情况下可以将所有参数改为double类型。
Error:(16, 41) java: 不兼容的类型: 推断类型不符合上限
推断: java.lang.Number&java.lang.Comparable<? extends java.lang.Number&java.lang.Comparable<?>>
上限: java.lang.String,java.lang.Object
类型变量的设定
有时,类或方法需要对类型变量加以约束。
public class ArrsyAlg3 {
public static <T > void min(T[] a){
if(a == null || a.length == 0) {
return null;
}
T smallest = a[0];
for(int i = 1; i < a.length; i++)
if (smallest.compareTo(a[i]) > 0)
smallest = a[i];
return smallest;
}
}
变量smallest为T类型,这意味着它可以是任何一个类的对象,那么怎么
确信T所属的类有CompareTo方法呢?
此时将T限制为Comparable接口(只含一个方法CompareTo的标准接口)的类。
public static <T extends Comparable> void min(T[] a)
实际上Comparable接口本身就是一个泛型类。
但现在,泛型的min方法只能被实现Comparable接口的类(如:String, LocalData等)的数组调用。由于Rectangle类没有实现Comparable接口所以调用min会出现一个编译错误。。
至于用extends而不用implements因为:
Comparable是一个接口
记法:<T extends BoundingType>
表示T应该是绑定类型的子类型,T和去绑定的类型可以是类,也可以是接口。
用extends是因为更接近子类的概念。
一个变量或通配符有多个限定,::
T extends Comparable & Serializable
限定用 & 分隔开,用 , 逗号分隔类型变量。
在java继承中,可以根据拥有多个接口超类型,但限定至多有一个类。
如果用一个类作为限定,它必须是限定列表中的第一个。