java 什么是泛型?泛型有啥作用?

162 阅读3分钟

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战

泛型

我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成 Object类型。当我们在取出每⼀个对象,并且进⾏相应的操作,这时必须采⽤类型转换。没有泛型的话,取出来的话,需要向下转型,效率低下。容易产⽣错误。
泛型:保护数据类型的安全
语法:

Collection<数据类型> c1 = new ArrayList();//JDK1.7版本之后

示例:

Collection<String> c1 = new ArrayList();//jdk1.7版本之后,后⾯不⽤再声明<String>
c1.add("hello");
c1.add("world");
//c1.add(123);
System.out.println(c1);

泛型的定义

定义含有泛型的类

定义格式:

修饰符 class 类名<代表泛型的变量> { }

什么时候确定泛型?在创建对象的时候确定泛型\color{orange}{在创建对象的时候确定泛型}
示例:

//作⽤在类上的泛型:当数据类型不确定的时候,可以⼀个泛型,通过创建对象传递过来⼀个类型,来确定T的类型
class Point<T>{

    private T x;

    private T y;

    public static <M> void test(M m){//静态⽅法上要单独声明,它不能使⽤类上⾯的声明的泛型,调⽤静态⽅法的时候,确定类型
        System.out.println("检测到了静态⽅法上的泛型:"+m);
    }

    public T getX() {
        return x;
    }

    public void setX(T x) {
        this.x = x;
    }

    public T getY() {
        return y;
    }

    public void setY(T y) {
        this.y = y;
    }

}

/**

* 泛型

*/

public class Demo {

    public static void main(String[] args) {

        Point<String> point = new Point<>();

        point.setX("wowow");

        point.setY("wowow");

        Point<Integer> point4 = new Point<>();

        point4.setY(2);

        point4.setX(3);

        Point.test("wowo");

        Point.test(23);
    }

}

定义含有泛型的⽅法

定义格式:

修饰符 <代表泛型的变量> 返回值类型 ⽅法名(参数){ }

什么时候确定泛型?调⽤⽅法时,确定泛型的类型\color{orange}{调⽤⽅法时,确定泛型的类型}
示例:

//作⽤在类上的泛型:当数据类型不确定的时候,可以⼀个泛型,通过创建对象传递过来⼀个类型,来确

定T的类型

class Point{

    public static <M> void test(M m){//静态⽅法上要单独声明,它不能使⽤类上⾯的声明的泛型,调⽤静态⽅法的时候,确定类型
        System.out.println("检测到了静态⽅法上的泛型:"+m);
    }

}

/**

* 泛型

*/

public class Demo {

    public static void main(String[] args) {

        Point.test("wowo");

        Point.test(23);

    }

}

含有泛型的接⼝

定义格式:

修饰符 interface接⼝名<代表泛型的变量> { }

示例:

/**
* 接⼝上声明泛型
* @param <T1>
* @param <T2>
*/

public interface A<T1,T2> {
    void test1(T1 t1);
    void test2(T2 t2);
}

public class AImpl implements A<String,Integer> {

    @Override
    public void test1(String s) {
    
    }

    @Override
    public void test2(Integer integer) {

    }

}

泛型通配符

当使⽤泛型类或者接⼝时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是⼀旦使⽤泛型的通配符后,只能使⽤Object类中的共性⽅法,集合中元素⾃身⽅法⽆法使⽤。

?:通配符,不确定类型,代表集合中可以存储任意类型的数据。
List:该容器有数据类型:Object
List<?>:该容器的数据类型可以是任意的

extends E
限定了上限,集合的泛型:E以及E的⼦类
super E 限定了下限,集合泛型:E以及E的⽗类

示例:

class Person{}

    class Student extends Person{}

    public class Demo3 {

        //?代表可以接收任意类型
        public static void test1(List<?> list){

        }

        public static void test2(List<Object> list){

        }

        //? extends Person限定所有类型是Person以及Person的⼦类,
        public static void test3(List<? extends Person> list){}

        //? super Student限定所有类型是Student以及Student的⽗类
        public static void test4(List<? super Student> list){}

        public static void main(String[] args) {

            List<String> list1 =new ArrayList<String>();

            List<Integer> list2 = new ArrayList<>();
            test1(list2);

            List<Object> list3 = new ArrayList<>();
            list3.add(1);
            list3.add("wowo");
            test2(list3);

            List<Person> list4 = new ArrayList<>();
            List<Student> list5 = new ArrayList<>();
            test3(list4);
            test4(list4);

        }

}