Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 编译器抱怨未处理的IOException,即使函数签名抛出它_Java - Fatal编程技术网

Java 编译器抱怨未处理的IOException,即使函数签名抛出它

Java 编译器抱怨未处理的IOException,即使函数签名抛出它,java,Java,我有一个类,其中静态工厂方法使用computeIfAbsent()返回实例: public class TrafficMonitor { private static ConcurrentMap<String, TrafficMonitor> instances = new ConcurrentHashMap<>(); private String busNumber; //private constructor could throw an IOEx

我有一个类,其中静态工厂方法使用
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);
   }

}
公共类流量监视器{
私有静态ConcurrentMap实例=新ConcurrentHashMap();
专用字符串总线号;
//私有构造函数可能引发IOException
专用流量监视器(字符串busNumber)引发IOException{
this.busNumber=总线号;
//它需要在构造函数中,因为它调用第三方API来实例化抛出IOException的对象
doIoOperation();
}
//返回此类实例的静态工厂方法
公共静态流量监视器forBus(字符串busNumber)引发IOException{
//编译器错误:未处理的异常:java.io.IOException
返回instances.computeIfAbsent(总线号,流量监视器::新建);
}
}
私有构造函数抛出IOException,在静态工厂函数中
forBus(String busNumber)
即使我在签名中有
抛出IOException
,编译器仍然抱怨
未处理的异常:java.io.IOException
。为什么?如何摆脱它


另一个问题:在本例中,
TrafficMonitor::new
是否自动从
forBus(字符串busNumber)中获取参数
函数或它如何使用私有构造函数创建实例,该构造函数需要一个参数
字符串busNumber

ComputeFabSent
需要一个
函数作为参数。函数SAM的签名是
R apply(T)
。如您所见,
函数
可能不会引发
IOException
。但是您的构造函数确实抛出了一个
IOException
。所以
TrafficMonitor::new
不是一个函数。因此,您不能将其作为参数传递给
computeIfAbsent()

清洁方式:不要在构造函数中执行IO:

public class TrafficMonitor {
    private static ConcurrentMap<String, TrafficMonitor> instances = new ConcurrentHashMap<>();
    private String busNumber;
    private boolean initialized;

    private TrafficMonitor(String busNumber) {
        this.busNumber = busNumber;
    }

    private synchronized void initialize() throws IOException {
        if (!initialized) {
            doIoOperation();
            initialized = true;
        }
    }

    public static TrafficMonitor forBus(String busNumber) throws IOException {
        TrafficMonitor result = instances.computeIfAbsent(busNumber, TrafficMonitor::new);
        result.initialize();
        return result;
   }
}


ComputeFabSent需要一个函数作为参数。函数SAM的签名是
R apply(T)
。如您所见,函数可能不会引发IOException。但是你的构造函数确实抛出了一个IOException。所以TrafficMonitor::new不是一个函数。因此,您不能将其作为参数传递给ComputeFabSent()。也许您是对的,我不熟悉双冒号,如何消除它?消除它的干净方法是避免在构造函数中执行IO操作。构造函数不应该这样做。它应该创建一个对象。不太干净的方法是传递一个lambda来调用构造函数,捕获IOException,并将其作为运行时异常重新调用。
构造函数不应该这样做
,嗯,没有这样的规则,我认为这取决于具体情况。在我的例子中,这样做是有意义的,因为我的类是第三方API的包装,它在实例化期间抛出
IOException
。话虽如此,如果您能为您的答案提供代码示例,那就太好了。
SAM
在您的答案中代表什么?单一抽象方法。这是接口必须满足的条件,才能成为功能接口,即能够用作lambda或方法引用的类型。我喜欢干净的方式,但如果仔细查看我的
forBus(String busNumber)
,它违反了我试图实现的逻辑,
TrafficMonitor
的实例与相同的
busNumber
的实例相同。也就是说,它是每个
busNumber
的“单例”。只有在创建
TrafficMonitor
的新实例时,才应执行
doIoOperation()
。您可以修改您的清洁解决方案代码以满足此要求吗?哦,是的,您有一个布尔标志来控制初始化。
private TrafficMonitor(String busNumber) {
    this.busNumber = busNumber;
    try { 
        doIoOperation();
    } catch(IOException e) {
        throw UnchedkIOException(e);
    }
}
public static TrafficMonitor forBus(String busNumber) {
    return instances.computeIfAbsent(busNumber, busNumber -> {
        try {
            return new TrafficMonitor(busNumber);
        } catch(IOException e) {
            throw UnchedkIOException(e);
        }
    });
}