泛型通配符和具体使用

71 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

泛型

1. 介绍

本质:参数化类型

泛型的擦除:

泛型只在编译阶段有效,编译之后JVM会采取去泛型化的措施

泛型在运行阶段是没有效果的

image-20220810135221022

image-20220810135228370

2. 泛型通配符

image-20220810135418690

无边界通配符

<?>实现

image-20220810135848674

上边界通配符

这里的String由于不是Number的子类,于是就会报错

<?extends Number>实现

image-20220810161205138

下边界通配符

必须是Integer到Object类型的对象

<? super Integer>

image-20220810161542748

3. 具体使用

image-20220810162144253

免去向上向下转型的问题

先声明再使用

image-20220811091030789

泛型类

新建一个Person类

/**
 * @Author: sc
 * @Date: 2022/8/11 10:26
 */
public class Person {
    private String username;
​
    private String password;
​
    public String getUsername() {
        return username;
    }
​
    public void setUsername(String username) {
        this.username = username;
    }
​
    public String getPassword() {
        return password;
    }
​
    public void setPassword(String password) {
        this.password = password;
    }
}

再新建一个PersonBean类

/**
 * @Author: sc
 * @Date: 2022/8/11 10:26
 */
public class PersonBean <T> {
    private T t;
​
    public PersonBean(T t) {
        this.t = t;
    }
​
    public T getT() {
        return t;
    }
​
    public void setT(T t) {
        this.t = t;
    }
}

测试类

/**
 * @Author: sc
 * @Date: 2022/8/11 10:32
 */
public class test {
​
    public static void main(String[] args) {
        Person person = new Person();
        person.setUsername("sc");
        person.setPassword("666");
​
        PersonBean<Person> personBean = new PersonBean<>(person);
        PersonBean<String> personBean1 = new PersonBean<>("hello");
​
    }
}

可以增加代码的灵活度

泛型方法

/**
 * @Author: sc
 * @Date: 2022/8/11 10:42
 */
public class Demo <K, V>{
​
    /**
     * 普通方法 可以使用 类中定义的泛型
     * @param k
     * @param v
     * @return
     */
    public K method1(K k, V v){
        return (K)null;
    }
​
    /**
     * 普通方法 使用方法中定义的泛型
     * @param t
     * @param v
     * @param <T>
     * @return
     */
    public <T> T method2(T t, V v){
        return (T)null;
    }
​
    /**
     * 在静态方法中我们没法使用 类中定义的泛型
     * 因为静态方法,在没有new这个对象之前也可以使用,但是如果用类中定义的泛型这个时候就没的用
     * @param <K>
     * @return
     */
    public static <K> K method3(){
        return null;
    }
​
}

泛型接口

比如这样写就会有点约束

/**
 * @Author: sc
 * @Date: 2022/8/11 10:42
 */
public interface Demo {
    
    int add(int a, int b);
    
}

比如我需要传入double类型的,就要再写一个方法,

但是这个时候我们可以使用泛型解决这个问题

/**
 * @Author: sc
 * @Date: 2022/8/11 10:42
 */
public interface Demo <T>{
​
    T add(T a, T b);
    
}

这时候可以看到自动生成的是直接生成double类型的数据类型

/**
 * @Author: sc
 * @Date: 2022/8/11 10:50
 */
public class DemoImpl implements Demo<Double>{
    @Override
    public Double add(Double a, Double b) {
        return null;
    }
}

1.3 反射

1.4 自定义注解