说起泛型,不用想,肯定都是用的佛性,可用可不用四舍五入下就是不用。可现实是,你不用,我不用,可总有“别人家的孩子”在用,你说气不气。
为何有了接口,我们还需要使用泛型呢?因为即便使用了接口,对于程序的约束还是太强。因为一旦指明了接口,就会要求我们的代码使用特定的接口,而我们的目的是希望编写出更通用的代码,是要使代码能够应用于某种不确定的类型,而不是一个具体的接口或类。
这是《Java编程思想》说的,可不是我吹的,香不香看了才知道。本文主要涉及下面几个方面的介绍:
泛型类
泛型的目的是用来指定要持有什么类型的对象,而由编译器来保证类型的正确性。使用泛型参数 T,用尖括号括住,放在类后。
public class Tested<T> {
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
}
现有测试类Test1th :
public class Test1th { }
需要Tested持有什么类型的对象,将其放在尖括号内即可。泛型与多态不冲突,所以我们也可以使用其子类。
public void startTest() {
Tested<Test1th> test = new Tested<>();
test.set(new Test1th());
Test1th td = test.get();
}
很简单吧,如果我们需要Tested 持有多个对象呢?来看栗子:
public class Tested<A, B> {
private A a;
private B b;
public void set(A a, B b) {
this.a = a;
this.b = b;
}
public A getA() {
return a;
}
public B getB() {
return b;
}
}
新增测试类Test2th:
public class Test2th { }
在使用时,为A、B 指定类型。当然Tested<A, B> 也支持继承,可以通过Test2ed<A, B, C> extend Tested<A, B>来进行扩展。
public void startTest() {
Tested<Test1th, Test2th> test = new Tested<>();
test.set(new Test1th(), new Test2th());
Test1th tdA = test.getA();
Test2th tdB = test.getB();
}
泛型接口
泛型也可应用于接口。泛型接口与泛型类在使用上相同。这里就拿常见的泛型接口 Iterable< T> 来举例吧,来让Tested<A, B> 具有简单迭代功能。注意在使用泛型接口时,要指定泛型接口的泛型参数类型。其中TestBase见下:
public class TestBase { }
栗子Tested<A, B>见下,也许你也注意到了Iterator< TestBase>,这说明泛型也是可以应用到匿名内部类之上的。
public class Tested<A, B> implements Iterable<TestBase> {
private A a;
private B b;
public Tested(A a, B b) {
this.a = a;
this.b = b;
}
@Override
public Iterator<TestBase> iterator() {
return new Iterator<TestBase>() {
@Override
public boolean hasNext() {
return a != null || b != null;
}
@Override
public TestBase next() {
TestBase tb = null;
if (a instanceof TestBase) {
tb = (TestBase) a;
a = null;
} else if (b instanceof TestBase) {
tb