System.out与System.err的打印顺序

本文探讨了Java中标准输出(System.out)与标准错误输出(System.err)的不同之处,包括它们在操作系统层面的实现原理,以及在实际编程中的应用场景。特别强调了两者在缓存机制上的差异,解释了为何标准错误输出能即时显示而标准输出可能存在延迟。

现象

代码:

System.out.println("username: ");
System.err.println("password: ");
System.out.println("username: ");
System.err.println("password: ");
System.out.println("username: ");
System.err.println("password: ");

 

控制台输出:

 

password: 
password: 

username: 
username: 
username: 
password: 

解释

大多数操作系统都有三个标准文件描述符:标准输入,标准输出,标准出错。

对应Java中的System.in,System.out,System.err。

在语言层面的实现三个文件描述符都是可以重定向的(只要你想),

但是一般而言,如果你在unix shell或windows command line中使用管道或重定向,则只是针对标准输入和输出。

另外,标准输出和标准出错的一个区别是:标准输出往往是带缓存的,而标准出错没有缓存(默认设置,可以改)

所以如果你用标准出错打印出来的东西可以马上显示在屏幕,而标准输出打印出来的东西可能要再积累几个字符才能一起打印出来。

如果你在应用中混用标准输出和标准出错就可能看到这个问题。

总的来说,System.out用于正常的输出,也就是程序真正想输出的内容。而System.err用于出错信息的输出,也就是你本来不期待看到的东西。

因此,System.out可能会被缓冲,而System.err不会,由于System.err不需要缓冲即可输出,直接造成了我们视觉上看到的其位置的不确定性

### Java 中异常处理的执行顺序 在 Java 的异常处理机制中,`try-catch-finally` 结构用于捕获和处理程序运行过程中可能出现的异常。以下是关于 `ArithmeticException` 和 `NullPointerException` 这两类常见异常的具体分析。 #### 执行顺序详解 当代码进入 `try` 块时,程序会依次执行其中的每一条语句。如果某条语句引发了异常,则根据该异常的类型寻找匹配的第一个 `catch` 块并执行其内部逻辑[^1]。如果没有找到对应的 `catch` 块,或者异常未被任何已定义的 `catch` 处理,则此异常会被传递至更高层的方法调用链直至 JVM 终止当前线程的执行[^2]。 对于特定类型的异常如 `ArithmeticException` 或 `NullPointerException`: - **`ArithmeticException`**: 此类异常通常发生在算术运算错误的情况下,比如整数除零操作。 - **`NullPointerException`**: 当尝试访问或修改一个 null 对象引用上的成员变量或方法时触发。 这些异常均属于受检异常(unchecked exceptions),它们不需要强制声明 throws 子句即可抛出,但在实际开发中仍需注意合理设计以避免潜在问题。 #### 示例解析 以下是一个完整的 `try-catch-finally` 使用案例: ```java public class ExceptionExample { public static void main(String[] args) { try { int a = 0; int b = 5 / a; // This will throw ArithmeticException String str = null; System.out.println(str.length()); // This would cause NullPointerException if executed. } catch (ArithmeticException e) { System.err.println("Caught an ArithmeticException: Division by zero is not allowed."); } catch (NullPointerException e) { System.err.println("Caught a NullPointerException: Attempted to access method/property of 'null' object."); } finally { System.out.println("Finally block always executes regardless of exception occurrence or type."); } System.out.println("Continuing with the rest of program..."); } } ``` 上述例子展示了如何利用多级 `catch` 来分别捕捉不同类型的基础运行期异常,并通过 `finally` 确保无论是否有异常发生都会执行清理资源或其他必要动作的部分代码。 ### 关于为何某些异常无法被捕获的原因探讨 有时即使设置了广泛的 `catch` 范围仍然存在未能成功拦截的情况,这可能是由于以下几个因素造成的: - 错误地估计了可能产生的具体异常类别; - 高层次别的通用型父类异常放在较低位置导致更具体的子类异常先被执行跳过后续选项; - 特定场景下的并发或多线程环境干扰正常流程判断; 因此,在编写涉及复杂业务逻辑的应用软件时,应当仔细审查所有可能导致失败的操作路径,并相应调整自己的防御策略。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值