泛型
泛型(Generics),是指在类定义时不指定类中信息的具体数据类型,而是暂时用一个标识符来替代,当外部实例化对象的时候,再来指定具体的数据类型。
public class A<T> {
private T b;
}
A<B> a = new A();
A<C> a = new A();
// 改类型的时候不用改源码,方便,
ArrayList<Integer> list = new ArrayList();
// 限制存入的类型
优点:极大的提升程序的灵活性,提升类的扩展性,
约束,避免类型转换之间的问题
泛型可以指代类中:成员变量的数据类型,方法的返回值类型以及方法的参数类型。(可以有多个)
泛型的应用
自定义类中添加泛型
public class 类名<泛型1, 泛型2, ...> {
private 泛型1 属性名;
public 泛型2 方法名(泛型3) {
方法体
}
}
// 例子
public class GenDemo {
public static void main(String[] args) {
Time<Integer> time = new Time();
time.setValue(10);
System.out.println(time.getValue());
Time<String> time2 = new Time();
time2.setValue("十点");
System.out.println(time2.getValue());
}
}
public class Time<T> { // T只是一个名字
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
// 多个泛型的例子
public class Test {
public static void main(String[] args) {
Time<String,Integer,Float> time = new Time<>();
time.setHour("十点");
time.setMinute(10);
time.setSecond(10.0F);
System.out.println(time.getHour()+time.getMinute()+time.getSecond());
}
}
public class Time<H,M,S> {
private H hour;
private M minute;
private S second;
public H getHour() {
return hour;
}
public void setHour(H hour) {
this.hour = hour;
}
public M getMinute() {
return minute;
}
public void setMinute(M minute) {
this.minute = minute;
}
public S getSecond() {
return second;
}
public void setSecond(S second) {
this.second = second;
}
}
泛型用哪个字母都可以,关键是类定义处的字母和类中信息的字母保持一致。
集合中泛型不能使用多态。
泛型通配符
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
test(list1);
test(list2);
}
public static void test(ArrayList<?> list) {
}
ArrayList<?> 表示可以使用任意的泛型类型对象,这样test方法具备通用性了。
泛型的上限和下限
上限:表示实例化时,具体的数据类型,可以是上限类型本身及其子类,用extends表示。
类名<泛型通配符 extends 上限类名>
下限:表示实例化时,具体的数据类型,可以是下限类型本身及其父类,用super表示。
类名<泛型通配符 super 下限类名>
public class Time<T> {
public static void main(String[] args) {
test(new Time<Double>());
test2(new Time<Object>());
}
// 泛型上限
public static void test(Time<? extends Number> time) {
}
// 泛型下限
public static void test2(Time<? super String> time) {
}
}
泛型接口
接口
public interface MyInterface<T> {
public T getValue();
}
注意
public T getValue(); // T代表一个准确的数据类型
public Object getValue2(); // 多态,返回啥都可以
实现泛型接口有两种方式:
-
实现类在定义时,继续使用泛型标识
public class MyInterfaceImpl<T> implements MyInterface{ private T obj; public MyInterfaceImpl(T obj) { this.obj = obj; } @Override public T getValue() { return this.obj; } }
-
实现类在定义时,直接给出具体的数据类型
public class MyInterfaceImpl2 implements MyInterface<String> {
private String obj;
public MyInterfaceImpl2(String obj) {
this.obj = obj;
}
@Override
public String getValue() {
return this.obj;
}
}
使用:
public class Test {
public static void main(String[] args) {
MyInterfaceImpl myInterface = new MyInterfaceImpl<String>("interface");
String val = (String)myInterface.getValue();
MyInterfaceImpl2 anInterface = new MyInterfaceImpl2("interface");
String value = anInterface.getValue();
}
}