我正在尝试在Java应用程序中保存和加载一个对象,该对象是另一个类的扩展。
我目前可以保存和加载当前类,但是我希望能够保存特定的对象,正如您在下面的代码中看到的那样,我已经声明了我的类Building并将其命名为TheBuilding,我想保存并加载此类。当前正在发生的事情是保存并加载BuildingGUI而不是特定对象
public class BuildingGUI extends Application implements Serializable{
private Building theBuilding;
public static void main(String[] args) {
BuildingGUI Building2 = new BuildingGUI();
try
{
//Create file output stream
FileOutputStream fileOutStr = new
FileOutputStream("theBuilding.ser");
//Create object output stream and write object
ObjectOutputStream objOutStr = new
ObjectOutputStream(fileOutStr);
objOutStr.writeObject(Building2);
//Close all streams
objOutStr.close();
fileOutStr.close();
System.out.printf("Serialized data is saved in a file -
theBuilding.ser");
}catch(IOException exp)
{
System.out.println("Error IOException");
exp.printStackTrace();
}
BuildingGUI Building = null;{
try
{
FileInputStream fileInStr = new FileInputStream("theBuilding.ser");
ObjectInputStream objInStr = new ObjectInputStream(fileInStr);
Building = (BuildingGUI) objInStr.readObject();
objInStr.close();
fileInStr.close();
}catch(IOException exp)
{
System.out.println("Error IOException");
exp.printStackTrace();
return;
}catch(ClassNotFoundException cexp)
{
System.out.println("BuildingGUI class not found");
cexp.printStackTrace();
return;
}
System.out.println(", theBuilding has been deserialized");
上面的代码通过保存BuildingGUI类文件然后再次加载来完成其预期的工作,但是我希望它保存一个特定的对象,该对象是私有Building theBuilding;
谢谢您的帮助
答案 0 :(得分:1)
由于您声称自己的代码可以正常工作,因此我只是将其复制并粘贴到您原来的问题中。
您在正确的道路上,只是:
您可以执行完全相同的操作,但对于Building
类型的对象。只需将方法的参数更改为接受Building
,而不是BuildingGUI
。
//Method to serialize and store specific BuildingGUI
public void buildingSaver(BuildingGUI building) throws IOException {
//Create file output stream
FileOutputStream fileOutStr = new FileOutputStream("theBuilding.ser");
//Create object output stream and write object
ObjectOutputStream objOutStr = new ObjectOutputStream(fileOutStr);
objOutStr.writeObject(Building2);
//Close all streams
objOutStr.close();
fileOutStr.close();
System.out.printf("Serialized data is saved in a file - theBuilding.ser");
}
//Method to deserialize BuildingGUI from file
public BuildingGUI buildingLoader(String filename) throws IOException,
ClassNotFoundException{
FileInputStream fileInStr = new FileInputStream(filename);
ObjectInputStream objInStr = new ObjectInputStream(fileInStr);
BuildingGUI building = (BuildingGUI) objInStr.readObject();
objInStr.close();
fileInStr.close();
return building;
}
如果您有多种类型的对象需要怎么办? 店吗?
您是否需要为所有这些方法编写单独的方法?
答案是否。
您可以有一个更通用的方法(也是static
),该方法接受对象作为参数,如下所示:
//parameter is Object, instead of Building
public static void writeObjectToDisk(Object obj, String name) throws IOException {
//Create file output stream
FileOutputStream fileOutStr = new FileOutputStream(name);
//Create object output stream and write object
ObjectOutputStream objOutStr = new ObjectOutputStream(fileOutStr);
objOutStr.writeObject(obj);
//Close all streams
objOutStr.close();
fileOutStr.close();
System.out.printf("Serialized data is saved in a file - "+name);
}
public static Object objectLoader(String filename) throws IOException,
ClassNotFoundException{
FileInputStream fileInStr = new FileInputStream(filename);
ObjectInputStream objInStr = new ObjectInputStream(fileInStr);
Object obj = (Object) objInStr.readObject();
objInStr.close();
fileInStr.close();
return obj;
}
要从Building
内部获取BuildingGUI
,您将需要一个访问器方法:
public class BuildingGUI extends Application implements Serializable{
private Building theBuilding;
public Building getBuilding(){
return this.theBuilding;
}
/*other code..*/
}
最后,在您的main
方法中:
public static void main(String[] args) {
//initialize BuildingGUI object and get the Building object
BuildingGUI building2 = new BuildingGUI();
Building myBuilding = building2.getBuilding();
//we serialize the Building, by casting it to (Object) and feeding it to the method
try{
someClass.writeObjectToDisk((Object)myBuilding);
}
catch(IOException ioe){
ioe.printStackTrace();
}
Building myBuilding2 = null;
BuildingGUI buildingGUI = null;
//now for deserializing
try{
//We cast to appropriate type, because method returns 'Object'
myBuilding2 = (Building)objectLoader("building.ser");
buildingGUI = (BuildingGUI)objectLoader("buildingGUI.ser");
}
catch(IOException ioe){
ioe.printStackTrace();
}
catch(ClassNotFoundException cnfe){
cnfe.printStackTrace();
}
}
最终通知:
如果初始化Building
类内部的BuildingGUI
对象引用。然后,在序列化BuildingGUI
时,也将隐式序列化Building
对象引用。因此,当您反序列化 BuildingGUI
时,您也可以访问Building
。我将添加最后一个范例。
public class BuildingGUI extends Application implements Serializable{
private Building theBuilding = new Building(); <-- we initialize it
public Building getBuilding(){
return this.theBuilding;
}
}
public static void main(String[] args) {
//initialize BuildingGUI object and get the Building object
BuildingGUI building2 = new BuildingGUI();
//we serialize the Building, by casting it to (Object) and feeding it to the method
try{
someClass.writeObjectToDisk((Object)building2);
}
catch(IOException ioe){
ioe.printStackTrace();
}
BuildingGUI buildingGUI = null;
//now for deserializing JUST THE BUILDINGGUI
try{
//We cast to appropriate type, because method returns 'Object'
buildingGUI = (BuildingGUI)ObjectLoader("buildingGUI.ser");
}
catch(IOException ioe){
ioe.printStackTrace();
}
catch(ClassNotFoundException cnfe){
cnfe.printStackTrace();
}
//You can get the building this way
Building myBuilding = buildingGUI.getBuilding();
}
答案 1 :(得分:1)
在您的main()
方法中,您有一个名为Building2
的局部变量,它是类BuildingGUI
的实例:
BuildingGUI Building2 = new BuildingGUI();
几行后,您正在将该对象写入文件:
objOutStr.writeObject(Building2);
因此,这就是您的程序向文件写入BuildingGUI
对象的原因。
您的类BuildingGUI
具有一个声明的theBuilding
类型的名为Building
的成员变量。如果您只想将Building
对象写入文件,则必须将写入对象的行更改为只写入该对象:
// Write the Building object that is contained
// in the BuildingGUI object to the file
objOutStr.writeObject(Building2.theBuilding);
但是,还缺少其他内容:您没有在代码中的任何地方初始化成员变量theBuilding
,因此它将被设置为默认值null
。您需要正确初始化它,例如,将第3行更改为:
private Building theBuilding = new Building();
请注意,这仅是一个示例,您没有向我们展示类Building
,所以我不知道它是否有一个不带参数的构造函数,使您可以像这样实例化它,或者您是否需要将参数传递给构造函数或以另一种方式实例化对象。
您还必须更改从文件加载数据的代码,因为您要在其中加载Building
对象,而不是BuildingGUI
对象。
答案 2 :(得分:0)
我不确定您是否很好地理解了您的问题,但我会尝试一下。
第一个问题:Building
类是Serializable
类吗?
如果是这样,这是一个好的开始。然后,您现在正在做的是从静态上下文(在main方法中)调用序列化代码,而您正在做的事情:
objOutStr.writeObject(Building2);
如此有效地,对象BuildingGUI
被按预期方式序列化了。
如果要序列化Building
对象,则需要使用getter对其进行访问,例如:
public Building getBuilding() {
return theBuilding;
}
然后将您的代码替换为:objOutStr.writeObject(Building2.getBuilding());
然后,在进行反序列化时,您将拥有一个Building类Object。
答案 3 :(得分:-1)
您可以使用:杰克逊。这是一个映射器,它可以将对象转换为json格式。然后,您将能够将此json字符串加载到特定的给定对象中