加载 POJO 父项时初始化 Java OOP 瞬态字段
Posted
技术标签:
【中文标题】加载 POJO 父项时初始化 Java OOP 瞬态字段【英文标题】:Java OOP transient field initialising upon loading POJO parent 【发布时间】:2019-03-04 01:55:12 【问题描述】:所以我有一个非常大的类,其中包含数百个瞬态对象,每次加载父级(在本例中为 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 再次加载时,瞬态字段将不会被加载,因此会自动设置为 null。
我应该在这里做什么?
编辑:
我还保存在 Person 类中的非瞬态对象以及这些瞬态字段,这就是为什么不能使用它的原因:
Peron person = new Person(); //every load
【问题讨论】:
这看起来很奇怪......你是在将对象写入磁盘吗?为什么要在 Person 类中引用这么多不同的类型? 它被保存为一个对象,但把它想象成一个真实的人,他会有很多属性,比如电视、汽车、房子等...... 如果你序列化这个人而不是它的数据——它仍然没有任何意义。你需要一种不同的抽象。在不知道你在构建什么的情况下,你的代码很难重构。 更不用说你所有的对象在每次“reloadafterfirstsave”之后都会失去它的状态,此时它与仅仅执行“person = new Person()”没有什么不同(除非你有非瞬态属性你没有提到的) 我确实序列化了一些 Person 的数据(这不是暂时的;这里没有显示,因为这不是问题所在),但是这个人会有一些需要每次重置的东西加载,例如,car 和 house 不会是瞬态的并且会被保存,但是,像 TodaysTVProgramSchedule.class 这样的对象会改变(假设玩家每天都重新加载) 【参考方案1】:你可以试试这个,但我不赞成这样做,主要是因为你需要非常小心例外情况。 我会假设您的 ObjectA、ObjectB、ObjectC 的构造函数不是空的,如果是,那么这将更容易实现。
我为你做了一个示例类
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;
编写代码很有趣,但我不建议使用它。
【讨论】:
有趣。我之前在其他项目上做过这个,发现创建带有额外转换所需的 getter 和 setter(这不能用 ide 自动完成)与我正在使用的仅 oop 类型方法一样乏味。但我也想听听其他人对此的看法以上是关于加载 POJO 父项时初始化 Java OOP 瞬态字段的主要内容,如果未能解决你的问题,请参考以下文章