在处理我应该处理的3个异常时,我在实现以下方法时遇到了一些麻烦。 我应该像我正在做的那样包含try / catch块,还是要留给应用程序而不是类设计?
该方法说我应该实现这个:
public Catalog loadCatalog(String filename)
throws FileNotFoundException, IOException, DataFormatException
此方法从产品目录中指定的存档中加载信息并返回目录。
首先打开文件进行阅读。然后继续阅读并处理文件的每一行。
方法String.startsWith
用于确定行的类型:
处理完生产线后,loadCatalog
会将产品(产品,咖啡或酿酒商)添加到产品目录中。
当处理完文件的所有行后,loadCatalog
会将产品目录返回给进行调用的方法。
此方法可能会抛出以下异常:
FileNotFoundException
- 如果指定的文件不存在。 IOException
- 如果读取指定文件的信息时出错。 DataFormatException
- 如果某行有错误(例外必须包含错误数据的行)这是我到目前为止所做的:
public Catalog loadCatalog(String filename)
throws FileNotFoundException, IOException, DataFormatException{
String line = "";
try {
BufferedReader stdIn = new BufferedReader(new FileReader("catalog.dat"));
try {
BufferedReader input = new BufferedReader(
new FileReader(stdIn.readLine()));
while(! stdIn.ready()){
line = input.readLine();
if(line.startsWith("Product")){
try {
readProduct(line);
} catch(DataFormatException d){
d.getMessage();
}
} else if(line.startsWith("Coffee")){
try {
readCoffee(line);
} catch(DataFormatException d){
d.getMessage();
}
} else if(line.startsWith("Brewer")){
try {
readCoffeeBrewer(line);
} catch(DataFormatException d){
d.getMessage();
}
}
}
} catch (IOException io){
io.getMessage();
}
}catch (FileNotFoundException f) {
System.out.println(f.getMessage());
}
return null;
}
答案 0 :(得分:4)
这取决于您是希望使用它的类或应用程序的其他部分来处理异常并执行所需的操作。
由于使用loadCatalog()
可能的代码不知道如何处理文件I / O或格式异常,个人而言,我会创建一个异常比如CatalogLoadException
并从loadCatalog()方法中抛出它,并将原因异常(FileNotFoundException
,IOException
,DataFormatException
)放入其中同时根据触发的异常包含信息性消息。
try {
...
//do this for exceptions you are interested in.
} catch(Exception e) {
//maybe do some clean-up here.
throw new CatalogLoadException(e); // e is the cause.
}
这样,您的loadCatalog()
方法只会抛出一个有意义的异常。
现在使用loadCatalog()
的代码只需要处理一个例外:CatalogLoadException
。
loadCatalog(String filename) throws CatalogLoadException
这也允许您的方法隐藏其实施细节,这样您就不必在基础低级别结构发生变化时更改其“异常抛出”签名。请注意,如果您更改此签名,则每段代码都需要相应更改以处理您引入的新类型的异常。
请参阅Exception Translation上的这个问题。
投掷签名要求的更新:
如果您 保留该签名,那么您实际上无法选择throw
他们到应用程序而不是catch
他们在{{1}内方法,否则loadCatalog()
签名将是无用的,因为我们不会抛出我们刚才处理的完全相同的异常。
答案 1 :(得分:1)
一般的想法是,您将异常渗透到适当的位置以处理它们。我猜你的教练希望他们能在主要的时候处理。在这种情况下,我可以猜测,因为你得到了抛出条款。一个简单的经验法则是,如果方法在throws子句中声明了异常,则不会在该方法中捕获它。所以你写的方法应该没有catch语句。
为此,您可以更改代码:
public Catalog loadCatalog(String filename)
throws FileNotFoundException,
IOException,
DataFormatException
{
String line = "";
BufferedReader stdIn = new BufferedReader(new FileReader("catalog.dat"));
BufferedReader input = new BufferedReader(new FileReader(stdIn.readLine()));
while(!stdIn.ready())
{
line = input.readLine();
if(line.startsWith("Product"))
{
readProduct(line);
}
else if(line.startsWith("Coffee"))
{
readCoffee(line);
}
else if(line.startsWith("Brewer"))
{
readCoffeeBrewer(line);
}
}
return null;
}
然后在调用loadCatalog的方法(可能是main)中:
try
{
loadCatalog(...);
}
catch(FileNotFoundException ex)
{
ex.printStackTrace();
}
catch(IOException ex)
{
ex.printStackTrace();
}
catch(DataFormatException ex)
{
ex.printStackTrace();
}
用适当的东西替换printStackTrace。
这样方法loadCatalog不处理显示错误消息,因此您可以在GUI或控制台代码中调用该方法,并且调用它的代码可以选择如何向用户显示错误(或交易)用它来某种方式)。
答案 2 :(得分:0)
这是Heinz Kabutz的一篇优秀文章,涉及异常处理。