有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java解析/从磁盘加载对象

我正在开发一个程序,从文件中读取不同格式的不同数据。为了解释我的需求,并且为了清晰起见,这里有一个示例(实际上是最小/简单的示例,数据格式在现实中非常复杂)

public class Person{
    private final String name;

    public Person(String name){
        this.name = Objects.requireNonNull(name);
    }

    public String getName(){return name;}
}

然后,我需要使用具有以下格式的文件创建Person类的实例:

name = Bob

(注意:在本例中,我使用java属性格式,但实际上,格式不同,并且存在大量数据。例如,我要加载的一个类有50多个字段(包括double/String/array)。从文件~30M加载,格式固定)

要加载这些文件,我考虑了3种方法:

首先:提供静态工厂方法:

public class Person{
    /*Fields, Constructors, Getters, ... */
    //...
    public static Person fromFile(Path path){/*implementation*/}
}

但是person类应该只是一个“data”类,使用这种方法,我必须在一个“data”类中处理IOException,这看起来很奇怪。 此外,加载我的对象的实例(实际上)可能相当复杂,并且意味着许多与Person类无关的方法/regex/java文件实用程序

第二:提供一个实用程序类:

public final class PersonLoader{
    /**Prevents instantiation*/
    private PersonLoader(){}

    public static Person load(Path path){/*implementation*/}
}

这种方法的主要问题是,一旦发布这两个类,我就应该维护它们。我发现没有办法强制(使用编译器)拥有一个专用的实用程序类。在2个月内,如果我添加另一种格式,我会考虑添加一个实用程序类吗?(我猜是没有)

Third:使用加载程序实例加载我的Person

这可以是这样的外部或内部类(也可以是单例):

 public (static) class PersonLoader{
     public PersonLoader(){}

     public Person load(){/*implementation*/}
 }

如果我将它用作内部类(静态版本),那么这种方法似乎结合了前一种方法的两个缺点。 如果我将它用作顶级类,维护问题仍然存在,每次我要加载数据时,我都需要创建另一个对象实例。 即使我使用单例模式,20个单例(我使用的每种格式)似乎是个坏主意

是否有其他方法可以做到这一点,或者我应该重构其中一种方法以满足我的需要


共 (1) 个答案

  1. # 1 楼答案

    我认为你可以有一个通用的加载器(你也可以让它成为单例加载器)

    public class ObjectLoader<OBJECT_TYPE> {
    
        public  OBJECT_TYPE create(Class<OBJECT_TYPE> type, String path){
            OBJECT_TYPE newObj = null;
            try{
                newObj = type.newInstance();
                Field[] declaredFields = type.getDeclaredFields();
                for (Field declaredField : declaredFields) {
                    declaredField.setAccessible(true);
                    declaredField.set(newObj, "PUT HERE NECESSARY VALUE ");
    
            }
            }catch (InstantiationException e) {
                //TODO: Handle error
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                //TODO: Handle error
                e.printStackTrace();
            }
            return newObj;
        }
    }
    

    并使用java反射来实例化对象