【发布时间】:2020-02-10 10:50:44
【问题描述】:
我有一个类,其中静态工厂方法使用computeIfAbsent()返回一个实例:
public class TrafficMonitor {
private static ConcurrentMap<String, TrafficMonitor> instances = new ConcurrentHashMap<>();
private String busNumber;
//private constructor could throw an IOException
private TrafficMonitor(String busNumber) throws IOException {
this.busNumber = busNumber;
// it needs to be in constructor because it call a 3rd party API to instantiate an object which throws IOException
doIoOperation();
}
// static factory method to return a instance of this class
public static TrafficMonitor forBus(String busNumber) throws IOException {
// Compiler error: Unhandled exception: java.io.IOException
return instances.computeIfAbsent(busNumber, TrafficMonitor::new);
}
}
私有构造函数在静态工厂函数forBus(String busNumber) 中抛出IOException,即使我在签名中有throws IOException,编译器仍然会抱怨unhandled exception: java.io.IOException。为什么?如何摆脱它?
另一个问题:在这个例子中,TrafficMonitor::new 是否会自动从forBus(String busNumber) 函数中获取参数/参数busNumber,或者它如何使用需要参数String busNumber 的私有构造函数创建实例?
【问题讨论】:
-
computeIfAbsent 需要一个函数作为参数。 Function 的 SAM 的签名是
R apply(T t)。如您所见,函数可能不会抛出 IOException。但是您的构造函数确实会引发 IOException。所以 TrafficMonitor::new 不是一个函数。所以你不能把它作为参数传递给 computeIfAbsent()。 -
也许你是对的,我对双冒号不熟悉,如何摆脱它?
-
摆脱它的干净方法是避免在构造函数中执行 IO 操作。构造函数不应该这样做。它应该创建一个对象。不太干净的方法是传递一个调用构造函数、捕获 IOException 并将其作为运行时异常重新抛出的 lambda。
-
A constructor isn't supposed to do that,好吧,没有这样的规则,我认为这取决于。就我而言,这样做是有意义的,因为我的类是第 3 方 API 的包装器,它在实例化期间抛出IOException。话虽如此,如果您能为您的答案提供代码示例,那就太好了。
标签: java