You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zhuhuairui
4c5c6e8e5b
上传文件至 'w8'
========== 问题回答 ==========
问题一:Java泛型擦除后如何通过反射获取泛型信息?
答:
Java的泛型擦除指的是在编译时,泛型类型信息会被擦除,替换为它们的上限类型(通常是Object),
以保证与Java 1.5之前的代码兼容。然而,反射API仍然提供了一些方法来在运行时获取泛型信息:
1. 通过ParameterizedType接口:
- 使用 Class.getGenericSuperclass() 获取父类的泛型类型
- 使用 Field.getGenericType() 获取字段的泛型类型
- 这些方法返回ParameterizedType类型,可以调用 getActualTypeArguments() 获取具体类型参数
2. 示例:
```java
Type type = MyClass.class.getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
Type[] args = pt.getActualTypeArguments();
Class<?> keyType = (Class<?>) args[0]; // 获取K
Class<?> valueType = (Class<?>) args[1]; // 获取V
}
```
3. 注意事项:
- 只有继承泛型类或实现泛型接口的子类才能获取到泛型信息
- 泛型数组类型可以通过 getGenericSuperclass() 获取
- 擦除后的原始类型信息可以通过 Class.getTypeParameters() 获取泛型参数声明
问题二:为什么Java泛型不支持基本类型?
答:
Java泛型不支持基本类型(如int、double、char等),主要有以下原因:
1. 历史兼容性问题:
- Java泛型是Java 1.5才引入的,为了向后兼容,泛型采用"类型擦除"实现
- 如果允许基本类型作为泛型参数,需要修改JVM字节码指令,工作量巨大
2. JVM对象模型限制:
- JVM中的泛型类型参数期望的是对象引用,而不是基本类型值
- 基本类型在JVM中存储在栈中,而对象存储在堆中
3. 类型擦除的实现机制:
- 擦除后泛型被替换为Object,而Object只能存储引用类型
- 基本类型无法直接赋值给Object引用
4. 性能考量:
- 如果支持int这样的基本类型,泛型需要自动装箱为Integer
- 这会增加额外的装箱/拆箱开销
5. 替代方案:
- 使用包装类(如Integer、Double)代替基本类型
- Java 1.5之后提供了自动装箱功能,简化了基本类型与包装类之间的转换
例如,Cache<int, String> 是不允许的,但 Cache<Integer, String> 是可以的。
|
4 weeks ago |
| .. |
|
Cache.java
|
上传文件至 'w8'
|
4 weeks ago |
|
CacheTest.java
|
上传文件至 'w8'
|
4 weeks ago |
|
GenericReflection.java
|
上传文件至 'w8'
|
4 weeks ago |
|
Pair.java
|
上传文件至 'w8'
|
4 weeks ago |
|
PairTest.java
|
上传文件至 'w8'
|
4 weeks ago |