Java中的泛型

一、总结

1.泛型: 使用通配符来表示具体的类型。

2.泛型中的T表示的是类,而不能是基本数据类型,如int.

3.泛型做参数时,使用"类<?>",?是统配符,来接收此泛型的所有实例化对象或泛型的子类/接口实例化的对象。其它普通类的对象不能赋值。

4.报错的信息中CAP#1是一个泛型

5.Person<?>应该表示一个实例化过的泛型对象
public static void printInfo(Person<?> p)

6.在方法里面也可以使用泛型,参数为T,但是需要在函数签名前加<T>表示T是泛型而不是一个具体的类,eg:
public static <T> void printInfo2(Person<T> p) { }

7.子类继承也可以继续使用泛型或不使用

8.接口也可以使用泛型,可以认为接口就是一种特殊的父类

9.受限泛型
在定义一个泛型的时候指定其上限和下限。指定上限就是泛型T只能是某个类或其子类,指定下限就是泛型T只能是某个类或者是其父类。定义泛型时使用extends来指定上限,使用super来指定下限。
eg:指定上限,要求这些类都是来源于Number类或Number类的子类

class Student<T extends Number> implements Persion<T> {
}

eg:指定下限,要求实例化对象都是String类或String类的父类。它是在成员方法中指定的

// 只能接收实例化为String或Object类型的对象(String类的父类只有Object类)
public static void printinfo(Persion<? super String> p) {
}

函数接收参数时:
使用 "<?>" 可以接收任意泛型对象。泛型的上限:<? extends 类型>  泛型的下限:<? super 类型>

10.Class<T>与Class<?>的区别

Class类的实例表示Java应用运行时的类或接口(每个Java类运行时都在JVM里表现为一个Class对象,可通过类名.class,类型.getClass()
Class.forName("类名")等方法获取Class对象)。
数组同样也被映射为为Class对象的一个类,所有具有相同元素类型和维数的数组都共享该Class对象。
基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为Class对象。

T bean;
Class<T> bean;
Class<?> bean;
单独的T代表一个类型,而Class<T>和Class<?>代表这个类型所对应的类

Class<T>在实例化的时候,T要替换成具体类
Class<?>它是个通配泛型,?可以代表任何类型

<? extends T>受限统配,表示T的一个未知子类。
<? super T>下限统配,表示T的一个未知父类。

Object类中包含一个方法名叫getClass,利用这个方法就可以获得一个实例的类型类。类型类指的是代表一个类型的类,因为一切皆是对象,
类型也不例外,在Java使用类型类来表示一个类型。所有的类型类都是Class类的实例。getClass()会看到返回Class<?>。

JDK中,普通的Class.newInstance()方法的定义返回Object,需要要将该返回类型强制转换为另一种类型;

二、试验例子

1.泛型实例化使用

interface Person<T> {
    public void setAge(T age);
    public T getAge();
}

class Student<T> implements Person<T> {
    T age;
    public void setAge(T age)
    {
        this.age = age;
    }
    public T getAge() {
        return this.age;
    }
}

class Student2 implements Person<String> {
    String age;
    public void setAge(String age)
    {
        this.age = age;
    }
    public String getAge() {
        return this.age;
    }
}

public class Generics5 {
    public static void main(String args[]) {
        Student<Integer> s = new Student<Integer>();
        s.setAge(10);
        printInfo(s);

        Student2 s2 = new Student2();
        s2.setAge("11 years"); //also ok
        printInfo(s2);
        printInfo2(s2);
    }

    public static void printInfo(Person<?> p) {
        System.out.println(p.getAge());
    }

    public static <T> void printInfo2(Person<T> p) {
        System.out.println(p.getAge());
    }

}

/*
$ java Generics5 
10
11 years
11 years
*/

2.上限泛型

interface Person<T> {
    public void setAge(T age);
    public T getAge();
}

/* Integer, Float */
class Student<T extends Number> implements Person<T> {  /*指定上限*/
    T age;
    public void setAge(T age)
    {
        this.age = age;
    }
    public T getAge() {
        return this.age;
    }
}

class Student2 implements Person<String> {
    String age;
    public void setAge(String age)
    {
        this.age = age;
    }
    public String getAge() {
        return this.age;
    }
}

public class Generics6 {
    public static void main(String args[]) {
        Student<Integer> s = new Student<Integer>();
        s.setAge(10);
        printInfo(s);

        Student2 s2 = new Student2();
        s2.setAge("11 years");
        printInfo(s2);

    }

    public static void printInfo(Person<?> p) {
        System.out.println(p.getAge());
    }

    
    public static <T> void printInfo2(Person<T> p) {
        System.out.println(p.getAge());
    }

}

3.下限泛型

interface Person<T> {
    public void setAge(T age);
    public T getAge();
}

class Student<T> implements Person<T> {
    T age;
    public void setAge(T age)
    {
        this.age = age;
    }
    public T getAge() {
        return this.age;
    }
}

class Student2 implements Person<String> {
    String age;
    public void setAge(String age)
    {
        this.age = age;
    }
    public String getAge() {
        return this.age;
    }
}

public class Generics {
    public static void main(String args[]) {
        Student<String> s = new Student<String>();
        s.setAge("10");
        printInfo(s);

        Student2 s2 = new Student2();
        s2.setAge("11 years");
        printInfo(s2);

    }

    public static void printInfo(Person<? super String> p) { /*指定下限*/
        System.out.println(p.getAge());
    }

    
    public static <T> void printInfo2(Person<T> p) {
        System.out.println(p.getAge());
    }

}
原文地址:https://www.cnblogs.com/hellokitty2/p/10428347.html