1.为什么需要泛型
将运行时检查提前到编译时检查
类型参数化
减少了数据类型转换,消除了强制类型转换
达到代码复用的目的
2.泛型类
package com.miao.demo.generic;
public class GenericDemo {
public static void main(String[] args) {
// 泛型类在创建对象时指定具体数据类型
Generic<String, Integer> generic = new Generic<String, Integer>("abc", 5);
generic.read();
System.out.println("============================");
Generic<Double, Boolean> generic2 = new Generic<Double, Boolean>(5.5, true);
generic2.read();
System.out.println("============================");
// 创建对象时未指定类型将按照Object类型操作
Generic generic3 = new Generic(5, "ok");
Object key3 = generic3.getKey1();// key3默认为Object类型
generic3.read();
System.out.println("============================");
// Generic<int ,boolean> generic4=new Generic(5, true);
// 错误,泛型类不支持基本数据类型
System.out.println("============================");
//同一泛型类,根据不同数据类型创建的对象,本质上是同一类型
//也就是说在逻辑上可以看成不同的类型,实际上是相同的类型
System.out.println(generic.getClass());
System.out.println(generic2.getClass());
System.out.println(generic.getClass() == generic2.getClass());
}
}
class Generic<E, T> {
private E key1;
private T key2;
public E getKey1() {
return key1;
}
public void setKey1(E key1) {
this.key1 = key1;
}
public T getKey2() {
return key2;
}
public void setKey2(T key2) {
this.key2 = key2;
}
public Generic(E key1, T key2) {
super();
this.key1 = key1;
this.key2 = key2;
}
public void read() {
System.out.println("key1:" + key1 + "\nkey2:" + key2);
}
}
3.从泛型类派生子类
注意:若子类是泛型类,则父类标识符必须包含于子类,因为父类类型需通过子类确定,因此当子类不是泛型时,父类类型必须明确,否则,父类类型仍不可确定,
package com.miao.demo.generic;
public class GenericDemo {
public static void main(String[] args) {
GenericFather<Integer> genericFather = new GenericFather<Integer>(5);
genericFather.read();
GenericSon<Integer> genericSon = new GenericSon<Integer>(5);
genericSon.read();
GenericSon1 genericSon1 = new GenericSon1("类型必须明确");
genericSon1.read();
}
}
class GenericFather<T> {
private T key;
public GenericFather(T key) {
this.key = key;
}
public T getKey() {
return key;
}
public void setKey(T key) {
this.key = key;
}
public void read() {
System.out.println(key);
}
}
//若子类与父类都是泛型,则父类标识符必须包含于子类标识符
class GenericSon<T> extends GenericFather<T> {
public GenericSon(T key) {
super(key);
}
@Override
public void read() {
System.out.println("若子类与父类都是泛型,则子类和父类标识符必须一致" + super.getKey());
}
}
//若子类不是泛型,则父类标识必须明确
class GenericSon1 extends GenericFather<String> {
public GenericSon1(String key) {
super(key);
// TODO Auto-generated constructor stub
}
@Override
public void read() {
System.out.println("若子类不是泛型,则父类标识必须明确" + super.getKey());
}
}
4.泛型接口
package com.miao.demo.generic;
public class GenericInterface {
public static void main(String[] args) {
//
//
}
}
interface GenericInterfaceDemo<T,E>{
T read(E x);
}
//若实现类不是泛型类,接口类型必须指明,原因同继承
class GenericInterfaceDemoImpl implements GenericInterfaceDemo<String,String>{
@Override
public String read(String x) {
return x;
}
}
//同样,若实现类是泛型类,则接口类型标识符必须包含于实现类标识符
class GenericInterfaceDemoImpl1<T,E> implements GenericInterfaceDemo<T,E>{
@Override
public T read(E x) {
// TODO Auto-generated method stub
return null;
}
}
5泛型方法
package com.miao.demo.generic;
public class GenericMethod {
public static void main(String[] args) {
GenericMethodDemo genericMethod = new GenericMethodDemo();
genericMethod.method(5);
genericMethod.method(5.5);
genericMethod.method("ok");
}
}
class GenericMethodDemo {
//注意标识符位置
public <T> void method(T t) {
System.out.println(t);
}
}
6.通配符
通配符上限?extends 实参类型
通配符上限?super 实参类型
7.擦除