Java 对象反序列化与基础 GUI 开发
一、对象反序列化
在 Java 中,对象序列化是将对象转换为字节流的过程,而反序列化则是将字节流还原为对象的过程。下面我们将详细介绍如何从文件中反序列化一个
Car
对象。
1. 反序列化步骤
-
创建
Car对象 :这次我们不使用构造函数初始化Car对象,而是将其值设置为从文件中读取的对象。 -
复制并修改代码
:从
Serialize类复制代码到DeSerialize类,并进行修改。注意在之前的Serialize类中,我们关闭了ObjectOutputStream但没有关闭FileOutputStream,在长时间运行的程序中,不关闭文件可能会导致奇怪的问题。当嵌套使用FileInput或Output类时,通常应按访问的相反顺序关闭文件。 -
使用
FileInputStream:将FileOutputStream替换为其姐妹类FileInputStream。
FileInputStream outFile = new FileInputStream("serialized.dat");
-
导入
java.io包 :确保引用相同的文件名,并合理命名变量。 -
使用
ObjectInputStream:将FileInputStream包装在ObjectInputStream中,用于从文件中读取对象。
ObjectInputStream in = new ObjectInputStream(outFile);
-
读取对象并转换类型
:
ReadObject方法读取文件中的对象,并将其转换为Car类型。
c = (Car)in.readObject();
-
关闭文件读取器
:按相反顺序关闭
ObjectInputStream和FileInputStream。
try {
FileInputStream inFile = new FileInputStream("serialized.dat");
ObjectInputStream in = new ObjectInputStream(inFile);
c = (Car)in.readObject();
in.close();
inFile.close();
}
-
捕获异常
:捕获
ClassNotFoundException异常,并输出错误信息。
catch(ClassNotFoundException e)
{
System.err.println("ERROR");
}
-
输出对象信息
:使用
toString方法输出Car对象的信息。为避免NetBeans提示变量未初始化,将Car对象初始化为null。
public class DeSerialize {
public static void main(String[] args) {
Car c = null;
try {
FileInputStream inFile = new FileInputStream("serialized.dat");
ObjectInputStream in = new ObjectInputStream(inFile);
c = (Car)in.readObject();
in.close();
inFile.close();
}
catch(IOException e)
{
System.err.println("ERROR");
}
catch(ClassNotFoundException e)
{
System.err.println("ERROR");
}
System.out.println(c.toString());
}
}
2. 反序列化流程
graph TD;
A[创建 Car 对象] --> B[复制并修改代码];
B --> C[使用 FileInputStream];
C --> D[导入 java.io 包];
D --> E[使用 ObjectInputStream];
E --> F[读取对象并转换类型];
F --> G[关闭文件读取器];
G --> H[捕获异常];
H --> I[输出对象信息];
二、基础 GUI 开发
有时候,我们编写的程序不仅要有强大的功能,还要有良好的用户界面,以提高用户体验。下面我们将介绍如何在 NetBeans 中创建一个基础的图形用户界面(GUI)。
1. Swing GUIs
NetBeans 是一个功能强大的程序,我们通过其提供的 GUI、菜单和按钮来访问各种功能。Java 的
swing
库可以帮助我们为自己的代码创建类似 NetBeans 的 GUI。
2. 创建 GUI 窗口
使用
JFrame
类可以创建一个应用程序窗口,具体步骤如下:
-
创建
JFrame
对象
:可以传递一个字符串参数作为窗口的名称。
package GUI;
import javax.swing.*;
public class GUI {
public static void main(String[] args) {
JFrame frame = new JFrame("Hello World GUI");
}
}
-
调用
pack方法 :在显示窗口之前,调用pack方法来预构建窗口中对象的物理关系,确保窗口显示正常。
frame.pack();
-
设置窗口可见
:调用
setVisible方法并将值设置为true,使窗口显示给用户。
frame.setVisible(true);
3. 设置窗口大小
使用
setPreferredSize
方法可以设置
JFrame
类的首选大小。我们可以使用
Dimension
类来存储和操作大小信息。
import java.awt.*;
frame.setPreferredSize(new Dimension(400, 400));
4. 添加标签
JLabel
是最简单的 GUI 元素之一,用于显示文本。创建
JLabel
对象后,需要将其添加到
JFrame
的
contentPane
中。
package gui;
import javax.swing.*;
import java.awt.*;
public class GUI {
public static void main(String[] args) {
JFrame frame = new JFrame("Hello World GUI");
frame.setPreferredSize(new Dimension(400, 400));
JLabel label = new JLabel("Hi. I am a GUI.");
frame.getContentPane().add(label);
frame.pack();
frame.setVisible(true);
}
}
5. 关闭应用程序
使用
setDefaultCloseOperation
方法可以设置窗口关闭时的操作。我们通常使用
EXIT_ON_CLOSE
选项,当关闭窗口时退出应用程序。
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
6. 多线程与推荐实践
在创建 GUI 时,程序可能会变成多线程的,这可能会导致一些底层问题。为了避免这些问题,建议使用
SwingUtilities
类的
invokeLater
方法来异步创建 GUI。
-
创建
MakeGUI方法 :将创建 GUI 的代码提取到一个新的方法中。
private static void MakeGUI()
{
JFrame frame = new JFrame("Hello World GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(400, 400));
JLabel label = new JLabel("Hi. I am a GUI.");
frame.getContentPane().add(label);
frame.pack();
frame.setVisible(true);
}
-
使用
SwingUtilities.invokeLater方法 :创建一个Runnable对象,并将其传递给invokeLater方法。
public static void main(String[] args) {
Runnable GUITask = new Runnable(){
@Override
public void run(){
MakeGUI();
}
};
SwingUtilities.invokeLater(GUITask);
}
综上所述,我们学习了如何在 Java 中反序列化对象以及创建基础的 GUI。反序列化对象可以帮助我们将对象持久化存储,而创建 GUI 可以提高程序的用户体验。通过遵循推荐的实践,我们可以避免一些潜在的问题,使程序更加稳定和可靠。
三、总结与对比
1. 反序列化与 GUI 开发要点总结
| 类别 | 要点 | 代码示例 |
|---|---|---|
| 对象反序列化 |
创建
Car
对象,使用
FileInputStream
和
ObjectInputStream
读取文件,捕获异常并输出对象信息
|
java<br>public class DeSerialize { <br> public static void main(String[] args) { <br> Car c = null; <br> try { <br> FileInputStream inFile = new FileInputStream("serialized.dat"); <br> ObjectInputStream in = new ObjectInputStream(inFile); <br> c = (Car)in.readObject(); <br> in.close(); <br> inFile.close(); <br> } <br> catch(IOException e) <br> { <br> System.err.println("ERROR"); <br> } <br> catch(ClassNotFoundException e) <br> { <br> System.err.println("ERROR"); <br> } <br> System.out.println(c.toString()); <br> } <br>}<br>
|
| 基础 GUI 开发 |
使用
JFrame
创建窗口,设置大小、添加标签、关闭应用程序,使用
SwingUtilities
异步创建 GUI
|
java<br>public static void main(String[] args) { <br> Runnable GUITask = new Runnable(){ <br> @Override <br> public void run(){ <br> MakeGUI(); <br> } <br> }; <br> SwingUtilities.invokeLater(GUITask); <br>}<br>
|
2. 反序列化与 GUI 开发流程对比
graph LR;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(对象反序列化):::process --> B(读取文件):::process;
B --> C(转换对象类型):::process;
C --> D(捕获异常):::process;
D --> E(输出对象信息):::process;
F(基础 GUI 开发):::process --> G(创建窗口):::process;
G --> H(设置窗口属性):::process;
H --> I(添加组件):::process;
I --> J(异步创建 GUI):::process;
从流程对比可以看出,对象反序列化主要围绕文件操作和对象转换,而基础 GUI 开发侧重于窗口和组件的创建与设置。
四、深入探讨与拓展
1. 反序列化的拓展应用
对象反序列化在很多场景下都有重要应用,比如数据持久化、分布式系统中的对象传输等。在实际应用中,我们可以将反序列化的对象存储在数据库中,或者在不同的服务之间传递。
例如,在一个分布式系统中,服务 A 将一个
Car
对象序列化后发送给服务 B,服务 B 接收到字节流后进行反序列化操作,从而获取
Car
对象的信息。
// 服务 A 序列化对象
Car car = new Car("FDAJFD54254", "Nisan", "Altima", "Green", 2000);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("serialized.dat"));
out.writeObject(car);
out.close();
// 服务 B 反序列化对象
FileInputStream inFile = new FileInputStream("serialized.dat");
ObjectInputStream in = new ObjectInputStream(inFile);
Car receivedCar = (Car) in.readObject();
in.close();
inFile.close();
2. GUI 开发的拓展功能
在基础 GUI 开发的基础上,我们可以进一步拓展功能,比如添加更多的组件(如按钮、文本框等),实现事件处理。
以下是一个添加按钮并处理按钮点击事件的示例:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GUIWithButton {
public static void main(String[] args) {
Runnable GUITask = new Runnable() {
@Override
public void run() {
MakeGUI();
}
};
SwingUtilities.invokeLater(GUITask);
}
private static void MakeGUI() {
JFrame frame = new JFrame("Hello World GUI with Button");
frame.setPreferredSize(new Dimension(400, 400));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("Hi. I am a GUI.");
frame.getContentPane().add(label, BorderLayout.NORTH);
JButton button = new JButton("Click me");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "Button clicked!");
}
});
frame.getContentPane().add(button, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
在这个示例中,我们添加了一个按钮,并为按钮添加了一个点击事件监听器。当按钮被点击时,会弹出一个消息框显示“Button clicked!”。
通过以上的深入探讨和拓展,我们可以看到 Java 对象反序列化和基础 GUI 开发在实际应用中有很大的潜力,并且可以通过不断学习和实践来进一步提升我们的编程能力。
超级会员免费看
1216

被折叠的 条评论
为什么被折叠?



