gpt4 book ai didi

java - 回到基础: Generics in Method Sig

转载 作者:行者123 更新时间:2023-12-01 07:48:19 26 4
gpt4 key购买 nike

因此,当我尝试传递对象 Map<String, Future<Cache<?>> 时,我的代码显示编译器错误到 Map<String, Future<?>> 的方法。如下...

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;
}

这应该可以工作,因为我的方法应该接受一个 Map,其中键是 String,值是任何类型的 Future。

下面显示我可以采用缓存加载器 future 并将其放入缓存写入器映射中,但我无法采用缓存写入器并将其放入缓存加载器映射中,因为缓存加载器映射中的 future 指定了 CacheLoader 泛型输入“在我的脑海中”是一个类似的概念。

            logger.info("starting cache loading");
Map<String, Future<Cache<?>>> cacheLoaders = startCacheLoading(injector, executorLoadingService);

logger.info("starting cache writing");
Map<String, Future<?>> cacheWriters = startCacheWriting(injector, executorWritingService);

Future<Cache<?>> aa = cacheLoaders.get("");
cacheWriters.put("", aa);

Future<?> bb = cacheWriters.get("");
cacheLoaders.put("", bb);

所以我的问题是......有人可以向我解释为什么原始代码片段有编译错误,以及是否有办法让我传递两个 Map 并丢失作为 Future 的值的类型?

最佳答案

进一步剥离你的示例,你正在尝试编译它:

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.
}

更改futures上的界限映射到:

Map<String, ? extends Future<?>>

Ideone demo

<小时/>

您的初始代码不起作用的原因是泛型在 Java 中是不变的:即使 Future<Cache<?>>Future<?> ,一个Map<String, Future<Cache<?>>不是Map<String, Future<?>> ,与 Map<String, Integer> 的方式大致相同。不是Map<String, Object> .

如果是的话,你的logProgress方法可以添加 Map<Future<SomethingOtherThanCache>>futures映射,导致返回时发生非类型安全的事情:

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!

相反,您需要使用上限 ( ? extends Future<?> ),这会导致 logProgress 出现编译器错误尝试将任何内容放入 map 中(除了文字 null )。

void logProgress(Map<String, ? extends Future<?>> futures) {
futures.put("", Futures.immediateFuture("boom!")); // Compiler error.

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

关于java - 回到基础: Generics in Method Sig,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44966119/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com