类型擦除(泛型擦除)

1.概念

泛型是Java 1.5版本才引进的概念,在这之前是没有泛型的,但是泛型代码能够很好地和之前版本的代码兼容。那是因为,泛型信息只存在于代码编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,我们称之为–类型擦除。

2.分类:

  • 无限制类型擦除

img

代码演示:

package com.genericity.demo5;

public class Earase<T> {
    private T key;

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }
}
package com.genericity.demo5;

import org.omg.PortableInterceptor.INACTIVE;

import java.lang.reflect.Field;
import java.util.ArrayList;

public class Test2 {
    public static void main(String[] args) {
        Earase<Integer> integerEarase=new Earase<>();
        //利用反射,获取Earase类的字节码文件的class类对象
        Class<? extends Earase> aClass = integerEarase.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName()+":"+declaredField.getType().getSimpleName());
        }
    }
}
//运行结果:key:Object
  • 有限制类型擦除

img

package com.genericity.demo6;

public class Earase<T extends  Number> {
    private T key;

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }
}
package com.genericity.demo6;

import java.lang.reflect.Field;

public class Test2 {
    public static void main(String[] args) {
        Earase<Integer> integerEarase=new Earase<>();
        //利用反射,获取Earase类的字节码文件的class类对象
        Class<? extends Earase> aClass = integerEarase.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName()+":"+declaredField.getType().getSimpleName());
        }
    }
}
//运行结果:key:Number
  • 擦除方法中类型定义的参数

img

package com.genericity.demo6;

import java.util.List;

public class Earase<T extends  Number> {
    private T key;

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }

    /**
     * 泛型方法
     * @param t 参数也只能是List类型,或者是List类型的子类才行
     * @param <T>
     * @return
     */
    public <T extends List> T show(T t){
        return t;
    }
}
Method[] declaredMethods = aClass.getDeclaredMethods();//获取类中的所有方法
for (Method declaredMethod : declaredMethods) {
    System.out.println(declaredMethod.getName()+":"+declaredMethod.getReturnType().getSimpleName());
}
//运行结果:
//getKey:Number
//setKey:void
//show:List
  • 桥接方法

img

package com.genericity.demo6;

/**
 * 泛型接口
 * @param <T>
 */
public interface Info<T> {
    T info(T t);
}
package com.genericity.demo6;

public class InfoImpl implements Info<Integer> {
    @Override
    public Integer info(Integer value) {
        return value;
    }
}
InfoImpl info = new InfoImpl();
Class<? extends InfoImpl> aClass1 = info.getClass();
//当然,我们在获取类的字节码文件的时候,也可以直接使用.class的方式   Class<InfoImpl>  aClass1=InfoImpl.class
Method[] declaredMethods1 = aClass1.getDeclaredMethods();
for (Method method : declaredMethods1) {
    System.out.println(method.getName()+":"+method.getReturnType().getSimpleName());
}

//运行结果:
//info:Integer
//info:Object

posted on 2021-12-08 17:06  ~码铃薯~  阅读(245)  评论(0编辑  收藏  举报

导航