Java:如何避免 "method not applicable for the arguments"错误

标签 java generics

我意识到此类问题已被问过无数次,但我还没有找到一个答案,似乎可以解决和/或解释 1)我做错了以及 2)我需要做什么才能得到它对。

我有一个应用程序,我正在尝试管理队列集合。队列管理器的用户将通过提供唯一 ID 来请求队列,如果队列已被管理,管理器将返回该队列,或者创建一个新队列(通过反射)并在尚未创建时返回它。

我已经对队列管理器进行了编码以使用 Java 泛型,但遇到了一个我不明白的问题,也不知道如何纠正该问题。

这是队列管理器:

public class QueueManager<T extends MessageType, C extends BlockingQueue<T>> {

  private Map<UUID, C> queueMap;

  public void removeQueue(UUID id) {
    queueMap.remove(id);
  }

  public C getQueue(Class<C> clazz, UUID id) {
    if (!queueMap.containsKey(id)) {
      queueMap.put(id, constructQueue(clazz));
    }

    return queueMap.get(id);
  }

  private C constructQueue(Class<C> clazz) {
    C result = null;

    try {
      Constructor<C> constructor = clazz.getDeclaredConstructor();
      result = constructor.newInstance();
    } catch (NoSuchMethodException | SecurityException | InstantiationException
        | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
      // handle exception
    }

    return result;
  }

}

使用队列管理器的代码:

public class QueueingListener<T extends MessageType> implements MessageListener<T> {

  private QueueManager<T, BlockingQueue<T>> queueMgr = new QueueManager<>();
...
  @Override
  public void handleMessage(T message) {
...
      queueMgr.getQueue(LinkedBlockingQueue.class,
          message.getMessageHeader().getUUID());
...
  }

代码提示编译错误:

The method getQueue(Class<BlockingQueue<T>>, UUID) in the type QueueManager<T,BlockingQueue<T>> is not applicable for the arguments (Class<LinkedBlockingQueue>, UUID)

有人可以解释一下这里出了什么问题以及我需要做什么吗?

我真的很想知道在哪里可以找到关于 Java 泛型的非常好的教程。我查看了许多资料,但它们似乎只涵盖了让某人继续前进的基础知识,而没有涵盖更高级的概念和更精细的细节。

最佳答案

为什么要关心所管理的队列类型,为什么不直接传递 Supplier<BlockingQueue>到 setter/getter ?

public class QueueManager<T extends MessageType> {

    private Map<UUID, BlockingQueue<T>> queueMap;

    public void removeQueue(UUID id) {
      queueMap.remove(id);
    }

    public BlockingQueue<T> getQueue(UUID id, Supplier<BlockingQueue<T>> createQueue) {
        return queueMap.computeIfAbsent(id, k -> createQueue.get());
    }

    // let's add a default while we're at it 
    public BlockingQueue<T> getQueue(UUID id) {
        return getQueue(id, () -> new ArrayBlockingQueue<T>(50));
    }
}

这样就可以打电话了

queueMgr.getQueue(message.getMessageHeader().getUUID(), LinkedBlockingQueue::new);

关于Java:如何避免 "method not applicable for the arguments"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56774684/

相关文章:

java - 来自 python 的转置矩阵

java - 如何在退出前安全地关闭所有线程

C# 泛型 : wildcards

java - 是否有 Math.floorDiv(a, b),但用于 BigInteger?

java - 识别两个不同的线程

c++ - C++在编译时如何知道模板类支持哪些方法?

c# - 在 UserControl 中使用泛型类型的正确方法是什么?

swift - 如何以通用方式快速访问关联枚举

c# - 从非泛型类覆盖抽象泛型方法

Java 正则表达式匹配之前和之后的所有内容