金溪县 腾冲县 施甸县 固镇县 库车县 枝江市 桐乡市 永登县 贺州市 措美县 鸡东县 慈利县 伊宁市 靖宇县 塔河县 肥城市

tiffany_对scanner.close方法的误解以及无法补救的错误

标签:三叉戟 温岭麻将怎么打

scanner错误关闭导致的异常

public class test2 {

  public static void main(String[] args) {
    Scanner scanner1 = new Scanner(System.in);
    System.out.println("run scanner1.close()");
    scanner1.close();

    Scanner scanner2 = new Scanner(System.in);
    System.out.println("run scanner2.nextLine()

但是会在scanner2.nextLine()调用时抛出异常
java.util.NoSuchElementException: No line found

原因

下面是scanner的源码

// The input source
    private Readable source;
public void close() {
        if (closed)
            return;
        if (source instanceof Closeable) {
            try {
                ((Closeable)source).close();
            } catch (IOException ioe) {
                lastException = ioe;
         天籁之声_2018年最新新闻网   }
        }
        sourceClosed = true;
        source = null;
        closed = true;
    }

所以调用close方法并不仅仅关闭scanner类,同时关闭了初始化时作为参数传入的Readable对象。
在示例代码中scanner1.close();关闭了System.in,所以虽然初始化scanner2没有问题,但是readLine()会报错。

是否可以通过重武道宗师_2018年最新新闻网新开启System.in的方式补救呢?

遗憾的是,至少作为java的使用者来说是不可以的,除非我们能控制jvm运行。
这涉及到System.in是如何开启的,简单来说因为System.in是特殊的系统资源,由jvm负责开启,无法通过java代码重新初始化System.in。
如果查看System.in的代码我们就能发现它通过native方法实现初始化,在native方法中将控制台校园篮球风云_2018年最新新闻网或文件句柄传输给System.in来完成。
同样的,Systerm.out System.err也是无法重新被开启的资源,对于它们,close方法应该被谨慎的调用。
(ps:实际上有什么原因关闭呢?)

让我们把问题拓展开来

实际上,所有的能够以System.in/out/err为构造器参数的包装器类的close方法都应该被考虑,
可以看到jdk的设计者并没有区别对待普通的流和System.in/out/err,
而包装器类的close方法关闭底层流对于普通流来说是很合理的,因此我们可以推测事实上其他的包装器的close方法也可能导致关闭System.in/out/err。
常用的bufferinputstream就是如此。

jdk7引入的带资源的try语法糖产生隐蔽的问题

jdk7引入的带资源的try语法糖隐式的帮助程序员调用close方法,
遗憾的是该方法也会产生上述问题,甚至更难被发现。

我们有必要积极的关闭不再需要的流嘛?如何对待io.close?如何预防该问题?

从性能的角度来说,积极关闭流是必须的,实际上如果我们使用findbugs等代码规范工具,能发现关闭io是被强烈推荐的。
如果你使用idea的话,建议在close之前,使用快捷键c灵山_2018年最新新闻网trl+b进入close方法的源我不是潘金莲_2018年最新新闻网代码来查看其关闭机制。这种方法非常简便,当然eclipse应该也有插件可以实现类似功能。
我们也可以通过包装System.in/out/err来安全的使用它们,实际上利用装饰器模式,覆盖System.in/out/err的close方法即可。

当前文章:http://hb7a-beipeichang-com.hljrb78.tw/iz02/9395b_158621.html

发布时间:2019-07-18 01:25:56

茅台集团换帅,李保芳接棒袁仁国成新一任董事长  银河优越会会员申请  澳门银河手机网站俄罗斯红场5月4日至9日将关闭参观  澳门银河官网真人娱乐  澳门银河官网手机app  银河娱乐首页yh163am.com  银河娱乐是正规网站吗  澳门银河送彩金罗晋拍打戏拒用替身:受不了动作戏不真实  澳门银河yh7788.bet  2288银河主站线路检测  

用手机访问
下载APP
appicon 下载
扫一扫,手机浏览
code
休闲娱乐
综合热点资讯
单机游戏下载

精彩专栏
游民星空联运游戏