java解惑(谜题41到谜题)

本文通过四个具体的Java编程实例,揭示了程序设计中常见的陷阱与误区,并提供了改进方案。涉及异常处理、循环控制、递归调用等核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[b]谜题41:域和流[/b]
下面的方法实现将一个文件拷贝到另一个文件,但它[color=red]并非总是能够做到[/color]这一点,为什么不能呢?如何修改?
static void copy(String src,String dest) throws IOException{
InputStream in =null;
OutputStream out = null;
try{
in = new FileInputStream(src);
out = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int n;
while((n=in.read(buf))>=0){
out.write(buf);
}
}
finally{
if(in!=null) in.close();
if(out!=null)out.close();
}
}

问题在于finally自身,close方法也可能抛出IOException异常。如果正好发生在in.close()调用之时,就会阻止out.close 的调用,从而使输出流保持在开放状态。注意,该程序违反了谜题36的建议:[color=red]对close的调用可能会导致finally语句块意外结束[/color]。解决方式 是将每一个close都包含在一个嵌套的try语句块中。
[b]谜题42:异常为循环而抛[/b]
public class Loop {
public static void main(String[] args) {
int[][] tests = {{6,5,4,3,2,1},{1,2},{1,2,3},{1,2,3,4},{1}};
int count = 0;
try{
int i =0;
while(true){
if(thirdElemIsThree(tests[i++])) count ++;
}
}catch(ArrayIndexOutOfBoundsException e){
}

System.out.println(count);
}
private static boolean thirdElemIsThree(int[] a) {

return a.length>=3 & a[2] ==3;
}
}

打印出0
这个程序犯了两个错误,第1个错误是该程序使用了一种可怕的循环惯用法。不要使用异常控制循环;应该只为异常条件而使用异常。
为纠正这个错误,将整个try-finally语句块替换为循环遍历数组的标准惯用法:
for(int i = 0;i<tests.length;i++){
if(thirdElemIsThree(tests[i]))count++;
}
再次运行,会出现java.lang.ArrayIndexOutOfBoundsException异常,因为&运算符要计算两个操作数,改用短路的&&运算符。return a.length>=3 [color=red]&&[/color] a[2] ==3;
[b]谜题43:异常的危险[/b]
在jdk1.2中,Thread.stop、Thread.suspend以及其他许多线程相关的方法都因为不安全而不推荐使用了。
[b]谜题44:删除类[/b]
[color=red]要想编写一个能够探测类丢失的程序,请使用反射[/color]来引用类而不是使用通常的语言结构。如下程序展示了这种技巧:
try{
Object m = Class.forName("Missing").newInstance();
}catch(NoClassDefFoundError ex){
System.err.println("got it!");
}

[color=red]总之,不要对捕捉NoClassDefFoundError形成依赖。更一般地讲,捕获Error及其子类型几乎是完全不恰当的。[/color]
谜题45:令人疲惫不堪的测试

本谜题测试你对递归的了解程度,下面的程序将做些什么呢?
public class Workout {
public static void main(String[] args) {

workhard();
System.out.println("It's nap time");
}
private static void workhard() {

try{
workhard();
}finally{
workhard();
}
}
}

要不是有try-finally语句,行为非常明显:workhard递归调用自身,直到程序抛出StackOverflowError异常。但这个程序一直的在循环。因为一般VM将栈的深度限制为1024,因此,调用的数量就是1+2+4+。。。=2^1025-1,而抛出异常的数量是2^1024,没人能看到这个程序终止的时刻。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值