Java 将单记录csv文件读入类字段的编程习惯用法

Java 将单记录csv文件读入类字段的编程习惯用法,java,oop,design-patterns,csv,Java,Oop,Design Patterns,Csv,假设我要读取以下文件: TestFile;100 进入类的字段: public class MyReader { String field1; Integer field2; } 阅读内容有两种稍有不同的方式: 公共类MyReader{ public void loadValues(File file) throws IOException { //a generic method that reads the content file to a string t

假设我要读取以下文件:

TestFile;100
进入类的字段:

public class MyReader { 
    String field1;
    Integer field2;
}
阅读内容有两种稍有不同的方式:

公共类MyReader{

public void loadValues(File file) throws IOException {

    //a generic method that reads the content file to a string throwing an IOException
    String line = readFileToString(file);
    String[] values = line.split(";");

    field1=values[0];
    field2=Integer.parseInt(values[1]);

}

//then i'll have well known getters:

public String getField1() {
  return field1;
} 

public Integer getField2() {
  return field2;
}
第二个成语:

private String[] values; //made the values a class field

public void loadValues(File file) throws IOException {

    //a generic method that reads the content file to a string throwing an IOException
    String line = readFileToString(file);

    values = line.split(";");

}

public String getField1() {
  return values[0]
} 

public Integer getField2() {
  return Integer.parseInt(values[1]);
}
最大的区别在于异常管理。 我故意忽略捕捉两种情况下可能发生的运行时异常:

  • ArrayIndexOutOfBoundsException
    如果文件包含少于两个字段
  • NumberFormatException
    如果整数解析失败
第一种方法
所有字段都是在启动时加载的。如果其中一个字段不可解析,我会得到
NumberFormatException
。如果字段少于所需的字段,我会得到越界异常。这听起来不错,特别是如果我想确保使用特定字段后所有字段值的正确性:fail fast范式。 假设我有100个字段,该记录包含一个错误,该错误会被记录到一个文件中以进行故障排除

Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
也就是说:我得到了错误,导致错误的值,给出错误的行号,但不是字段名。这对开发人员来说是好的,对通常无法访问源代码的系统工程师来说不是那么好

第二种方法
只有通过getter访问字段时,才会从数据字符串中“提取”和解析字段。 在相同的情况下,每个getter都可能返回上述两个错误。 与“fail fast paradigm”相反,存在一定程度的“容错性”。如果记录的第100个字段包含不正确的值,但类的客户端不调用其getter,则永远不会抛出异常。 另一方面,当调用错误值的getter时,记录的异常将包含导致问题的字段的信息(在堆栈跟踪中):

问题

这两种方法各有利弊,可以说采用哪种方法的决定取决于具体情况。问题是:

  • getter和setter是javabeans主题。它们返回异常是否“可接受”
  • 这两种方法中的类可能显然具有相同的接口,但由于它们具有完全不同的异常体系结构,客户端应该以完全不同的方式使用它们。那么如何向客户端表示这一事实呢?也许getters语义有误导性,也许有更雄辩的方式

首先,第二种方法不起作用,因为您将values[]数组存储为局部变量,并且其他函数(在您的例子中是getter)无法访问它

第二,不要在getter中抛出异常,因为您公开的api会产生误导,并且不符合任何约定

第三,不要自己解析字符串,考虑使用现成的库来解析CSV,不要重新创建轮子,如

第四,为csv记录创建一个简单的POJO对象,您可以在为每个字段分配值时检查错误,然后抛出异常或不抛出异常,提供默认值等


希望这能有所帮助

好的,局部变量应该是一个字段,这显然是在处理和混合我的类时的一个输入错误。我已经纠正了这个错误。
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:449)
at java.lang.Integer.parseInt(Integer.java:499)

at com.test.MyReader.getField2(MyReader.java:39)

at com.test.MyReader.test(MyReader.java:33)
at com.test.MyReader.main(MyReader.java:16)