Java OOP transient 字段在加载 POJO 父级时初始化

标签 java class oop syntax initialization

所以我有一个非常大的类,其中有数百个 transient 对象,每次加载父级(在本例中为 Person.class)时都需要重新初始化。 (Peron.class 已加载并保存)

这是我目前的类结构的示例:

public final class Person {

    private transient ObjectA a;
    private transient ObjectB b;
    private transient ObjectC c;
    private transient ObjectD d;
    //and hundreds more...

    public Person() {

        initTransientObjects();

    }

    private void initTransientObjects() {

        a = new ObjectA();
        b = new ObjectB();
        c = new ObjectC();
        d = new ObjectD();
        //and hundreds more...
    } 

    public void onReloadAfterFirstSave() {
        initTransientObjects();
    }

}

这使得编写新对象变得非常乏味,我想知道是否有一种方法可以使它更紧凑,如下所示:

public final class Person {

    private transient ObjectA a = new ObjectA();
    private transient ObjectB b = new ObjectB();
    private transient ObjectC c = new ObjectC();
    private transient ObjectD d = new ObjectD();
    //and hundreds more...
    //this way I only have to type the new object once instead of twice

    public void onReloadAfterFirstSave() {
        //what here? because now transient fields are null
    }

}

请注意,我无法使用上述内容的原因是,显然,当再次加载 Person 时, transient 字段将不会被加载,因此会自动设置为 null。

我应该在这里做什么?

编辑:

我还在 Person 类中保存了非 transient 对象以及这些 transient 字段,这就是为什么不选择使用它:

Peron person = new Person(); //every load

最佳答案

你可以尝试这个,但我不赞成这样做,主要是因为你需要非常小心异常(exception)情况。 我假设您的 ObjectA、ObjectB、ObjectC 的构造函数不是空的,如果它们是空的,那么这将更容易实现。

我专门为你制作了一个示例类(class)

import java.lang.reflect.InvocationTargetException;
import java.util.Random;

/**
 *
 * @author emngaiden
 */
public class Test2 {

    ClassContainer[] containers;
    Object[] instantieted_objects;

    public Test2() {
        initObjects();
    }

    public static void main(String[] args) {
        Test2 test=new Test2();
        StringBuilder sb=(StringBuilder)test.getObject(2);
        sb.append((String)test.getObject(0));
        sb.append(((Random)test.getObject(1)).nextDouble());
        System.out.println(sb.toString());
    }

    public Object getObject(int i){
        return this.instantieted_objects[i];
    }

    private void initObjects() {
        //total number of objects ObjectA, ObjectB etc...
        int number_of_objects = 3;
        this.containers = new ClassContainer[number_of_objects];
        this.instantieted_objects = new Object[number_of_objects];
        //create the containers, you write this only one, and can
        //share it between objects of the same class
        this.containers[0] = new ClassContainer(String.class,
                new Class[]{String.class},
                new Object[]{"hello world"}
        );
        this.containers[1] = new ClassContainer(Random.class,
                new Class[]{long.class},
                new Object[]{192323l}
        );
        this.containers[2] = new ClassContainer(StringBuilder.class,
                null,
                null
        );
        //poblate the objects in the array
        for(int i=0; i<this.containers.length; i++){
            try{
                this.instantieted_objects[i]=instantiateObject(containers[i]);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

    //returns a new object instance based on the container
    private Object instantiateObject(ClassContainer container)
    throws NoSuchMethodException, InstantiationException, IllegalAccessException,
    IllegalArgumentException, InvocationTargetException {
        //no arguments for the constructor means that the constructor is empty
        if(container.args!=null){
            //get the constructor that matches the Class[] array on its arguments
            return 
                container.obj.getConstructor(container.args)
                .newInstance(container.values);
        }
        else{
            return container.obj.newInstance();
        }
    }

    //class to hold the necessary data to instantiate the object
    public class ClassContainer {

        //the target class, for ObjectA(int,int)this must be ObjectA.class 
        Class obj;
        //the argument classes, it would be {int.class,int.class}
        Class[] args;
        //the actual values for the constructor, it would be {1,2}
        Object[] values;

        public ClassContainer(Class obj, Class[] args, Object[] values) {
            this.obj = obj;
            this.args = args;
            this.values = values;
        }
    }
}

这编写起来很有趣,但我不建议使用它。

关于Java OOP transient 字段在加载 POJO 父级时初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52549040/

相关文章:

java - 从 Hibernate 时间戳检索数据

java - 以函数式方式重构 RxJava Observable concat 代码和错误处理

Java实例变量数组大小基于另一个实例变量

c# - 继承和接口(interface) .NET

java多服务开闭原则

java - Java套接字无法发送两个字节数组

ruby - 如何实现 Watir 类(例如 PageContainer)?

ios - 在Objective-C中设置另一个类的属性

c++ - 为什么重载运算符不起作用?

java - 如果哈希码等于实现不正确,我的对象创建会失败吗?