在使用java.nio.channels.Selector
对象时,我不禁注意到工厂创建方法Selector.open()
会抛出IOException。
除了处理另一个IOException的痛苦之外,我不知道如何打开选择器可能是一个I / O操作,更不用说失败并抛出IOException。
要打开的Selector类中的代码如下:
public static Selector open() throws IOException {
return SelectorProvider.provider().openSelector();
}
注意它遵循我去查看openSelector()代码的SelectorProvider
对象。如下:
public abstract AbstractSelector openSelector()
throws IOException;
看起来这个类是在运行时动态加载的,这使得构造这些选择器的方式更加神秘。
如果“动态加载”失败,负责创建Selector的类是sun.nio.ch.DefaultSelectorProvider
,我没有源代码,所以就我追踪IOException的来源而言,我可以这么做
Java选择器上的javadoc根本没有帮助:
抛出:IOException - 如果发生I / O错误
如果有人对Selector.open()创建的这个市场IOException有任何见解,请告诉我。另外回答一个更实际的问题,如果IOException被“正确”处理(例如消息框,闪烁灯,工具包发出哔哔声等)或者只是隐藏在一个log / empty catch块中。
答案 0 :(得分:3)
简短的回答是它的平台和实现具体,所以你几乎别无选择;你应该抓住它并处理它。而且因为这将是一个非常罕见的事件(之后你将没有Selector
),它可能是一个钟声和口哨的事情。选项B忽略它并让它击中堆栈顶部并停止运行。
答案很长,在Linux上,使用当前的默认实现,它不会抛出。如果它是> = 2.6内核,则openSelector()
将实例化并返回EPollSelectorImpl
。如果它是< 2.6你得到PollSelectorImpl
。这些类的构造函数都没有抛出IOException
。
但是,在Windows上,您会得到一个WindowsSelectorImpl
,其构造函数 抛出IOException
。我必须深入挖掘,找出会导致它的原因,但显然可以做些什么。
同样,这是一个实现细节,所以它可能在将来总是发生变化。
您可以提取openjdk的完整源代码来查看这些类的源代码。
答案 1 :(得分:2)
它允许实现抛出IOExceptions,原因自然是在API级别未指定。例如,Selector
的Windows实现使用一个选择树,其内部节点是管道,用于处理可选择通道数超过Windows最大值的情况。因此Selector必须能够打开管道,这可能会失败。