泛型内部类参数的父类方法无法重写?求原因与实现方案
问题原因与解决方案
核心原因
问题出在泛型类型擦除结合非静态内部类的关联性上:
- 你的
ApplicationDTOManager中的CreationRequest是非静态内部类,这类内部类会隐式持有外部类的引用,其完整类型实际是ApplicationDTOManager.this.CreationRequest。 - 当泛型抽象类
ApplicationController被类型擦除后,hasCreatePermissions方法的参数会退化为原始类型ApplicationDTOManager.CreationRequest。而子类UserResource中使用的UserDTOManager.CreationRequest属于另一个独立的外部类类型,Java编译器会判定这是一个新方法,而非对父类方法的重写。
解决方案
把ApplicationDTOManager中的CreationRequest改为静态内部类。静态内部类不依赖外部类的实例,类型独立,泛型编译时会正确绑定到具体子类的内部类类型,从而让子类方法参数与父类泛型化后的参数匹配,实现正确重写。
代码示例
修改前(存在问题的代码)
// 抽象DTO管理器,内部为非静态内部类 public abstract class ApplicationDTOManager { // 非静态内部类导致类型绑定问题 public abstract class CreationRequest {} } // 泛型抽象控制器 public abstract class ApplicationController<T extends ApplicationDTOManager> { public boolean hasCreatePermissions(T.CreationRequest request, Optional<UUID> id) { return false; } } // 子类控制器,无法正确重写 public class UserResource extends ApplicationController<UserDTOManager> { // 编译器判定为新方法,而非重写 @Override public boolean hasCreatePermissions(UserDTOManager.CreationRequest request, Optional<UUID> id) { return true; } } // UserDTOManager实现类 public class UserDTOManager extends ApplicationDTOManager { public class CreationRequest extends ApplicationDTOManager.CreationRequest {} }
修改后(可正确重写的代码)
// 抽象DTO管理器,内部改为静态内部类 public abstract class ApplicationDTOManager { // 静态内部类解除与外部类实例的绑定 public static abstract class CreationRequest {} } // 泛型抽象控制器无需修改 public abstract class ApplicationController<T extends ApplicationDTOManager> { public boolean hasCreatePermissions(T.CreationRequest request, Optional<UUID> id) { return false; } } // 子类控制器可正确重写方法 public class UserResource extends ApplicationController<UserDTOManager> { @Override public boolean hasCreatePermissions(UserDTOManager.CreationRequest request, Optional<UUID> id) { return true; } } // UserDTOManager实现类,内部类同步改为静态 public class UserDTOManager extends ApplicationDTOManager { public static class CreationRequest extends ApplicationDTOManager.CreationRequest {} }
该方案完全符合你的要求:无需新增泛型、无需构造函数,仅调整内部类的静态修饰符即可解决问题。
内容的提问来源于stack exchange,提问作者Mansehaj Singh
相关产品推荐
相关产品推荐

