使用异常处理实现 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是释放你程序中可能用到的资源。