我对 try catch 块有这种奇怪的行为。当我在其中初始化变量时,即使我在外面声明它们,它们似乎超出了以下代码的范围。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFile {
public static void main(String[] args) {
FileInputStream fis;
FileOutputStream fos;
args[0] = "somefile.txt";
args[1] = "copyithere.txt";
int i;
try {
try {
fis = new FileInputStream(args[0]);
} catch (FileNotFoundException e) {
System.out.println("Input file not found");
e.getMessage();
}
try {
fos = new FileOutputStream(args[1]);
} catch (FileNotFoundException e) {
System.out.println("Output file not found");
e.printStackTrace();
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Give input and output file name");
e.getStackTrace();
}
try {
do {
i = fis.read();
fos.write(i);
} while (i != -1);
} catch (IOException e) {
System.out.println("Some IO exception");
e.getMessage();
}
}
}
奇怪的是,当我将变量声明为空"文件输入流 fis = 空;然后一切都变好了..没有初始化的声明不等同于初始化为 null..? 另一种摆脱"超出范围错误"的方法是当我在捕获块的末尾放置"return;"时。代码不应该在没有它的情况下运行良好吗?我可以看到这如何导致错误,但这如何与"fis 和 fio 的范围外错误"联系起来?
没有初始化的声明不等同于初始化 到空..?
在局部变量的情况下不行。创建实例时,仅初始化实例变量。
摆脱"超出范围错误"的另一种方法是当我把 "返回;">
您应该使用 Java 7 中引入try with resources
块。它将自动关闭流,例如:
int i;
try(FileInputStream fis = new FileInputStream(args[0]);
FileOutputStream fos = new FileOutputStream(args[1]);){
do {
i = fis.read();
fos.write(i);
} while (i != -1);
}
没有初始化的声明不等同于初始化 为空?
局部变量只需要由程序员初始化,其中作为类的实例变量将由 JVM 在对象创建期间使用其默认值(基于类型)进行初始化。
摆脱"超出范围错误"的另一种方法是当我把 "返回;"在捕获块的末尾。代码不应该只是运行吗 没有它好吗?
这里有两种可能性:
(1)绿色路径场景:如果第一个try
块中没有FileNotFoundException
,那么fis
变量就会初始化成功,所以不会有任何错误。
(2)红色路径场景:fis
不会在第一个try
块中的FileNotFoundException
上初始化,所以如果你从第一个catch
块本身return
,那么在最后一个try
块中不需要fis
变量(因为这些行永远不会被执行,因为你是从中间返回的), 所以没有初始化错误。
当我从方法中取出声明并使它们静态时 也有效..你知道这种区别的原因是什么吗?
static
变量将由 JVM 使用默认值(如实例变量)进行初始化,因此如果您将它们标记为static
,则不会有任何变量初始化错误(JVM 已经初始化了它们)。