Java泛型通配符使用出错,求问题排查
问题分析与修复方案
你的代码存在两个核心问题,导致无法正常运行:
1. 重载方法调用歧义
在main方法中调用order(new Box<Mammal>())时,该参数同时符合Box<? extends Mammal>和Box<? super Mammal>两个重载方法的参数类型——Mammal既是自身的子类(符合extends通配符),也是自身的父类(符合super通配符)。编译器无法确定要调用哪个重载方法,会直接抛出编译错误。
2. 泛型类型实例化非法
Box类的getContent方法中,new T()的写法违反Java泛型规则:Java泛型基于类型擦除机制,编译时泛型参数T会被擦除为其上限类型Thing,运行时无法获取T的具体类型,因此不能直接通过new T()实例化泛型对象,编译器会提示Cannot instantiate the type T错误。
修复后的代码示例
方案1:解决重载歧义 + 通过Class对象实例化泛型类型
public class WildCards { public static void main(String[] args) { // 调用处理extends通配符的方法 orderExtends(new Box<>(Animal.class)); orderExtends(new Box<>(Human.class)); orderExtends(new Box<>(Mammal.class)); // 调用处理super通配符的方法(传入Mammal的父类类型) orderSuper(new Box<>(Creature.class)); orderSuper(new Box<>(Thing.class)); } // 重命名方法避免重载歧义 public static void orderExtends(Box<? extends Mammal> box) { System.out.println(box.getContent() + " is a Mammal."); } public static void orderSuper(Box<? super Mammal> box) { System.out.println("Mammal is a " + box.getContent()); } } // 继承关系保持不变 class Thing extends Object {} class Creature extends Thing {} class Animal extends Creature {} class Mammal extends Animal {} class Primate extends Mammal {} class Gorilla extends Primate {} class Human extends Primate {} // 修改Box类,通过Class<T>实现泛型实例化 class Box<T extends Thing> { private final Class<T> type; public Box(Class<T> type) { this.type = type; } String getContent() { try { // 通过Class对象实例化并获取类名 return type.getDeclaredConstructor().newInstance().getClass().getName(); } catch (Exception e) { e.printStackTrace(); return "Instance creation failed"; } } }
方案2:直接传入对象实例(更简洁)
如果不需要动态创建对象,也可以直接在Box构造时传入已实例化的对象:
class Box<T extends Thing> { private final T object; public Box(T object) { this.object = object; } String getContent() { return object.getClass().getName(); } } // main方法调用示例 orderExtends(new Box<>(new Animal())); orderExtends(new Box<>(new Human())); orderExtends(new Box<>(new Mammal())); orderSuper(new Box<>(new Creature()));
内容的提问来源于stack exchange,提问作者twee eat
相关产品推荐
相关产品推荐

