1. 简单的泛型
1.1 持有任何类型的对象
当你创建Holder对象时,必须指明想持有什么类型的对象,将其置于尖括号内。然后,你就只能在Holder中存入该类型(或其子类,因为多态与泛型不冲突)的对象了。并且,在你从Holder中取出它持有的对象时,自动的就是正确的类型。
public class Holder<T> {
private T a;
public Holder(T a){
this.a = a;
}
public T getA() {
return a;
}
public void setA(T a) {
this.a = a;
}
public static void main(String[] args) {
Holder<Student> holder = new Holder<>(new Student());
Student stu = holder.getA();
}
}
1.2 一次方法调用返回多个对象
一组对象直接打包存储于其中,存储可以是任意不同的类型。不过,我们希望能够为每一个对象指明其类型,并从容器中读取出来时,能够得到正确的类型。
public class TwoTuple<A, B> {
private A first;
private B second;
public TwoTuple(A first, B second) {
this.first = first;
this.second = second;
}
public A getFirst() {
return first;
}
public void setFirst(A first) {
this.first = first;
}
public B getSecond() {
return second;
}
public void setSecond(B second) {
this.second = second;
}
}
public class ThreeTuple<A, B, C> extends TwoTuple<A, B> {
private C third;
public ThreeTuple(A first, B second, C third) {
super(first, second);
this.third = third;
}
public C getThird() {
return third;
}
public void setThird(C third) {
this.third = third;
}
}
public class TupleTest {
public TwoTuple<String, Integer> f(){
return new TwoTuple<>("hi",55);
}
public ThreeTuple<Student, String, Integer> g(){
return new ThreeTuple<>(new Student(), "hi", 66);
}
}
public class TestMain {
public static void main(String[] args) {
TupleTest tupleTest = new TupleTest();
ThreeTuple<Student, Integer, String> threeTuple = tupleTest.g();
Student stu = threeTuple.getFirst();
System.out.println(threeTuple);
}
}
2. 泛型接口
public interface InterfaceTest<T> {
T test();
}
public class InrterfaceImpl implements InterfaceTest<Animal>{
private Class[] types = {Dog.class, Cat.class};
private static Random rand = new Random(47);
@Override
public Animal test() {
try {
return (Animal)types[rand.nextInt(types.length)].newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
3. 泛型方法
类中可以包含参数化方法,而这个方法所在的类可以是泛型类,也可以不是泛型类。也就是说,是否拥有泛型方法,与其所在的类是否是泛型没有关系。
泛型方法基本原则:无论何时,只要你能做到,那么就应该只使用泛型方法,因为它可以使事情更清楚明白。另外,对于一个static的方法而言,无法访问泛型类的类型参数,所以,如果static方法需要使用泛型能力,就必须使其成为泛型方法。
要定义泛型方法,只需将泛型参数列表置于返回值之前:
public class GenericMethods {
public <T> void f(T x){
System.out.println(x.getClass().getSimpleName());
}
public static void main(String[] args) {
GenericMethods gm = new GenericMethods();
gm.f("");
gm.f(1);
gm.f(1.0);
gm.f(1.0F);
gm.f('c');
gm.f(gm);
}
}
String
Integer
Double
Float
Character
GenericMethods