【发布时间】:2018-03-17 03:10:35
【问题描述】:
我编写了这段代码,但是我不确定为什么会得到如图所示的编译行为。最终对象dataMap 已在构造函数内部分配,因为它通常是这样做的,并且 Lambdas 被懒惰地评估。如果我去掉 final 修饰符,代码编译得很好。
ConsumerTest.java:17: error: variable dataMap might not have been initialized
dataMap.compute(DataType.EVENS, (k, v) -> {
^
ConsumerTest.java:29: error: variable dataMap might not have been initialized
dataMap.compute(DataType.ODDS, (k, v) -> {
^
2 errors
成员变量dataMap 声明为final,并在构造函数中初始化。为什么编译器无法识别这一点并抱怨呢?
import java.util.*;
import java.util.function.IntConsumer;
import java.util.stream.IntStream;
public class ConsumerTest {
enum DataType {
EVENS,
ODDS
}
private final Map<DataType, Set<Integer>> dataMap;
private final IntConsumer allConsumers;
private IntConsumer evenConsumer = e -> {
if (e % 2 == 0) {
dataMap.compute(DataType.EVENS, (k, v) -> {
if (v == null) {
v = new HashSet<>();
}
v.add(e);
return v;
});
}
};
private IntConsumer oddConsumer = e -> {
if (e % 2 != 0) {
dataMap.compute(DataType.ODDS, (k, v) -> {
if (v == null) {
v = new HashSet<>();
}
v.add(e);
return v;
});
}
};
public ConsumerTest() {
dataMap = new HashMap<>();
allConsumers = evenConsumer.andThen(oddConsumer);
}
public static void main(String[] args) {
ConsumerTest main = new ConsumerTest();
IntStream.range(10, 31).forEach(main.allConsumers);
System.out.println(main.dataMap);
}
}
【问题讨论】:
-
你只需要初始化它,比如
private final Map<DataType, Set<Integer>> dataMap = new Map(); -
@AnthonyKong
Map是一个接口,不能被实例化。你的意思可能是new HashMap<>() -
那么
HashMap怎么样?它是您的程序,最终只有您知道要使用哪种数据结构。 -
@AnthonyKong,dataMap 在下面的构造函数中初始化。这里有趣的部分是,通过删除 final 修饰符,这是可行的。
-
投反对票的人应该注意解释他们这样做的原因