我写了这个方法,我想处理UnexpectedFormatExceptions
:更具体地说,是MissingFieldException
,EmptyFieldException
,UnknownCardTypeException
,UnknownSpellCardException
。
问题是我不完全理解处理异常的想法。现在,我创建了一个类UnexpectedFormatExceptions
(如前所述)和子类与构造函数等。我是否应该添加try
块来获取每个异常的整个代码和catch
块?这里有什么正确的行动方案?
public ArrayList<Card> loadCardsFromFile(String path) throws IOException, FileNotFoundException, UnexpectedFormatException {
String currentLine = "";
FileReader fileReader = new FileReader(path);
@SuppressWarnings("resource")
BufferedReader br = new BufferedReader(fileReader);
String[] currentsplit;
ArrayList<Card> temp = new ArrayList<Card>();
while ((currentLine = br.readLine()) != null) {
currentsplit = currentLine.split(",");
if (currentsplit[0].equals("Monster")) {
MonsterCard x = new MonsterCard(currentsplit[1], currentsplit[2], Integer.parseInt(currentsplit[5]),Integer.parseInt(currentsplit[3]), Integer.parseInt(currentsplit[4]));
temp.add(x);
}
else {
if (currentsplit[1].equals("Card Destruction")) {
CardDestruction x = new CardDestruction(currentsplit[1], currentsplit[2]);
temp.add(x);
}
if (currentsplit[1].equals("Change Of Heart")) {
ChangeOfHeart x = new ChangeOfHeart(currentsplit[1], currentsplit[2]);
temp.add(x);
}
if (currentsplit[1].equals("Dark Hole")) {
DarkHole x = new DarkHole(currentsplit[1], currentsplit[2]);
temp.add(x);
}
if (currentsplit[1].equals("Graceful Dice")) {
GracefulDice x = new GracefulDice(currentsplit[1], currentsplit[2]);
temp.add(x);
}
if (currentsplit[1].equals("Harpie's Feather Duster")) {
HarpieFeatherDuster x = new HarpieFeatherDuster(currentsplit[1], currentsplit[2]);
temp.add(x);
}
if (currentsplit[1].equals("Heavy Storm")) {
HeavyStorm x = new HeavyStorm(currentsplit[1], currentsplit[2]);
temp.add(x);
}
if (currentsplit[1].equals("Mage Power")) {
MagePower x = new MagePower(currentsplit[1], currentsplit[2]);
temp.add(x);
}
if (currentsplit[1].equals("Monster Reborn")) {
MonsterReborn x = new MonsterReborn(currentsplit[1], currentsplit[2]);
temp.add(x);
}
if (currentsplit[1].equals("Pot of Greed")) {
PotOfGreed x = new PotOfGreed(currentsplit[1], currentsplit[2]);
temp.add(x);
}
if (currentsplit[1].equals("Raigeki")) {
Raigeki x = new Raigeki(currentsplit[1], currentsplit[2]);
temp.add(x);
}
}
}
return temp;
}
答案 0 :(得分:1)
但我并不完全理解处理例外的想法。
类比:
正常代码流程
火车正在赛道上运行。
例外流程
火车离开赛道(出轨)
异常处理:
让火车回到正轨。
我是否应该添加一个try块来获取整个代码并捕获块 每个例外?或者我该怎么办?
仅为最后一个语句块捕获适当的异常。尽量保持try-catch块尽可能小,并且只使用适当的try-catch块包围必要的代码块。
您也可以选择使用这种新语法(Java 7):
try {
// statements
} catch (MissingFieldException|EmptyFieldException|UnknownCardTypeException|UnknownSpellCardException ex) {
logger.log(ex);
throw ex;
}
答案 1 :(得分:0)
“但我不完全理解处理异常的想法。”
异常只是无法遵循正常的程序流程。
因此,如果无法遵循正常流程,则使用异常处理可以对“非正常”流程采取措施。
FileNotFoundException
是一个简单的试图说明:
所以
try {
...statements to open a file and read its contents...
} catch (FileNotFoundException fnfe) {
// maybe print out an error message to the user
// or set a flag
// etc
}
如果您不希望某个方法处理Exeption,那么您可以将Exception处理委托给“外部”方法或调用者,方法是让代码“抛出异常”,但是在某个地方“我需要做try / catch来处理它,就像我上面所示。
答案 2 :(得分:0)
例外是一个非常棘手的话题 - 至少IMO-很难掌握。很多时候会出现关于抛出什么异常,在哪里处理它们或者是否抛弃它们(等等)的分歧。如果你想掌握它们,你可能需要大量的阅读,特别是用坏的异常方法来焚烧自己。我有时会相当通用,给你留下很多设计决定。但是我对你的代码做了一些评论和建议。
我是否应该添加
try
块来获取每个例外的整个代码和catch
块?
No. No, no, no, NO!当您试图找出代码的哪一部分实际上抛出了Exception
时,它可能会让您的生活变得艰难。但不仅如此。在Google /这里搜索“尝试抓住一切”或类似的内容以查看其他参数 - 我的答案已经足够长了。
就个人而言,我将你的方法分成三个:我有一个从文件中读取并将内容放入ArrayList<String>
的方法,然后我将ArrayList<String>
传递给它方法,对于String
中的每个ArrayList
,我会尝试创建Card
*。分离它们也会使你的方法更容易(单元)测试。这是结构
public ArrayList<String> loadRowsFromFile(String path) throws IOException, FileNotFoundException {
// whatever
}
// up to you if you want this to throw UnexpectedFormatException
public ArrayList<Card> loadCardsFromFile(ArrayList<String> cardsList) throws UnexpectedFormatException {
// whatever
}
public Card buildCardFromString(String card) throws MissingFieldException, EmptyFieldException, UnknownCardTypeException, UnknownSpellCardException {
// whatever
}
我认为如果你考虑一下你的方法合同会有所帮助:我的方法需要什么作为输入?我的方法根据输入产生什么?它应该与任何输入一起使用吗?它是否只能用于某些输入并抛出异常并让调用代码处理它们?如果card
或cardsList
为null
(或为空),您可能需要抛出IllegalArgumentException
或提供一些默认行为,具体取决于您的需求 - 您需要考虑它们。从Card
/空null
中生成String
是否有意义?从[{1}} /空ArrayList<Card>
中获得null
是否有意义?如果答案是“否”,则无论如何抛出(相关)异常。不要为糟糕的输入创建变通方法。它会让你的代码变成一场噩梦。
最容易分析的是cardsList
。这是一种预期会从文件中生成行列表的方法。但是如果loadRowsFromFile
无效,那么继续进行是没有意义的,因为它无法履行其合同:path
从无效文件/路径生成出来最明智的是什么?一般来说,可能没有。因此,抛出相关的异常是有意义的。调用它的代码需要处理这个异常,或者,如果没有预期,或者处理这个异常没有意义,它应该把它放到调用堆栈的上方。
有特定的例外(例如ArrayList<Card>
,MissingFieldException
等)可以清理代码并帮助调试和解决异常,但同样,它实际上取决于你想要处理它们的位置或方式。例如,一个图层可能需要特定的例外情况,然后它会将它们重新抛出更高的位置,而EmptyFieldException
表示更常见的例外情况。
*您可能真的想查看factory method pattern。