泛型、可变参数
1 泛型<>
泛型概述:
- 本质:参数化类型
- 例如原来函数定义的形参,被规定成一个具体的数据类型。那么调用该函数时就只能传入该类型的实参。泛型即将原来具体的类型参数化,然后再调用、使用时再传入具体的类型。
- 定义格式
<类型> // 指定一种类型的格式,这里的类型可以看作是形参
<类型1,类型2,...> // 指定多种类型的格式,多种类型之间用逗号隔开,这里的类型也可以看作形参。
- 可以用在类、方法、接口中。分别称为泛型类、泛型方法、泛型接口
泛型类
实例化类的时候指明泛型的具体类型(也可以不指定)
// 定义泛型类
public class Generic<T> {
private T t;
// 定义设置和访问私有成员的两个方法
public void setT(T t){
this.t = t;
}
public T getT(){
return t;
}
}
// 创建泛型类的对象
public class GenericTest {
public static void main(String[] args) {
Generic<String> generic = new Generic<>(); // 泛型T被指定为String,也可以不传入实参
generic.setT("泛型");
System.out.println(generic.getT());
Generic<Integer> generic1 = new Generic<>();
generic1.setT(23);
System.out.println(generic1.getT());
}
}
泛型方法
调用方法的时候指明泛型的具体类型(也可以不指定)
// 定义泛型方法
public <E> void print(E e){
System.out.println(e);
}
调用方法时不用指定类型。
泛型接口
// 泛型接口定义格式
public interface Generic<T>{
}
// 泛型接口实现类定义格式
public class GenericImpl<T> implements Generic{
}
2 类型通配符(泛型通配符)<?>
问题背景
String类是Object的子类。
但是对于List<T>
泛型两个传入“实参”后的类:List<String>
类不是List<Object>
的子类
类型通配符
使用?代替具体的类型实参。可以把?看成所有类型的父类。可以解决当具体类型不确定的时候,这个通配符就是 ? ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。
类型通配符的上限
- 如果我门不希望List<?>是任何泛型List的父类,只希望它代表某一类泛型List的父类,可以使用类型通配符的上限
- <?extends类型>
- List<?extends Number>:它表示的类型是Number或者其子类型
类型通配符的下限
- List<?super Number>: 它表示的类型是Number或者其父类型
3 可变参数 …
方法参数个数可变
public class ArgsDome {
public static int sum(int ... a){
int s = 0;
for(int i:a){
s = s+i;
}
return s;
}
public static void main(String[] args) {
System.out.println(sum(1,3,6,7));
}
}
注意事项:
- a其实是一个数组
- 如果一个方法有多个参数,包含可变参数,可变参数要放在最后