使用异常处理实现 Iterator 接口
Implementing Iterator interface with exception handling
我需要创建一个 class 库,它使我能够读取不同的文件(内部具有不同数据表示的 .dat 文件)并使用其内容创建对象(每一行一个对象)。
我还必须创建一个开始读取文件的单元测试,这样我就不必先读取整个文件并将内容保存在数组中。我想用工厂模式。
这是我实现的 class 实现迭代器接口
package klassenbibliothek;
public class MyReader implements Iterator<Object>
{
BufferedReader reader;
MyReader(BufferedReader myReader)
{
reader = myReader;
}
@Override
public boolean hasNext() // aus Whosebug, von mir abgeändert
{
try {
return reader.ready();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
throw new NoSuchElementException();
}
}
@Override
public String next()
{
//return SubstancesFileObjectCreator(reader.readLine());
try {
return reader.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
// return null;
throw new NoSuchElementException();
}
}
}
我的问题是:为什么我会收到此错误消息 "finally block does not complete normally"?我没有返回任何东西,我只是抛出一个异常。
我想在单元测试中使用 hasNext() 和 next() 方法,以便单元测试可以控制何时开始读取文件。单元测试在不同的包中。
这是我的其他 classes:
class AbstractFileObjectCreator
package klassenbibliothek;
public abstract class AbstractFileObjectCreator
{
public abstract AbstractFileObject createFileObject(String line);
}
class 物质文件对象创建器
package klassenbibliothek;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class SubstancesFileObjectCreator extends AbstractFileObjectCreator
{
MyReader myReader;
public void makeReader() throws IOException
{
String dataFileName = "C:/temp/Substances.dat";
BufferedReader bReader = new BufferedReader(new FileReader(dataFileName));
myReader = new MyReader(bReader);
}
@SuppressWarnings("null")
public AbstractFileObject createFileObject(String line)
{
AbstractFileObject mySubstance = null;
String lineValues[] = myReader.next().split("\t");
if(lineValues[0].equals("R"))
{
boolean dutyToDeclare_local;
boolean isUnwanted_local;
boolean isProhibited_local;
boolean isReach_local;
boolean isDeleted_local;
boolean isHidden_local;
String nodeidRaw = lineValues[1];
float nodeid = Float.parseFloat(nodeidRaw);
String casNrRaw = lineValues[2];
String euIndexCodeRaw = lineValues[3];
String einecsCodeRaw = lineValues[4];
String dutyToDeclareRaw = lineValues[5];
if(dutyToDeclareRaw.equals(1))
{
dutyToDeclare_local = true;
}
else
{
dutyToDeclare_local = false;
}
String isUnwantedRaw = lineValues[6];
if(isUnwantedRaw.equals("1"))
{
isUnwanted_local = true;
}
else
{
isUnwanted_local = false;
}
String isProhibitedRaw = lineValues[7];
if(isProhibitedRaw.equals("1"))
{
isProhibited_local = true;
}
else
{
isProhibited_local = false;
}
String isReachRaw = lineValues[8];
if(isReachRaw.equals("1"))
{
isReach_local = true;
}
else
{
isReach_local = false;
}
String isDeletedRaw = lineValues[9];
if(isDeletedRaw.equals("1"))
{
isDeleted_local = true;
}
else
{
isDeleted_local = false;
}
String isHiddenRaw = lineValues[10];
if(isHiddenRaw.equals("1"))
{
isHidden_local = true;
}
else
{
isHidden_local = false;
}
mySubstance = new Substance(nodeid, casNrRaw, euIndexCodeRaw, einecsCodeRaw, dutyToDeclare_local, isUnwanted_local, isProhibited_local, isReach_local, isDeleted_local, isHidden_local);
// und weiter...
}
else
{
String languageCode = lineValues[1];
String name = lineValues[2];
// Synonym-Objekt erzeugen und zu Substance-Objekt hinzufügen
Synonym newSynonym = new Synonym(languageCode, name);
mySubstance.addAppendix(newSynonym);
while(myReader.hasNext())
{
String lineValues_synonyms[] = myReader.next().split("\t");
String lineValuesZero = lineValues_synonyms[0];
if(lineValuesZero.equals("R"))
{
break; // nicht so gut glaube ich!!!
}
String languageCode_next = lineValues_synonyms[1];
String name_next = lineValues_synonyms[2];
Synonym newSynonym_next = new Synonym(languageCode_next, name_next);
mySubstance.addAppendix(newSynonym_next);
}
}
return mySubstance;
}
}
class 抽象文件对象
package klassenbibliothek;
public abstract class AbstractFileObject
{
boolean isDeleted;
public AbstractFileObject(boolean isDeleted)
{
this.isDeleted = isDeleted;
}
public boolean getIsDeleted()
{
return isDeleted;
}
public abstract void addAppendix(Object newAppendix);
}
class 物质
public class Substance extends AbstractFileObject
{
private float nodeid;
private String casNr;
private String euIndexCode;
private String einecsCode;
private boolean dutyToDeclare;
private boolean isUnwanted;
private boolean isProhibited;
private boolean isReach;
private boolean isDeleted;
private boolean isHidden;
private ArrayList<Synonym> synonymList;
public Substance(float nodeid, String casNr, String euIndexCode, String einecsCode,
boolean dutyToDeclare, boolean isUnwanted, boolean isProhibited, boolean isReach,
boolean isDeleted, boolean isHidden)
{
super(isDeleted);
this.nodeid = nodeid;
this.casNr = casNr;
this.euIndexCode = euIndexCode;
this.einecsCode = einecsCode;
this.dutyToDeclare = dutyToDeclare;
this.isUnwanted = isUnwanted;
this.isProhibited = isProhibited;
this.isReach = isReach;
//this.isDeleted = isDeleted;
this.isHidden = isHidden;
}
// getter and setter
}
class同义词
package klassenbibliothek;
public class Synonym
{
private String languageCode;
private String name;
public Synonym(String languageCode, String name)
{
this.languageCode = languageCode;
this.name = name;
}
public String getLanguageCode()
{
return languageCode;
}
public String getName()
{
return name;
}
}
单元测试
package klassenbibliothek.test;
import static org.junit.Assert.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class SubstancesTest {
@Test
public void test() {
//fail("Not yet implemented");
long startTimeNanos = System.nanoTime();
/*
* While... iterator over data file
*/
}
}
我是否以正确的方式使用工厂模式?我很困惑。
最后块用于清理。他们不应该专门抛出这样的异常。将抛出的异常移出 finally 块。
如果前面有 try 块,finally 块 总是 执行。所以你的总是抛出 NoSuchElementException()。
finally
{
// return null;
throw new NoSuchElementException();
}
你应该在其中做一些事情而不是抛出异常。
从finally 块中删除throw 异常并将其放在catch 块或其他地方。 finally block是释放你程序中可能用到的资源。
我需要创建一个 class 库,它使我能够读取不同的文件(内部具有不同数据表示的 .dat 文件)并使用其内容创建对象(每一行一个对象)。
我还必须创建一个开始读取文件的单元测试,这样我就不必先读取整个文件并将内容保存在数组中。我想用工厂模式。
这是我实现的 class 实现迭代器接口
package klassenbibliothek;
public class MyReader implements Iterator<Object>
{
BufferedReader reader;
MyReader(BufferedReader myReader)
{
reader = myReader;
}
@Override
public boolean hasNext() // aus Whosebug, von mir abgeändert
{
try {
return reader.ready();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
throw new NoSuchElementException();
}
}
@Override
public String next()
{
//return SubstancesFileObjectCreator(reader.readLine());
try {
return reader.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
// return null;
throw new NoSuchElementException();
}
}
}
我的问题是:为什么我会收到此错误消息 "finally block does not complete normally"?我没有返回任何东西,我只是抛出一个异常。
我想在单元测试中使用 hasNext() 和 next() 方法,以便单元测试可以控制何时开始读取文件。单元测试在不同的包中。
这是我的其他 classes: class AbstractFileObjectCreator
package klassenbibliothek;
public abstract class AbstractFileObjectCreator
{
public abstract AbstractFileObject createFileObject(String line);
}
class 物质文件对象创建器
package klassenbibliothek;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class SubstancesFileObjectCreator extends AbstractFileObjectCreator
{
MyReader myReader;
public void makeReader() throws IOException
{
String dataFileName = "C:/temp/Substances.dat";
BufferedReader bReader = new BufferedReader(new FileReader(dataFileName));
myReader = new MyReader(bReader);
}
@SuppressWarnings("null")
public AbstractFileObject createFileObject(String line)
{
AbstractFileObject mySubstance = null;
String lineValues[] = myReader.next().split("\t");
if(lineValues[0].equals("R"))
{
boolean dutyToDeclare_local;
boolean isUnwanted_local;
boolean isProhibited_local;
boolean isReach_local;
boolean isDeleted_local;
boolean isHidden_local;
String nodeidRaw = lineValues[1];
float nodeid = Float.parseFloat(nodeidRaw);
String casNrRaw = lineValues[2];
String euIndexCodeRaw = lineValues[3];
String einecsCodeRaw = lineValues[4];
String dutyToDeclareRaw = lineValues[5];
if(dutyToDeclareRaw.equals(1))
{
dutyToDeclare_local = true;
}
else
{
dutyToDeclare_local = false;
}
String isUnwantedRaw = lineValues[6];
if(isUnwantedRaw.equals("1"))
{
isUnwanted_local = true;
}
else
{
isUnwanted_local = false;
}
String isProhibitedRaw = lineValues[7];
if(isProhibitedRaw.equals("1"))
{
isProhibited_local = true;
}
else
{
isProhibited_local = false;
}
String isReachRaw = lineValues[8];
if(isReachRaw.equals("1"))
{
isReach_local = true;
}
else
{
isReach_local = false;
}
String isDeletedRaw = lineValues[9];
if(isDeletedRaw.equals("1"))
{
isDeleted_local = true;
}
else
{
isDeleted_local = false;
}
String isHiddenRaw = lineValues[10];
if(isHiddenRaw.equals("1"))
{
isHidden_local = true;
}
else
{
isHidden_local = false;
}
mySubstance = new Substance(nodeid, casNrRaw, euIndexCodeRaw, einecsCodeRaw, dutyToDeclare_local, isUnwanted_local, isProhibited_local, isReach_local, isDeleted_local, isHidden_local);
// und weiter...
}
else
{
String languageCode = lineValues[1];
String name = lineValues[2];
// Synonym-Objekt erzeugen und zu Substance-Objekt hinzufügen
Synonym newSynonym = new Synonym(languageCode, name);
mySubstance.addAppendix(newSynonym);
while(myReader.hasNext())
{
String lineValues_synonyms[] = myReader.next().split("\t");
String lineValuesZero = lineValues_synonyms[0];
if(lineValuesZero.equals("R"))
{
break; // nicht so gut glaube ich!!!
}
String languageCode_next = lineValues_synonyms[1];
String name_next = lineValues_synonyms[2];
Synonym newSynonym_next = new Synonym(languageCode_next, name_next);
mySubstance.addAppendix(newSynonym_next);
}
}
return mySubstance;
}
}
class 抽象文件对象
package klassenbibliothek;
public abstract class AbstractFileObject
{
boolean isDeleted;
public AbstractFileObject(boolean isDeleted)
{
this.isDeleted = isDeleted;
}
public boolean getIsDeleted()
{
return isDeleted;
}
public abstract void addAppendix(Object newAppendix);
}
class 物质
public class Substance extends AbstractFileObject
{
private float nodeid;
private String casNr;
private String euIndexCode;
private String einecsCode;
private boolean dutyToDeclare;
private boolean isUnwanted;
private boolean isProhibited;
private boolean isReach;
private boolean isDeleted;
private boolean isHidden;
private ArrayList<Synonym> synonymList;
public Substance(float nodeid, String casNr, String euIndexCode, String einecsCode,
boolean dutyToDeclare, boolean isUnwanted, boolean isProhibited, boolean isReach,
boolean isDeleted, boolean isHidden)
{
super(isDeleted);
this.nodeid = nodeid;
this.casNr = casNr;
this.euIndexCode = euIndexCode;
this.einecsCode = einecsCode;
this.dutyToDeclare = dutyToDeclare;
this.isUnwanted = isUnwanted;
this.isProhibited = isProhibited;
this.isReach = isReach;
//this.isDeleted = isDeleted;
this.isHidden = isHidden;
}
// getter and setter
}
class同义词
package klassenbibliothek;
public class Synonym
{
private String languageCode;
private String name;
public Synonym(String languageCode, String name)
{
this.languageCode = languageCode;
this.name = name;
}
public String getLanguageCode()
{
return languageCode;
}
public String getName()
{
return name;
}
}
单元测试
package klassenbibliothek.test;
import static org.junit.Assert.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class SubstancesTest {
@Test
public void test() {
//fail("Not yet implemented");
long startTimeNanos = System.nanoTime();
/*
* While... iterator over data file
*/
}
}
我是否以正确的方式使用工厂模式?我很困惑。
最后块用于清理。他们不应该专门抛出这样的异常。将抛出的异常移出 finally 块。
如果前面有 try 块,finally 块 总是 执行。所以你的总是抛出 NoSuchElementException()。
finally
{
// return null;
throw new NoSuchElementException();
}
你应该在其中做一些事情而不是抛出异常。
从finally 块中删除throw 异常并将其放在catch 块或其他地方。 finally block是释放你程序中可能用到的资源。