Moosphan / Android-Daily-Interview

:pushpin:每工作日更新一道 Android 面试题,小聚成河,大聚成江,共勉之~

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2019-08-09:谈谈你对Java泛型中类型擦除的理解,并说说其局限性?

Moosphan opened this issue · comments

Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。

如在代码中定义的List和List等类型,在编译后都会变成List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法避免在运行时刻出现类型转换异常的情况。类型擦除也是Java的泛型实现方法与C++模版机制实现方式之间的重要区别。

泛型用于扩展,T。

Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了“伪泛型”的策略,即Java在语法上支持泛型,但是在编译阶段会进行所谓的“类型擦除”(Type Erasure),将所有的泛型表示(尖括号中的内容)都替换为具体的类型(其对应的原生态类型),就像完全没有泛型一样。

commented

参考:https://www.cnblogs.com/wuqinglong/p/9456193.html

1,类型擦除,发生在编译过程。指的是,所有的泛型信息都会被擦除(默认继承Object)

2,已解决的局限:
1)ArrayList(String> 不能够添加Integer类型的数据;通过 编译器先检查代码中的泛型的类型 解决
2)编辑器从ArrayList(String>中泛型中获取值,都有Object 强转 String
3) 父类定义泛型,子类实现;实现的 重载,实际上,编译器会变成重写。通过 编译器的桥方法解决

3,未解决的局限:
1)泛型类型变量,不能是,基本数据类型
2)运行时,无法检测类型;例如:object instanceof ArrayList(String> 这个逻辑无法实现
3)泛型类型,无法在静态方法和静态变量中使用;如下:
public class TestClass {
public static T getSome() {
return null;
}
}
这一段逻辑,添加 static字段,编译器报错

commented

泛型类型,无法在静态方法和静态变量中使用,这句话有点问题,应该是泛型类的泛型,无法在静态方法和静态变量中使用

参考:https://www.cnblogs.com/wuqinglong/p/9456193.html

1,类型擦除,发生在编译过程。指的是,所有的泛型信息都会被擦除(默认继承Object)

2,已解决的局限: 1)ArrayList(String> 不能够添加Integer类型的数据;通过 编译器先检查代码中的泛型的类型 解决 2)编辑器从ArrayList(String>中泛型中获取值,都有Object 强转 String 3) 父类定义泛型,子类实现;实现的 重载,实际上,编译器会变成重写。通过 编译器的桥方法解决

3,未解决的局限: 1)泛型类型变量,不能是,基本数据类型 2)运行时,无法检测类型;例如:object instanceof ArrayList(String> 这个逻辑无法实现 3)泛型类型,无法在静态方法和静态变量中使用;如下: public class TestClass { public static T getSome() { return null; } } 这一段逻辑,添加 static字段,编译器报错

public class TestClass<T> {
public static T getSome() {
return null;
}
}

泛型类型,无法在静态方法和静态变量中使用,这句话有点问题,应该是泛型类的泛型,无法在静态方法和静态变量中使用

参考:https://www.cnblogs.com/wuqinglong/p/9456193.html
1,类型擦除,发生在编译过程。指的是,所有的泛型信息都会被擦除(默认继承Object)
2,已解决的局限: 1)ArrayList(String> 不能够添加Integer类型的数据;通过 编译器先检查代码中的泛型的类型 解决 2)编辑器从ArrayList(String>中泛型中获取值,都有Object 强转 String 3) 父类定义泛型,子类实现;实现的 重载,实际上,编译器会变成重写。通过 编译器的桥方法解决
3,未解决的局限: 1)泛型类型变量,不能是,基本数据类型 2)运行时,无法检测类型;例如:object instanceof ArrayList(String> 这个逻辑无法实现 3)泛型类型,无法在静态方法和静态变量中使用;如下: public class TestClass { public static T getSome() { return null; } } 这一段逻辑,添加 static字段,编译器报错

public class TestClass { public static T getSome() { return null; } }

以下用法也可以
public static T getSome() {
return null;
}