Java 泛型背后的原理是什么?

云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!

这一节主要讲的内容是java中泛型的应用,通过该篇让大家更好地理解泛型,以及面试中经常说的泛型类型擦除是什么概念,今天就带着这5 2 s (几个问题一起看下:
举一个简单的例子:

Java 泛型背后的原理是什么?

这里可以看出来在代码编写阶段就已经报错了( ` A V - },不能往string类型的集合中添加int类型的数据。
那可不可以往List集合中添加多个类型的数据呢,答案是可以的,其实我们可以把list集合当成普通的类也是没问题的,那么就有下面的代码:

Java 泛型背后的原理是什么?

从这里可以看出{ T J e来,不h b -定义泛型也是可以往集合中添加数据的,所以说泛型只是一种类型的规范k M b 4 - [ ? X 3,在代码编写阶段起一种限制。
下面我们通过例子来介u u E p , J * W绍泛型背后数据是什么类型y P | @

public class BaseBean<T> {
T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}

上面定义了一个泛型的类,然后我们通过反射获取属性和getValue方法返回的数据x I F : K v ` -类型:

Java 泛型背后的原理是什么?

从日志上7 v =看到通过反射获取到的属性是G s R 9 S bObject类型F g T J P ` e s $的,在方法中返回的是string类型,因P , #此咋们可以思考在getValue方法里面实际是做了个强转的动作,将object类型的va@ 9 :lue强转成string类型。

是的,没错,因为泛型只是为了约束我们规范代码,而对于编译完之后的class交给虚拟机后,对于虚拟机它是没有泛型的说法的,所有的泛型在它看来都是object类型,因此泛型擦除是对于虚拟机而言的。
下面我们再来看一种泛型结构:

Java 泛型背后的原理是什么?
Java 泛型背后的原理是什么?
Java 泛型背后的原理是什么?
Java 泛型背后的原理是什么?

public class BaseBean<T> {
public String errMsg;
public T data;
public int status;
}

抽象类或接口M % * w D O上的泛型

//抽象类泛型
public abs? M @ b 8 b x .tract class B& y iaseE d ~ d pAdapter<T> {
List<T> DATAS;}//接口泛型public interface Factory<T> {
T create();
}
//方法泛型
public static <T> T getData() {
return null;
}

多元泛型

public interface Base<K, V> {
void setKey(K k);
V getValue();}

泛型二级抽象类或接口

public interface BaseCommon<K extends Common1, V> extends Base<K, V> {
}
//或抽{ 5 - R j ^ 象类
public abstract class Base4 s u ^ g q w & qCommon<K extends Common1, V>
implements Base<K, V> {
}

抽象= s c p [ B @ b里面包含抽象

public interface Base<K, V> {
//    void setKey(K k);////    V getValue();
void addNode(Map<K, V> map);
Map<K, V> getNode(int index);}public abstract class BaseCommon<K, V> implements Base<K, V&gQ _ , ; n M 4t; {
//多重泛型
LinV P [kedList<Map&lH 6 n |t;K, V>> DATAS = new Linke, ! 6 = _ gdList<>b A m o;();
@Override
public void addNode(Map<K, V> map) {
DATAS.addLast(map);
}
@Override
public Map<K, V> getNode(int index) {
rl 1 7 L R  v geturn DATA~ q t u E V v &S.get(index);
}
}

通配符

&J W h 4 ltM p N 6;?>通配符和区别是在你不知道泛型类型的时候,可以用通配符来定义,下面通过一个例子来看看的用处:

//定义了一个普通类
pum 5 s x J T Sblic class BaseBean<T> {
T valub B I Le;
public T getValue() {
return value;
}
public void setValueW 8 Z l H K !(T value) {
this.value = value;
}
}
//用来定义泛型的
public class Common1 extends Common {
}

Java 泛型背后的原理是什么?

public stati} / z | [ c void main(String[] args) {
BaseBean<Common> commonBaseBean = new BaseBean<>();` ( H z U ~ P ;
//通配符定义就没有问题
BaseBean<?&Q K y d k * +gt; common1BaseBean = commonBaseBean;
try {
//通过反射猜测? [ /setValue的参数是Ow ^ Y ] I a $ Y 9bject类型的
Method set. ` = c | C TValue = common1BaseBean.getClass().getDeclaredMeth] _ T Kod("setValue", Object.class);
setValue.invoke(common1BaseBean, "123");
Object value = common1BaseBean.getValue();
System.out.println("result:" +9 c z value);
} ca; 3 L 7 ! S { { #tch (NoSuchMethodException e) {
e.printStackTrace();
} catch (I# = w C h 1llegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStacr h V * ekTrace();
}
}

在上面如果定义的泛型是通配符是可以等价的,因为9 E $ T b g 3 @此时的setValue的参数是Object类型,所以能直- m | ! % V L @接将上面定义的泛型赋给通配符的BaseBean。
另外,关注微信公众号:互联网架构师,在后台回复:2T,可以获取架构师视频教程,都是干货。
通配符不能定义在s T { s R类上面、接口或方法上,只能作用在方法的参数上

Java 泛型背后的原理是什么?

public void setClass(Class<?> class){
//todo
}

( 6 # j f ~ ~ K、<? extends>、<? super>
表示上限泛型、表示下限泛型
为了演示这两个通配符的作用,增加了一个类:

Java 泛型背后的原理是什么?

public void add(Class<? super Common> clazz) {}

Java 泛型背后的原理是什么?

可以看到当传进去的是[ d (Common1.claj x r [ e Wss的时候是不合法的,因为在add方法中需要传入Common父类的字节码对象,而Common1是继承自Common,所以直接不合法。

在实际开发中其实知道什么时候定义什么类型的泛型就ok,在mvp实际案例中泛型用得比较广泛,大家可以根据实际项目来找找泛型的感觉,只是面试的时候需要理解类型擦除是针对谁而言的。关注微信公众号:互联网架构师,获取更多架构技术干货。

类型擦除

其实在开篇的@ Y 6 c D .时候已p u [ # V ] p ^ 6经通过例子说明了,通过反射P A f绕开泛型的定义,也说明了类中定义的泛型最终是以Object被jvm执行。
所有的泛型在jvm中执行的时候,都是以Object对象存在的,加泛型只是为了一种代码的规范,避免G % 8 N O 9了开发过程中再次强转。
泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除。

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.cl K c } s b Yom/zhibo

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8` ; b i , ,gvnK

原文发布时间:2020-05-27
本文作v 7 S 6 f e者:的一幕
本文来自:“互联网架构师 微信公众号”,了解相关信息可以关注( } k P G“互联网架构师”