通过例子体现泛型擦除特性
通过Spring拷贝方法演示
1、演示代码
定义了公用的泛型拷贝对象(源对象和目标对象),里面包含list的泛型属性;
import org.springframework.beans.BeanUtils; import java.util.ArrayList; import java.util.List; class CopyObj{ private List list; public List getList() { return list; } public void setList(List list) { this.list = list; } } /** * @author Green * @date 2021年12月31日 11:11 上午 */ public class CopyTest { public static void main(String[] args) { // 定义包含List 属性的源对象 CopyObjstrCopyObj = new CopyObj<>(); List stringList = new ArrayList<>(); stringList.add("abc1"); stringList.add("abc2"); stringList.add("abc3"); strCopyObj.setList(stringList); // 定义包含List 属性的目标对象 CopyObjintCopyObj = new CopyObj<>(); List integerList = new ArrayList<>(); intCopyObj.setList(integerList); // 通过spring拷贝对象,只要属性名和属性类型能够对应上都会进行拷贝 // 运行时泛型擦除了,所以泛型对不上并不影响 // 两个对象中都包含名为list 类型为java.util.List 的属性,所以这两个属性会进行拷贝 // 但是拷贝之后目标对象intCopyObj中存储的是源对象strCopyObj中属性list的值, // 也就是讲string类型的值拷贝到了intCopyObj对象中的List 类中属性中 // 拷贝可成功,因为泛型擦除,实际拷贝进的属性类型是List BeanUtils.copyProperties(strCopyObj, intCopyObj); // 这里是拷贝 // 但是这里遍历会出问题,因为编译时会检测泛型, // 要想编译通过,目标对象的属性编译时是Integer类型,但实际运行是这里存储的是String类型 // 所以这里遍历会报错类型转换异常 for (Integer integer : intCopyObj.getList()) { System.out.println("success!"); } } }
2、debug详情
拷贝是可以完成的,目标对象intCopyObj中属性List
但是下一步遍历的时候会报错,String不能转换为Integer,如下图:
原因:这就是因为泛型在编译期有效,在运行期擦除了,可以通过反射赋值而不受泛型限制,但是后面的调用运行期会报错;具体原因可以看第一部分的代码注释;
TRANSLATE withArabic | Hebrew | Polish |
Bulgarian | Hindi | Portuguese |
Catalan | Hmong Daw | Romanian |
Chinese Simplified | Hungarian | Russian |
Chinese Traditional | Indonesian | Slovak |
Czech | Italian | Slovenian |
Danish | Japanese | Spanish |
Dutch | Klingon | Swedish |
English | Korean | Thai |
Estonian | Latvian | Turkish |
Finnish | Lithuanian | Ukrainian |
French | Malay | Urdu |
German | Maltese | Vietnamese |
Greek | Norwegian | Welsh |
Haitian Creole | Persian |