Hello World的Bug

最近看到一篇挺有意思的文章,国外一程序员发现,很多语言实现的 Hello World 程序都有 Bug。

比如在Java中,Hello World一般是:

class hello{
    public static void main(String[] args){
        System.out.println("hello world");
    }
}

正常情况下运行如下:

$ javac hello.java
$ java hello
hello world

但如果我们将它重定向输出到/dev/full文件:

/dev/full:满设备。任何写入都将失败,并把errno设为ENOSPC(没有剩余空间)

$ java hello > /dev/full

可以看到程序没有任何输出,查看程序返回值:

$ echo $?
0

此时发现程序返回0,说明并没有报错。

然而我们知道程序重定向输出到/dev/full肯定是报错的,而返回值却显示没有报错,因此就有bug。

究其原因,是因为在输出流System.out.println("hello world");中,即使报错了也不会抛出异常,

A PrintStream adds functionality to another output stream, namely the ability to print representations of various data values conveniently. Two other features are provided as well. Unlike other output streams, a PrintStream never throws an IOException; instead, exceptional situations merely set an internal flag that can be tested via the checkError method.
PrintStream为另一个输出流添加了功能,即能够方便地打印各种数据值的表示。还提供了另外两个功能。与其他输出流不同,PrintStream从不抛出IOException;相反,异常情况只是设置了一个内部标志,可以通过checkError方法进行测试。

也就是说System.out.println("hello world");输出之后,永远不会抛出IO异常,需要手动通过checkError去判断有没有报错,于是改进如下:

class hello{
    public static void main(String[] args){
        System.out.println("hello");
        boolean hasError = System.out.checkError();
        if(hasError){
            System.exit(1);
        }
    }
}

运行程序:

$ javac hello.java
$ java hello
hello
$ java hello > /dev/full
$ echo $?
1

可以看到改进后的代码重定向输出到/dev/full后正确报错了。

所以开发的时候最好不要用System.out.println()输出,即使用也要判断一下输出后有没有报错,不然可能程序报错了也不知道。

事实上不止Java有这个问题,很多语言都有,原作者还测试了其他语言,C、C++、Go都有这个问题,详见:https://github.com/sunfishcode/hello-world-vs-io-errors

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值