Java 回到基础:方法Sig中的泛型

Java 回到基础:方法Sig中的泛型,java,generics,Java,Generics,因此,当我尝试传递对象Map>时,我的代码显示编译器错误。如下 private static void logProgress(Map<String, Future<Cache<?>>> cacheLoaders, Map<String, Future<?>> cacheWriters) throws InterruptedException, ExecutionException { if (l

因此,当我尝试传递对象
Map>
时,我的代码显示编译器错误。如下

private static void logProgress(Map<String, Future<Cache<?>>> cacheLoaders, Map<String, Future<?>> cacheWriters)
            throws InterruptedException, ExecutionException {
        if (logFuturesAndCheckStillRunning("loader", cacheLoaders)
                && logFuturesAndCheckStillRunning("writer", cacheWriters)) {
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                logger.error("interrupted whilst log progress slept", e);
            }
            logProgress(cacheLoaders, cacheWriters);
        }
    }

    private static boolean logFuturesAndCheckStillRunning(String context, Map<String, Future<?>> futures)
            throws InterruptedException, ExecutionException {
        boolean areStillRunning = false;
        for (String key : futures.keySet()) {
            Future<?> future = futures.get(key);
            if (future.isDone()) {
                futures.remove(key);
                logger.info("{} future has completed: {}", context, future.get());
            } else {
                logger.info("{} future is still running: {}", context, future);
                areStillRunning = true;
            }
        }
        return areStillRunning;
    }
private static void logProgress(映射>缓存编写器)
抛出InterruptedException、ExecutionException{
if(LogFutures和CheckStillRunning(“加载器”,缓存加载器)
&&日志未来和检查仍在运行(“编写器”,缓存编写器)){
试一试{
时间单位。秒。睡眠(10);
}捕捉(中断异常e){
记录器错误(“在日志进程休眠时中断”,e);
}
日志进程(缓存加载程序、缓存写入程序);
}
}

private static boolean logfutures和checkstillrunning(字符串上下文,Map将示例进一步剥离,您尝试编译以下内容:

interface Cache<T> {}

static void logProgress(Map<String, Future<?>> futures) {}

public static void main (String[] args) {
    Map<String, Future<Cache<?>>> map = new HashMap<>();
    logProgress(map);  // Compiler error.
}



您的初始代码不起作用的原因是泛型在Java中是不变的:即使是
未来
,一个
映射将您的示例进一步剥离,您仍在尝试编译以下内容:

interface Cache<T> {}

static void logProgress(Map<String, Future<?>> futures) {}

public static void main (String[] args) {
    Map<String, Future<Cache<?>>> map = new HashMap<>();
    logProgress(map);  // Compiler error.
}



初始代码不起作用的原因是泛型在Java中是不变的:即使a
Future
、a
MAPI存在错误,请将它们附加到问题中(例如StackTrace).@Flown这是一个编译错误。@AndyTurner无论如何它应该在问题中。@Flown当然,但在这种情况下不要要求堆栈跟踪,就像你不会要求日志一样:)@AndyTurner我的第一条注释更改了,我忘了也更改了。例如,如果有错误,请将它们附加到你的问题中(例如StackTrace).@Flown这是一个编译错误。@AndyTurner无论如何它应该在问题中。@Flown当然,但在这种情况下不要要求堆栈跟踪,就像你不会要求日志一样:)@AndyTurner我的第一条评论更改了,我忘了也更改了i.e。谢谢你的解释,这肯定有帮助。很好。尤其是表意文字链接!谢谢你的解释,这肯定有帮助。很好。尤其是表意文字链接!
Map<String, ? extends Future<?>>
void logProgress(Map<String, Future<?>> futures) {
  Future<String> future = ...
  futures.put("", future);  // Compiler error, but let's pretend it's OK.
}

Map<String, Future<Cache<?>> map = new HashMap<>();
logProgress(map);  // Compiler error, but let's pretend it's OK.
Future<Cache<?>> future = map.values().iterator().next();
Cache<?> cache = future.get();  // ClassCastException here!
void logProgress(Map<String, ? extends Future<?>> futures) {
  futures.put("", Futures.immediateFuture("boom!")); // Compiler error.

  futures.put("", null);  // OK.
}