了解本例中Java泛型的最佳使用
假设我有一个生产调度系统,它由四部分组成:了解本例中Java泛型的最佳使用,java,generics,Java,Generics,假设我有一个生产调度系统,它由四部分组成: 有些工厂可以生产某种类型的产品,并知道他们是否忙碌: interface Factory<ProductType> { void buildProduct(ProductType product); boolean isBusy(); } 我一直在绞尽脑汁想如何以一种类型安全的方式解决这个问题,但是我的泛型技能让我在这里失败了 例如,将其更改为以下内容也无济于事: public void assignWork() {
- 有些工厂可以生产某种类型的产品,并知道他们是否忙碌:
我一直在绞尽脑汁想如何以一种类型安全的方式解决这个问题,但是我的泛型技能让我在这里失败了 例如,将其更改为以下内容也无济于事:interface Factory<ProductType> { void buildProduct(ProductType product); boolean isBusy(); }
您的代码很奇怪。public void assignWork() { for (Factory<?> factory: workQueues.keySet()) if (!factory.isBusy()) { Product<?> product = workQueues.get(factory).poll(); product.getFactory().buildProduct(product); } }
您的问题是您正在将一个
传递给一个方法,该方法需要一个产品
,实际上是产品类型
T
我也不知道什么是
,因为您在OP中没有提到它的定义。产品
您需要传递
才能工作。我不知道您将从何处获得它,因为我无法理解您试图用代码做什么产品
Map>>workQueues=newhashmap>>();
//工厂的类型是“工厂的?” 对于(工厂:workqueues.keySet()) //队列的类型为“产品的队列?”Map<Factory<?>, Queue<Product<?>>> workQueues = new HashMap<Factory<?>, Queue<Product<?>>>(); // factory has the type "Factory of ?" for (Factory<?> factory: workqueues.keySet()) // the queue is of type "Queue of Product of ?" Queue<Product<?>> q = workqueues.get(factory); // thus you put a "Product of ?" into a method that expects a "?" // the compiler can't do anything with that. factory.buildProduct(q.poll()); }
排队明白了!感谢meriton回答了这个问题: 我需要在一个单独的泛型函数中完成
-部分的编译。以下是我需要对代码进行的更改,以使其正常工作(真是一团糟):product.getFactory().buildProduct(product)
- 请更具体地介绍OrderSystem:
interface OrderSystem { <ProductType extends Product<ProductType>> ProductType getNextProduct(); }
接口命令系统{ ProductType getNextProduct(); }
- 定义我自己的强类型队列以容纳产品:
@SuppressWarnings("serial") class MyQueue<T extends Product<T>> extends LinkedList<T> {};
@SuppressWarnings(“串行”) 类MyQueue扩展了LinkedList{};
- 最后,将调度程序更改为此beast:
class Dispatcher { Map<Factory<?>, MyQueue<?>> workQueues = new HashMap<Factory<?>, MyQueue<?>>(); @SuppressWarnings("unchecked") public <ProductType extends Product<ProductType>> void addNextOrder(OrderSystem orderSystem) { ProductType nextProduct = orderSystem.getNextProduct(); MyQueue<ProductType> myQueue = (MyQueue<ProductType>) workQueues.get(nextProduct.getFactory()); myQueue.add(nextProduct); } public void assignWork() { for (Factory<?> factory: workQueues.keySet()) if (!factory.isBusy()) buildProduct(workQueues.get(factory).poll()); } public <ProductType extends Product<ProductType>> void buildProduct(ProductType product) { product.getFactory().buildProduct(product); } }
类调度器{ Map>workQueues=newhashmap>(); @抑制警告(“未选中”) public void addNextOrder(OrderSystem OrderSystem){ ProductType nextProduct=orderSystem.getNextProduct(); MyQueue MyQueue=(MyQueue)workQueues.get(nextProduct.getFactory()); 添加(nextProduct); } 公共工程(){ 对于(工厂:workQueues.keySet()) 如果(!factory.isBusy()) buildProduct(workQueues.get(factory.poll()); } 公共产品(产品类型产品){ product.getFactory().buildProduct(产品); } }
还要注意的是,队列的类型转换需要
函数上的@SuppressWarnings(“unchecked”)
注释,而不是某些产品对象。因为我只在这个队列上调用“add”,在编译和类型擦除之后,它将所有元素简单地存储为对象,所以这永远不会导致任何运行时强制转换异常。(如果这是错误的,请纠正我!)为什么@SuppressWarnings(“unchecked”)
需要泛型类型?@Andy可能不需要,但我想如果我在Product return a Factory中使用getFactory()方法,那么使这项工作正常的机会可能更小,因为那个时候,返回的工厂甚至不知道它应该生产哪种类型的产品。但也许我错了?通常你会有一个Product
,以及其他类型的子类(例如产品
,书籍
),而不是“X的产品,它是X的产品的子类型”-这是可能的吗?同意。。。(这是可能的)。。。也许我不需要用更干净的方法。但通过这种方式,我能够更好地强制执行,我得到了正确的工厂回来。。。否?是有道理的,但是为什么我的第二个版本的代码不能工作,它使用了这个调用:汽车
product.getFactory().buildProduct(product)代码>getFactory方法是否正确定义为仅返回可以将产品作为参数处理的工厂?
class Widget implements Product<Widget> { public String color; @Override public Factory<Widget> getFactory() { return WidgetFactory.INSTANCE; } } class WidgetFactory implements Factory<Widget> { static final INSTANCE = new WidgetFactory(); @Override public void buildProduct(Widget product) { // Build the widget of the given color (product.color) } @Override public boolean isBusy() { return false; // It's really quick to make this widget } }
Map<Factory<?>, Queue<Product<?>>> workQueues = new HashMap<Factory<?>, Queue<Product<?>>>(); // factory has the type "Factory of ?" for (Factory<?> factory: workqueues.keySet()) // the queue is of type "Queue of Product of ?" Queue<Product<?>> q = workqueues.get(factory); // thus you put a "Product of ?" into a method that expects a "?" // the compiler can't do anything with that. factory.buildProduct(q.poll()); }
interface OrderSystem { <ProductType extends Product<ProductType>> ProductType getNextProduct(); }
@SuppressWarnings("serial") class MyQueue<T extends Product<T>> extends LinkedList<T> {};
class Dispatcher { Map<Factory<?>, MyQueue<?>> workQueues = new HashMap<Factory<?>, MyQueue<?>>(); @SuppressWarnings("unchecked") public <ProductType extends Product<ProductType>> void addNextOrder(OrderSystem orderSystem) { ProductType nextProduct = orderSystem.getNextProduct(); MyQueue<ProductType> myQueue = (MyQueue<ProductType>) workQueues.get(nextProduct.getFactory()); myQueue.add(nextProduct); } public void assignWork() { for (Factory<?> factory: workQueues.keySet()) if (!factory.isBusy()) buildProduct(workQueues.get(factory).poll()); } public <ProductType extends Product<ProductType>> void buildProduct(ProductType product) { product.getFactory().buildProduct(product); } }
- 请更具体地介绍OrderSystem: