产生泛型的原因

​ 由于Object可以接收所有类型的参数,当使用object接收参数时,如果将接收到的参数进行向下转型,则可能会出现java.lang.ClassCastException,并且在编译时不会有任何报错,导致重大安全隐患

​ 如果想要避免java.lang.ClassCastException,最好的做法就是回避掉强制类型转换。泛型的本质就在于类中的属性或方法参数与返回值类型可以由对象实例化的时候动态决定

​ 由于泛型属于JDK1.5之后的设计,为了保证之前的程序在追加泛型之后还能正常使用,所以在不设置泛型类型时,自动的使用Object作为类型保证程序正常运行

泛型示例:

public class Main {
    public static void main(String[] args) {
       Point<Integer> p1 = new Point<>(20,50);
        System.out.println("("+p1.getX()+","+p1.getY()+")");
    }
}
//里面的T和上面声明的T会保持一致
class Point <T>{
    private final T x;
    private final T y;

    Point(T x, T y) {
        this.x = x;
        this.y = y;
    }

    public T getX(){
        return this.x;
    }
    public T getY() {
        return this.y;
    }
}

注意:

  • 泛型之中只允许设置引用类型,使用基本类型必须使用包装类
  • 从JDK1.7开始泛型对象实例化后面<>中的内容可以省略 ,例如:Point<Integer> p1 = new Point<Integer>(20,50);

可以省略未:Point<Integer> p1 = new Point<>(20,50);

泛型通配符

如果方法不设置泛型,那方法可能会对你的泛型类内部数据进行修改,如果不允许方法对你的泛型进行修改,只允许获取,则可以使用通配符<?>

public class Main {
    public static void main(String[] args) {
       Point<Integer> p1 = new Point<>(20,50);
        printPoint(p1);
    }
    public static void printPoint(Point<?> point){
        System.out.println("("+point.getX()+","+point.getY()+")");
    }
}

class Point <T>{
    private final T x;
    private final T y;
    Point(T x, T y) {
        this.x = x;
        this.y = y;
    }

    public T getX(){
        return this.x;
    }
    public T getY() {
        return this.y;
    }
}

<?>通配符扩展:

​ 设置通配下限:

​ 设置通配上限:用<T super type>,写入类型必须是type以及他的子类型

​ 设置通配上限:用<T extends type>,写入类型必须是type以及他的父类型

class Point <T extends String>{
    private final T x;
    private final T y;

    Point(T x, T y) {
        this.x = x;
        this.y = y;
    }

    public T getX(){
        return this.x;
    }
    public T getY() {
        return this.y;
    }
}

泛型接口

泛型接口实现一:

在实现接口的类中继续使用泛型

public class Main {
    public static void main(String[] args) {
        Imessage<String> ImessageClass = new ImessageClass<String>();
        System.out.println(ImessageClass.echo("喵喵"));
    }

}
//实现泛型的接口
interface Imessage<T>{
    public String echo(T message);
}
//实现类
class ImessageClass<T> implements Imessage<T>{
    @Override
    public String echo(T message) {
        return "[echo]"+message;
    }
}

泛型接口实现二:

​ 在实现接口的类中直接指定泛型的类型

public class Main {
    public static void main(String[] args) {
        Imessage<String> ImessageClass = new ImessageClass();
        System.out.println(ImessageClass.echo("喵喵"));
    }

}
//实现泛型的接口
interface Imessage<T>{
    public String echo(T message);
}
//实现类
class ImessageClass implements Imessage<String>{
    @Override
    public String echo(String message) {
        return "[echo]"+message;
    }
}

泛型方法

泛型方法不一定出现在泛型类中

    public static void main(String[] args) {
        Integer[] a = func(1, 2, 3, 4, 5);
        for (int b : a)
            System.out.println(b);
    }

    @SafeVarargs
    public static <T> T[] func(T... args) {
        return args;
    }
}
最后修改:2021 年 04 月 27 日
如果觉得我的文章对你有用,请随意赞赏