Java泛型使用

Java泛型

本质就是参数化类型

1. 泛型的擦除

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

泛型在运行时是没有效果的。

public static void main(String[] args) throws Exception {
        List<String> list = new ArrayList<>();
        list.add("elian");
        list.add("gupao");
        list.add("hello");
        for (Object obj :
                list) {
            System.out.println((String) obj);
        }
        // 通过反射的方式添加元素
        Class<? extends List> aClass = list.getClass();
        Method add = aClass.getDeclaredMethod("add", Object.class);
        add.invoke(list, new Object());
        System.out.println(list);
}

2. 泛型通配符介绍

2.1 无边界通配符介绍

通用类型
public class FanxDemo02 {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("elian");
        list1.add("hello");
        loop(list1);
        List<Number> list2 = new ArrayList<>();
        list2.add(1);
        list2.add(2);
        list2.add(3);
        loop(list2);
    }
    public static void loop(List<?> list) {
        for (Object o : list) {
            System.out.println(o);
        }
    }
}

任何类型都可以作为List的泛型进行传递。

2.2 上边界通配符

image-20220228161357657

代表从Number往下的所有子类都可以使用

image-20220228162237442

上边界指定了通用类型的上限,String这里就不能作为List的泛型进行传递了。

2.3 下边界通配符

表示必须是Integer及其父类直到Object所有对象都可以
public static void loop(List<? super Integer> list) {
        for (Object o : list) {
            System.out.println(o);
        }
}

3. 泛型的具体使用

规则:

  • 必须先声明,再使用
  • 泛型的声明是通过"<>"实现
  • 约定泛型可以使用单个大写字母来表示
    public <T>T get(T t) { // 必须先声明<T>才能用T作为返回值类型
        return t;
    }

4. 泛型类

public class FanxPerson <T> {
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    @Override
    public String toString() {
        return "FanxPerson{" +
                "t=" + t +
                '}';
    }

    public static void main(String[] args) {
        FanxPerson<Person> person1 = new FanxPerson<>();
        FanxPerson<String> person2 = new FanxPerson<>();
        Person person = new Person();
        person.setAddr("北京通州");
        person.setAge(26);
        person.setName("Elian");
        person1.setT(person);
        person2.setT("Hello");
        System.out.println(person1);
        System.out.println(person2);
    }
}
class Person {
    private String name;
    private Integer age;
    private String addr;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", addr='" + addr + '\'' +
                '}';
    }
}

可以增加代码灵活度。

5. 泛型方法

public class FanxMethod <K, V> {
    // 直接使用方法声明的泛型
    public V methode(K k, V v) {
        return v;
    }
    // 因为static静态方法
    // 对象中的泛型,只有在创建的之后才能知道类型
    // 所以static方法中泛型必须单独声明
    public static <K, V>K method( K k, V v ) {
        return k;
    }
    // 在返回值之前声明新的泛型
    public <T> T meth1( T t, V v ) {
        return t;
    }
    public <T> void meth2( T t, V v ) {
    }
}

6. 泛型接口

public interface CalculateGeneric <T> {
    T add( T a, T b );
}
class CalculateIntegerGeneric implements CalculateGeneric<Integer> {
    @Override
    public Integer add(Integer a, Integer b) {
        return a + b;
    }
}
class CalculateDoubleGeneric implements CalculateGeneric<Double> {
    @Override
    public Double add(Double a, Double b) {
        return a + b;
    }
}
posted @ 2022-02-28 17:09  coderElian  阅读(90)  评论(0)    收藏  举报