泛型及其通配符的理解

概述
  • 格式:<大写字母>,例如 < T >
  • 定义:<> 中的字母,泛指一种数据类型,它可以是任意的数据类型,在使用时,为其传入一个类型即可。<> 中的字母可以当一种数据类型,在类里面使用。
  • 优点: 把运行时期的问题提前到了编译期间,在编译期间就会进行类型的检测,避免了强制类型转换。泛型是在JDK5中加入的。
应用
1.泛型类:
  • 写法:类创建完成后,类型就确定了
修饰符 class 类名<类型> { }
  • 示例代码
例如:
public class Person<T> {
	//使用泛型
	private T name;
	public T getT() {
		return t;
	}
	public void setT(T t) {
		this.t = t;
	}
	public static void main(String[] args){
			//传入时就确定T的类型是String
			//Person<String> s = new Person<>();这样写也行
			Person<String> s = new Person<String>();
			s.setT("李白");
			System.out.println(s.getT());
	}
}
2.泛型方法
  • 写法:可以在调用时,传入不同的类型
修饰符 <类型> 返回值类型 方法名(类型 变量名) { }
  • 示例代码
public class Generic{
	public static <T> void paint(T str){
			System.out.println(str);
	}
	public static void main(String[] args){
			Generic.paint(5);
			Generic.paint("你好");
	}
}
3.泛型接口及其实现
  • 写法
修饰符 interface 接口名<类型> { }
  • 示例代码
public interface Genericable<E>{
	void show(T t);
}
  • 接口实现,类一样
//第一个实现
public class Generic implements Genericable<int>{
		public void show(int t){
			System.out.print(t);
		}
}
//第二个
public class Generic2 <E> implements Genericable<E>{
		public void show(E t){
			System.out.print(t);
		}
}
//第三个,不传相关泛型实际变量,当Object,但不可写E
public class Generic2  implements Genericable{
		public void show(Object t){
			System.out.print(t);
		}
}
//错误写法
//当创建了带泛型声明的接口、父类之后,
//可以为该接口创建实现类,或从该父类派生子类,
//但需要指出的是,当使用这些接口、父类时不能再包含类型形参。例如,下面代码就是错误的。将会报错
public class Generic2  implements Genericable<E>{

}
4.类型通配符
一、匹配任何类型
  • <?>: ArrayList<?>: 表示元素类型未知的ArrayList,它的元素可以匹配任何的类型,但是并不能把元素添加到ArrayList中了,获取出来的也是父类类型
  • 下面代码错误的
 List<?> l = new ArrayList<String>();
 //下面代码将报错
 l.add(new Object());
  • 分析:由于<?>是类型通配符,变量l指向的集合里面存储的类型不明确,不能添加。但可以添加null
二、类型通配符上限
  • 类型通配符上限: <? extends 类型>或<? extends T>或<T extends 类型>。
  • ArrayListList <? extends Number>: 它表示的类型是Number或者其子类型
三、类型通配符下限
  • 类型通配符下限: <? super 类型>或 <? super T>或 <T super 类型>
  • ArrayListList <? super Number>: 它表示的类型是Number或者其父类型
通配符示例代码
public class GenericDemo4 {
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
ArrayList<Number> list3 = new ArrayList<>();
ArrayList<Object> list4 = new ArrayList<>();
method(list1);
method(list2);
method(list3);
method(list4);
getElement1(list1);
getElement1(list2);//报错
getElement1(list3);
getElement1(list4);//报错
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
}
// 泛型通配符: 此时的泛型?,可以是任意类型
public static void method(ArrayList<?> list){}
// 泛型的上限: 此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(ArrayList<? extends Number> list){}
// 泛型的下限: 此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(ArrayList<? super Number> list){}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值