2021-10-29  2021-10-29    1397 字   3 分钟

泛型

概述

泛型:参数化类型

泛型声明的格式

1.泛型类 2.泛型接口 3.泛型方法。

1.泛型类:

​ 格式:

[权限修饰符] class 类名<标识符,标识符>{}

代码

package com.demo;
/**
 1.泛型类:
 格式:
 [权限修饰符] class 类名<标识符,标识符>{}
 */
public class 泛型<M> {
    public static void main(String[] args) {
        fun(5);
        泛型<Double> k = new 泛型<>();
        泛型<Integer> k1 = new 泛型<>();

    }
    public static void fun(int a){}
   /* public static void add(int a,int b){}
    public static void add(double a,double b){}
    public static void add(float a,int b){}*/
   public  void add(M a, M b){}
}

泛型接口

格式

[权限修饰符] interface 接口名称<标识符,标识符>{ }

代码

package com.demo;
/**
 1.格式:
 [权限修饰符] interface 接口名称<标识符,标识符>{

 }
 */
public class 泛型 {
    public static void main(String[] args) {
        T<String> t = new T<String>() {
            @Override
            public void fun(String s) {

            }
        };
        T<Integer> t1 = new T<Integer>() {
            @Override
            public void fun(Integer integer) {

            }
        };
    }
}
interface   T<M>{
    public void fun(M m);
}

泛型方法

概述

接口或类上的泛型可以给类/接口的成员使用,方法也算是成员,所以接口或类上的泛型可以给方法使用。

引入泛型方法的原因:(使用场景)

① 当类或接口上的泛型不够该方法使用时,可以将该方法声明成泛型方法。

② 静态方法必须使用泛型方法。(静态方法随着类的加载而加载,当类出现时,未必有对象,泛型也可能没有被指定)

泛型方法声明的格式

[权限修饰符][修饰符] <标识符,标识符>返回值类型 方法名称 (参数列表 泛型){}

泛型方法的泛型的确定

随着方法的调用而确定

代码

package com.demo;
/**
  1.泛型方法:
 */
public class 泛型方法 {
    public static void main(String[] args) {
        F<String> f = new F<>();
        f.fun("abc", 12);
        f.fun("abc", "abc");
    }
}
class F<N>{
    public <K>void fun(N n,K k){

    }
    public void  fun1(N n){

    }
    //返回值类型前面声明泛型。 泛型方法
    public static <B>void sf(B b){}
}

泛型的特点

可擦除技术:只存在编译期,在class文件中不存在。

菱形技术:<> 1.7有类型推断,可以进行直接推断,在new后面的可以省略数据类型不写

泛型的好处

可以将运行期的异常转换成编译期的异常,减少了类型转换异常的发生。

避免了向下转型。

泛型的继承时的注意问题

子类继承时

如果父类有泛型,在子类中没有指定任何泛型时,为Object类型

如果子类中使用泛型时

当泛型的值不确定时,子类与父类都要有泛型

当泛型的值确定时,父类后面指定泛型的具体类型

代码

package com.demo;

public class 泛型关于子类继承问题 {
    public static void main(String[] args) {
        ZiP<Integer>  zp = new ZiP<>();
        ZiP<Integer>  zp1 = new ZiP();
        ZiP<Integer> zp2 = new ZiP<>();
        ZiP<String> zp3= new ZiP<>();

        Zip1  zp4 = new Zip1();
        zp4.fun("abc");


    }
}
class P<T1>{
     public void fun(T1 t1){}
}
//当泛型的值不确定时,子类与父类都要有泛型
class ZiP<T1> extends P<T1>{}
//当泛型的值确定时,父类后面指定泛型的具体类型
class Zip1 extends  P<String>{}

泛型的通配符

概述

1.泛型的通配符:

​ ? 代表可以接收任意数据类型。表示有泛型。

​ 注意:具体类型的操作,就不能使用。

2.泛型通配符的限定:

​ ? extends T 上限限定

​ ? super T 下限限定

3.泛型的命名:

原则上泛型起名是标识符,但是一般起名用字母代替,Java中常见字母

E T K V 用法上没区别,含义有区别

E :Element 元素

T :Type 类型

K: key 键

V: value 值

代码

package com.demo;
import java.util.ArrayList;
import java.util.Iterator;
/**
   1.泛型的通配符:
    ? 代表可以接收任意数据类型。表示有泛型。
    注意:具体类型的操作,就不能使用。
   2.泛型通配符的限定:
        ? extends T 上限限定
        ?  super T  下限限定
   3.泛型的命名:
       原则上泛型起名是标识符,但是一般起名用字母代替,Java中常见字母
        E T  K V 用法上没区别,含义有区别
        E :Element 元素
        T :Type 类型
        K: key 键
        V: value 值
 */
public class 泛型的通配符 {
    public static void main(String[] args) {
        /*ArrayList<Integer> list = new ArrayList();
        fun(list);
        ArrayList<String> list1 = new ArrayList();
        fun(list1);*/
        ArrayList<Person> list2 = new ArrayList<>();
        fun1(list2);
    }
    public static void fun(ArrayList<?> list){
        Iterator<?> it = list.iterator();
        while (it.hasNext()){
            Object value = it.next();
        }
    }
    public static void  fun1(ArrayList<? super   Student> list){}
}
class  Person{

}
class Student extends  Person{}
class MiddleStudent extends  Student{}

avatar
青山
悟已往之不谏 知来者之可追
一言
今日诗词
站点信息
本站访客数 :
本站总访问量 :