简化泛型类实例化:无需重复指定WorldObjectType类型
解决嵌套泛型重复指定类型的问题
嘿,这个场景我太熟悉了——嵌套泛型里重复写相同的类型参数真的是又啰嗦又容易出错!别担心,咱们可以通过静态工厂方法+语言的泛型类型推断来彻底解决这个问题,让你只需要传入WorldObjectsProvider<WorldObjectSUBCLASS>,编译器自动帮你提取出WorldObjectSUBCLASS类型,再也不用重复指定啦。
先还原你的问题场景
假设你的基础类型和类定义大概是这样的(我补全了示例代码方便理解):
// 基础的世界对象类型 interface WorldObjectType {} // 你的具体子类 class WorldObjectSubclass implements WorldObjectType {} // 对象提供者接口,泛型绑定到WorldObjectType interface ObjectsProvider<T extends WorldObjectType> {} // 具体的提供者实现 class WorldObjectsProvider<T extends WorldObjectType> implements ObjectsProvider<T> {} // 你原来的管理类,需要同时指定T和Provider<T> class ObjectManager<T extends WorldObjectType, P extends ObjectsProvider<T>> { private P provider; public ObjectManager(P provider) { this.provider = provider; } // 类中需要用到T的业务方法 public void handleObject(T object) { // 处理逻辑 } }
之前创建实例的时候,你不得不重复写两次WorldObjectSubclass:
// 冗余的重复指定 ObjectManager<WorldObjectSubclass, WorldObjectsProvider<WorldObjectSubclass>> manager = new ObjectManager<>(new WorldObjectsProvider<>());
解决方案:用静态工厂方法实现自动类型推断
咱们给ObjectManager加一个私有构造方法和静态工厂方法,让编译器自动帮我们推导泛型参数:
class ObjectManager<T extends WorldObjectType, P extends ObjectsProvider<T>> { private P provider; // 把构造方法私有化,强制外部通过工厂方法创建实例 private ObjectManager(P provider) { this.provider = provider; } // 静态工厂方法:编译器会从传入的provider自动推断出T的类型 public static <T extends WorldObjectType> ObjectManager<T, WorldObjectsProvider<T>> create(WorldObjectsProvider<T> provider) { return new ObjectManager<>(provider); } // 如果需要兼容所有ObjectsProvider实现,而不只是WorldObjectsProvider,可以改成: // public static <T extends WorldObjectType, P extends ObjectsProvider<T>> ObjectManager<T, P> create(P provider) { // return new ObjectManager<>(provider); // } public void handleObject(T object) { // 处理逻辑 } }
现在创建实例就超级简洁了——完全不用手动指定泛型参数:
// 编译器自动推断T是WorldObjectSubclass var manager = ObjectManager.create(new WorldObjectsProvider<WorldObjectSubclass>()); // 如果你不用var(比如Java 10之前),也只需要指定一次类型: ObjectManager<WorldObjectSubclass, ?> manager = ObjectManager.create(new WorldObjectsProvider<>());
核心思路说明
这种方法的本质是利用语言的泛型类型推断能力,把重复的泛型参数推导工作交给编译器来做。静态工厂方法的泛型声明会从你传入的WorldObjectsProvider<X>中自动提取出X作为T,从而避免了你手动重复写两次X。
如果是在C#这类语言里,思路完全一致——同样可以用静态工厂方法,或者利用C# 9+的目标类型推断来简化构造调用。
内容的提问来源于stack exchange,提问作者Damian Dudycz
相关产品推荐
相关产品推荐

