正如我理解正确,爪哇执行类型擦除,其中T在
class Test { private T something;
} 成为对象。但是为什么在这个例子中:
class Test { private Object[] arr; private int index = 0;
Test(){ arr = new Object[10];)
public void put(T el) { arr[index++] = el; }
}
Test test = new Test(); test.put(10) 触发编译错误并要求在编译时T成为String的参数Object?
谢谢你的回答!
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在Java中,类型擦除确实会发生,这意味着在编译后泛型类型信息(如T
)会被擦除,实际的类只使用它们的原始类型或边界类型。然而,你的问题描述中提到的现象实际上与类型擦除无关,而是关于泛型方法的实际使用和编译器对泛型类型的推断。
在这个例子中:
class Test<T> {
private Object[] arr;
private int index = 0;
Test() {
arr = new Object[10];
}
public void put(T el) {
arr[index++] = el;
}
}
Test<?> test = new Test(); // 这里需要指定类型参数,否则会报错
test.put(10); // 如果上面的声明是正确的,这里不会触发错误
首先,创建Test
实例时,你需要明确指定泛型参数类型,除非你有特定的理由使用通配符(如Test<?>
表示可以接受任何类型的Test
)。如果你想要存储任何类型的对象,最直接的方式是在定义Test
类时就指定Object
作为泛型参数,或者在实例化时明确指定类型:
// 明确指定类型为Integer
Test<Integer> test = new Test<>();
test.put(10); // 这样就不会有问题了
或者,如果你想让Test
能够接受任何类型的对象而不事先指定类型,你可以这样定义和实例化:
class Test {
private Object[] arr;
private int index = 0;
Test() {
arr = new Object[10];
}
public void put(Object el) {
arr[index++] = el;
}
}
Test test = new Test();
test.put(10); // 正确,因为put接受Object类型
在你的例子中,如果尝试不指定泛型类型就创建Test
的实例,编译器无法确定T
的具体类型,因此会报错。而当你调用put
方法时,传递一个整数(如10
),这实际上是允许的,只要你在创建Test
实例时指定了合适的泛型类型,比如Test<Integer>
。