Java复习Day2

异常

Exception分类:Runtime Exception,其他异常
1 try-catch-finally
try(){

}catch(Exception e){
e.printStackTrace();
}finally{

}

2 throws
一层一层往外抛出,最外面的函数用try-catch围住
注意:放在参数后面

自定义异常

A(){
B();
}
B(){
代码段
}
1运行时异常
class AgeIsIllegal extends RuntimeException{
public AgeIsIllegal(String message){
super(message);
}
}
函数内部代码段throw new AgeIsIllegal(….),A函数的B部分再用try-catch围住

2异常
public class NameNullException extends Exception{
public NameNullException(String message) {
super(message);
}
}
函数内部代码段throw new NameNullException(….),然后B函数把异常抛出去(throws NameNullException),A函数的B部分再用try-catch围住

Gui编程

1导包
import javax.Swing.*
import java.awt.*
再次记住java.lang不用导
2常见写法
几个点

  • 1.继承JFrame,this可以不写,大多绑在桌布jpanel上,貌似JFrame上也行
  • 2.JTextField参数是int类型大小,JTextField为其子类
  • 3.几种常见的布局管理器
    setLayout(new FlowLayout());
    setLayout(new GridLayout());
    setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
  • 4.事件监听器的写法 匿名内部类 必须在函数构造器内(构造器内的函数内也行)

jb2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
…代码内容
}
});
可用匿名内部类进一步简化
jb2.addActionListener((ActionEvent e) ->{
…代码内容
});

  • 5.设置背景
    Color redLight=Color.RED;
    panel.setBackground(redLight);
    常见写法:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
      public class App3 extends JFrame{
    List<Student>list=new ArrayList<>();
    public App3(){
    super("1819A卷");
    this.setSize(500,400);
    this.setLocationRelativeTo(null);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    init();
    }

    private void init() {
    JPanel jp=new JPanel();
    jp.setLayout(new FlowLayout());
    JLabel nameLabel = new JLabel("姓名:");
    JTextField name = new JTextField(5); // 调整文本框宽度
    JLabel ageLabel = new JLabel("年龄:");
    JTextField age = new JTextField(5); // 调整文本框宽度
    jp.add(nameLabel);
    jp.add(name);
    jp.add(ageLabel);
    jp.add(age);
    JLabel msgLa = new JLabel(); // 用于显示信息
    jp.add(msgLa); // 将消息标签添加到面板
    JButton jb1=new JButton("添加");
    JButton jb2=new JButton("取消");
    JButton jb3=new JButton("显示");
    this.add(jp);
    jp.add(jb1);
    jp.add(jb2);
    jp.add(jb3);
    public static void main(String[] args) {
    App3 app3=new App3();
    app3.setVisible(true);
    }
    }
    常见例题
    一、程序运行初始界面如下左图,界面如下图所示。每次点击“计数”按钮,均会在相
    关标签中给出计数提示;点击退出按钮,则会结束程序。请补充完成此程序。
    a.)程序运行的初始界面 b.)点击“计数”按钮 9 次后的界面
    _(1) /* 请补充需要导入的包 /
    class MyGUI extends JFrame (2){
    private JButton b_count,b_exit;
    private JLabel cLa;
    private int count=0;
    public MyGUI() { setLayout(new FlowLayout());
    b_count = new JButton(“计数”);
    b_exit= new JButton(“退出”);
    cLa=new Jlabel(“0”);
    add(cLa); add(b_count); add(b_exit);
    setVisible(true);
    _(3)/
    剩余部分,请补充完整 /
    }
    _(4)/
    其它方法,请补充完整 */
    public static void main(String[] args) { new MyGUI(); }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package FinalTest.GUi.Gui1718;

import com.sun.javaws.exceptions.ExitException;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MyGUI extends JFrame {
private JButton b_count,b_exit;
private JLabel cLa;
private int count=0;
public MyGUI() {
setLayout(new FlowLayout());
b_count = new JButton("计数");
b_exit = new JButton("退出");
cLa = new JLabel("0");
add(cLa);
add(b_count);
add(b_exit);
setSize(500,300);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
b_count.addActionListener(new ActionListener() {
int click=0;
@Override
public void actionPerformed(ActionEvent e) {
click++;
cLa .setText("您点击了"+Integer.toString(click)+"次");
}
});
b_exit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(null, "您确定要退出吗?", "退出确认", JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION) {
System.exit(0); // 退出程序
}

}
});
}
public static void main(String[] args) { new MyGUI(); }
}

二、
给定如下学生类 Student,App3 类实现构造界面添加学生。请将代码补充完整,以满足
下面所有条件:
(1)App3 中内置一学生数组,用于存储添加的学生对象;
(2)App3 构造的界面如上图所示。
a. 点击“取消”,清空姓名、年龄文本框的数据;
b. 点击“添加”,将正确的学生对象添加到学生数组中,并清空文本框;
c. 点击“显示”,在控制台输出所有学生数据,并清空文本框;
(3)构造异常类、处理异常类
a) 构造异常类 NameNullException,当姓名文本框中所获得内容 s,在通过
s.trim()剔除首尾空格后,s 值为空字符串(即””)时,抛出此异常,并通过标签
msgLa 显示“姓名不能为空”;
b) 构造异常类 AgeValueException,当年龄文本框中所获得年龄值小于 10 或大
于 60 时抛出此异常,并通过标签 msgLa 显示“年龄值不正确”;
c) 通过 Integer.parseInt(s)将 s 转换成 int 数据时,可能抛出虚拟机异常
NumberFormatException,请在该异常输出时捕获,并通过标签 msgLa 显示“数
据格式不正确”;当异常产生时,不得创建学生对象。
(4)已给出的代码部分不得改动,否则算错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package FinalTest.GUi.DaAn1819;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

// 学生类
class Student1 {
private String name;
private int age;

public Student1(String s, int a) {
name = s;
age = a;
}

public String toString() {
return name + " " + age;
}
}
// 主应用类
class App1 extends JFrame {
private Student1[] st; // 存储学生对象的数组
private int len; // 实际人数
private JButton b_add, b_cancel, b_show;
private JTextField name, age;
private Label msgLa; // 用于显示异常提示信息

public App1(int maxStudentNum) {
st = new Student1[maxStudentNum];
len = 0;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 100);
setBackground(Color.lightGray);
setLocation(300, 240);
setLayout(new FlowLayout());

name = new JTextField(10); // 调整文本框宽度
age = new JTextField(5);

add(new Label("姓名:"));
add(name);
add(new Label("年龄:"));
add(age);

b_add = new JButton("添加");
add(b_add);
b_cancel = new JButton("取消");
add(b_cancel);
b_show = new JButton("显示");
add(b_show);

msgLa = new Label(" ");
add(msgLa);
init();
setVisible(true); // 设置窗口可见
}

private void showAllStudent() {
clear();
for (int i = 0; i < len; i++) {
System.out.println(st[i]);
}
}

private void clear() {
name.setText("");
age.setText("");
msgLa.setText(""); // 清空消息标签
}
public void init(){
b_add.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
// 获取并处理姓名
String s = name.getText().trim();
if (s.isEmpty()) {
throw new NameNullException1("姓名不能为空");
}

// 获取并处理年龄
int judgeAge;
try {
judgeAge = Integer.parseInt(age.getText().trim());
if (judgeAge < 10 || judgeAge > 60) {
throw new AgeValueException("年龄值不正确");
}
} catch (NumberFormatException ex) {
throw new NumberFormatException("数据格式不正确");
}

// 创建新学生对象并添加到数组中
if (len < st.length) {
st[len++] = new Student1(s, judgeAge);
msgLa.setText("学生添加成功!");
}
clear(); // 清空文本框
} catch (NameNullException1 | AgeValueException | NumberFormatException ex) {
msgLa.setText(ex.getMessage()); // 显示错误信息
}
}
});

b_cancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
clear(); // 清空文本框
}
});

b_show.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showAllStudent(); // 显示所有学生
clear(); // 清空文本框
}
});}

// 姓名为空异常类
class NameNullException1 extends Exception {
public NameNullException1(String message) {
super(message);
}
}

// 年龄值不正确异常类
class AgeValueException extends Exception {
public AgeValueException(String message) {
super(message);
}
}
public static void main(String[] args) {
App1 a = new App1(20); // 最大学生数为20
}
}


补充 implements ActionListener
就可以这样写监听器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class JFOwn extends JFrame implements ActionListener {
public JFOwn(){
this.setTitle("登录界面");
this.setSize(300,300);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
init();
}
private void init(){
JButton jb=new JButton("登录按钮");
JPanel jp=new JPanel();
this.add(jp);
jp.add(jb);
jb.addActionListener(this);
}
//单独重写接口的方法
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(this,"有人点击了登录");

}
}
public static void main(String[] args) {
JFOwn k=new JFOwn();
k.setVisible(true);
}

借此也有一道期末题目
假设某系统设计中已经确定事件源 S(Comp_1 类型),S 上将产生 EvEvent 类型事
件,EvEvent 型事件对应的监听器接口为 EvListener,该接口中包含两个事件处理方
法 action_1(EvEvent e)、action_2(EvEvent e)。Comp_1 类中包含有与
EvListener 接口绑定方法:void addEvListener(EvListener eL)设计代码框
架实现如下要求:当 S 上发生 Ev 型事件并触发 action_1()动作时,输出:“action_1
动作被激发…”。
注:为确保事件能够正常传播、捕获并激发事件处理动作,假定上述所有的 class、接
口、接口中的方法均由系统预定义。另外,需要指明必须要导入的包。(10 分)

1
2
3
4
5
6
7
8
9
10
11
import java.awt.*; 
import java.awt.event.*;
class GUI extends JFrame implements EvListener{
GUI(){
Comp_1 s=new Comp_1();
//假定界面构造部分已完成
s.addEvListener(this);
}
action_1(EvEvent e){System.out.print("action_1 动作被激发。。。");}
action_2(EvEvent e){ ; }
}

线程问题

线程安全处理方法
法一 同步方法:代码块加 synchronized (…),实例加this(注意括号内内容,不要让b一家人来取钱被a一家人干扰),静态加….class(Account.class)
法二 同步代码块:方法限定加上synchronized
法三 Lock锁:自己加锁下锁
1.创建一个锁对象 private final Lock lk=new ReentrantLock();//加上final,避免被修改
2.上锁 lk.lock();
3.释放锁 lk.unlock();
注:为了确保如果代码出现异常也能够下锁,用try-catch-finally语句
pEFVXOH.png

题目一(用list框架,没体现锁的思想,不推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class T implements Runnable{
private int data;
@Override
public void run() {
//synchronized (this) {
int newdata=data;
System.out.print(Thread.currentThread().getName() + ":");
for (int i = 1; i <= 10; i++) {
System.out.print(newdata + " ");
newdata=data+newdata;
}
System.out.println();
//}
}
public T(int data){
this.data=data;
}
}
package FinalTest.Thread.Moni;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class App2 {
public static void main(String[] args) throws InterruptedException {
List<Thread> list=new ArrayList<>();
String s=new String("互斥标记");
System.out.println("线程开始");
Runnable run2=new T(2);
Runnable run3=new T(3);
Runnable run5=new T(5);
Thread thread2 = new Thread(run2,"t2");
Thread thread3 = new Thread(run3,"t3");
Thread thread5 = new Thread(run5,"t5");
list.add(thread2);list.add(thread3);list.add(thread5);
Random r=new Random();
while (list.size()>0) {
int j=r.nextInt(list.size());
list.get(j).start();
list.get(j).join();
list.remove(list.get(j));
}
// // 启动 t2 并等待其完成
// thread2.start();
// thread2.join(); // 主线程等待 t2 完成
//
// // 启动 t3 并等待其完成
// thread3.start();
// thread3.join(); // 主线程等待 t3 完成
//
// // 启动 t5 并等待其完成
// thread5.start();
// thread5.join(); // 主线程等待 t5 完成
//盖住的这部分顺序是固定了的,体现不出每次输出不同的效果,用list集合来装,甚至不用上锁了
System.out.println("程序结束");
}
}



2、下面代码模拟实现 3 台 PC 机共享打印的情形。下面以给出部分代码,请按照要求补
充完整。(20 分)
【要求】
a. PC 类的声明部分不得更改,不得增/删、改 PC 中的属性;
b. 3 个 PC 对象在 main 中同时打印输出,要确保只有当一个作业输出完成后,才能
进行下一个作业的输出。但三个作业打印输出的次序是不确定的;
c. 只有当所有作业都输出完成后,才能执行 main 中最后一条输出语句。
【注意】:已给定的代码不得做任何更改。
class PC implements Runnable{// 模拟的 PC 机
private String printFlag;//打印标记
private String name;
private String[] neiRong;//打印内容
private Thread t;
/* 上面涉及到的属性均已齐全,请补齐所缺的各种方法(15 分) /
}
class App{
public static void main (String[] args) {
String s=”abc”;
String[] s1={“1”,”2”,”3”};
String[] s2={“A”,”B”,”C”,”D”,”E”};
String[] s3={“你好,”,”我也好,”,”大家都好!”};
/
构造 PC 机 t1、t2、t3,并运行 (5 分)
其中 t1、t2、t3 分别对应作业 1、作业 2、作业 3
且只有 t1、t2、t3 均结束,才能执行下面的输出语句 */
System.out.print(“\n 所有作业均已结束!”);
}
}
输出结果为:
作业 1: 1 2 3
作业 3: 你好, 我也好, 大家都好!
作业 2: A B C D E
所有作业均已结束!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class PC implements Runnable{// 模拟的 PC 机
private String printFlag;//打印标记
private String name;
private String[] neiRong;//打印内容
private Thread t;
/* 上面涉及到的属性均已齐全,请补齐所缺的各种方法(15 分) */
public PC(String printFlag,String name,String[] neiRong){
this.printFlag=printFlag;
this.name=name;
this.neiRong=neiRong;
t=new Thread(this);
}
public void start(){ t.start(); }
public void join() throws InterruptedException {
t.join();
}
@Override
public void run(){
synchronized (printFlag) {
System.out.print(name+":");
for (int i = 0; i < neiRong.length; i++) {
System.out.print(neiRong[i]+" ");
}
System.out.println();
}
}
}
class App{
public static void main (String[] args) throws InterruptedException {
String s="abc";
String[] s1={"1","2","3"};
String[] s2={"A","B","C","D","E"};
String[] s3={"你好,","我也好,","大家都好!"};
PC t1=new PC(s,"作业 1",s1);
PC t2=new PC(s,"作业 2",s2);
PC t3=new PC(s,"作业 3",s3);
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
/* 构造 PC 机 t1、t2、t3,并运行 (5 分)
其中 t1、t2、t3 分别对应作业 1、作业 2、作业 3
且只有 t1、t2、t3 均结束,才能执行下面的输出语句 */
System.out.print("\n 所有作业均已结束!");
}
}

变式题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class Print_Server {
private int x;
}
public class T implements Runnable{
private Thread t;
private Print_Server data;
private String name; private String[] say;
public void start(){ t.start(); }
public T(Print_Server d,String n, String []s){
data=d; name=n; say=s; t=new Thread(this);
}


@Override
// public void run() {
// System.out.print(name+"说: ");
// for (String s : say) {
// System.out.print(s+" ");
// }
// System.out.println();
// }
public void run(){
synchronized(data){
System.out.print(name+"说:");
for(int i=0; i<say.length; i++)
System.out.print(say[i]);
System.out.println ();
}
}
}
public class App2 {
public static void main(String[] args) throws InterruptedException {
Print_Server d=new Print_Server();

String s=new String("互斥标记");
System.out.println("线程开始");
String[] s1={"弟子规 ","圣人训 ","首孝弟 ","次谨信 ",
"泛爱众 ","而亲仁 ","有余力 ","则学文"};
String[] s2={"人之初,","性本善,","性相近,","习相远。"};
String[] s3={"赵 ","钱 ","孙 ","李 ","周 ","武 ","郑 ","王 "};
T t1=new T(d,"张三",s1); T t2=new T(d,"李四",s2);
T t3=new T(d,"王五",s3);//锁的data也就是d
t1.start();
t2.start();
t3.start();
}
}

I/O流

字节的编码和解码形式必须统一
编码 string->byte
byte[ ]bytes=” …”.getBytes(“GBK”);
解码 byte->string
String s=new String(bytes,”GBK”);
File
I/O流
pEFMGnO.png
字节流适合数据传送,字符流适合文本内容
InputStream is = new FileInputStream(“file-io-app\src\itheima03.txt”);
byte[] buffer = new byte[3];
int len; // 记住每次读取了多少个字节。 abc 66
while ((len = is.read(buffer)) != -1){
// 注意:读取多少,倒出多少。
String rs = new String(buffer, 0 , len);
System.out.print(rs);
}

//覆盖管道:覆盖之前的数据
// OutputStream os = new FileOutputStream(“file-io-app/src/itheima04out.txt”);
// 追加数据的管道
OutputStream os = new FileOutputStream(“file-io-app/src/itheima04out.txt”, true);
byte[] bytes = “我爱你中国abc”.getBytes();
os.write(bytes);

    os.write(bytes, 0, 15);

    // 换行符
    os.write("\r\n".getBytes());

    os.close(); // 关闭流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1.复制文本文件
public static void main(String[] args) throws Exception {
// 需求:复制照片。
// 1、创建一个字节输入流管道与源文件接通
InputStream is = new FileInputStream("file-io-app\\src\\itheima03.txt");
// 2、创建一个字节输出流管道与目标文件接通。
OutputStream os = new FileOutputStream("file-io-app\\src\\itheima03copy.txt");

System.out.println(10 / 0);
// 3、创建一个字节数组,负责转移字节数据。
byte[] buffer = new byte[1024]; // 1KB.
// 4、从字节输入流中读取字节数据,写出去到字节输出流中。读多少写出去多少。
int len; // 记住每次读取了多少个字节。
while ((len = is.read(buffer)) != -1){
os.write(buffer, 0, len);
}

os.close();
is.close();
System.out.println("复制完成!!");
}

try (
// 1、创建一个文件字符输入流管道与源文件接通
Reader fr = new FileReader(“io-app2\src\itheima01.txt”);
)
char[ ] buffer = new char[3];
int len; // 记住每次读取了多少个字符。
while ((len = fr.read(buffer)) != -1){
// 读取多少倒出多少
System.out.print(new String(buffer, 0, len));
}
// 性能是比较不错的!
} catch (Exception e) {
e.printStackTrace();
}

    try (
            // 0、创建一个文件字符输出流管道与目标文件接通。
            // 覆盖管道
            // Writer fw = new FileWriter("io-app2/src/itheima02out.txt");
            // 追加数据的管道
            Writer fw = new FileWriter("io-app2/src/itheima02out.txt", true);
            ){
                char[] buffer = {'黑', '马', 'a', 'b', 'c'};
        fw.write(buffer);
        fw.write("\r\n");

        // 5、public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去
        fw.write(buffer, 0, 2);
        fw.write("\r\n");
    } catch (Exception e) {
        e.printStackTrace();
    }
    FileWriter必须要关闭流或者刷新流才能保存数据可以写在try的括号里

字节缓冲流来复制文本文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class BufferedInputStreamTest1 {
public static void main(String[] args) {
try (
InputStream is = new FileInputStream("io-app2/src/itheima01.txt");
// 1、定义一个字节缓冲输入流包装原始的字节输入流
InputStream bis = new BufferedInputStream(is);

OutputStream os = new FileOutputStream("io-app2/src/itheima01_bak.txt");
// 2、定义一个字节缓冲输出流包装原始的字节输出流
OutputStream bos = new BufferedOutputStream(os);
){

byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1){
bos.write(buffer, 0, len);
}
System.out.println("复制完成!!");

} catch (Exception e) {
e.printStackTrace();
}
}
}

字符缓冲流来复制文件(由于有新增方法br.readLine(),bw.newLine();所以不用多态去写)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//可以按行去读取,返回的也是String类型,FileInputStream和FileReader的read都是返回的int类型
public class BufferedReaderTest2 {
public static void main(String[] args) {
try (
Reader fr = new FileReader("io-app2\\src\\itheima04.txt");
// 创建一个字符缓冲输入流包装原始的字符输入流
BufferedReader br = new BufferedReader(fr);
){
String line; // 记住每次读取的一行数据
while ((line = br.readLine()) != null){
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class BufferedWriterTest3 {
public static void main(String[] args) {
try (
Writer fw = new FileWriter("io-app2/src/itheima05out.txt", true);
// 创建一个字符缓冲输出流管道包装原始的字符输出流
BufferedWriter bw = new BufferedWriter(fw);
){

bw.write('a');
bw.write(97);
bw.write('磊');
bw.newLine();

bw.write("我爱你中国abc");
bw.newLine();

} catch (Exception e) {
e.printStackTrace();
}
}
}

序列化流
先ObjectOutPutStream再ObjectInputStream(先将对象序列化再反序列化)
对象如果需要序列化,必须实现序列化接口。
transient 这个成员变量将不参与序列化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
public class User implements Serializable {
private String loginName;
private String userName;
private transient int age;
// transient 这个成员变量将不参与序列化。
private transient String passWord;

public User() {
}

public User(String loginName, String userName, int age, String passWord) {
this.loginName = loginName;
this.userName = userName;
this.age = age;
this.passWord = passWord;
}

public String getLoginName() {
return loginName;
}

public void setLoginName(String loginName) {
this.loginName = loginName;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getPassWord() {
return passWord;
}

public void setPassWord(String passWord) {
this.passWord = passWord;
}

@Override
public String toString() {
return "User{" +
"loginName='" + loginName + '\'' +
", userName='" + userName + '\'' +
", age=" + age +
", passWord='" + passWord + '\'' +
'}';
}
}
public class Test1ObjectOutputStream {
public static void main(String[] args) {
try (

// 2、创建一个对象字节输出流包装原始的字节 输出流。
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("E://fxxk.txt"));
){
// 1、创建一个Java对象。
User u = new User("admin", "张三", 32, "666888xyz");

// 3、序列化对象到文件中去
oos.writeObject(u);
System.out.println("序列化对象成功!!");

} catch (Exception e) {
e.printStackTrace();
}
}
}
public class Test2ObjectInputStream {
public static void main(String[] args) {
try (
// 1、创建一个对象字节输入流管道,包装 低级的字节输入流与源文件接通
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E://fxxk.txt"));
){
User u = (User) ois.readObject();
System.out.println(u);
} catch (Exception e) {
e.printStackTrace();
}
}
}

几道真题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package FinalTest.IOStream;
import java.io.*;
public class App1617 {
public static void main(String[] args) {
Reader reader = null;
Writer writer = null;
try {// 创建文件读取流和文件写入流
reader = new FileReader("D:/f2.txt");
writer = new FileWriter("D:/f1.txt");
//char[] chars = new char[10];
int read;
while ((read = reader.read()) != -1) {// 读取并写入
//while ((read = reader.read(chars)) != -1) {
//writer.write(chars, 0, read); // 写入实际读取的字符数量
writer.write(read);
}
System.out.println("复制完成");
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class fabni_text {
// 计算 Fibonacci 数列的递归方法
public static int DiGui(int i){
if(i==1||i==2){
return 1;
}
else{
return DiGui(i-1)+DiGui(i-2);
}
}
public static void main(String[] args) {
Writer writer = null;
BufferedWriter bw = null;
BufferedReader br = null;
try {
// 创建文件写入流
writer = new FileWriter("F:/Fibonacci.txt");
bw = new BufferedWriter(writer);
// 写入 Fibonacci 数列
for (int i = 1; i < 20; i++) {
bw.write(Integer.toString(DiGui(i))+" "); // 将整数转换为字符串
//bw.write(DiGui(i)+" ");
if(i==10){
bw.newLine();
}
}
// 关闭写入流以确保数据被写入
bw.close();
writer.close();
// 创建文件读取流
br = new BufferedReader(new FileReader("F:/Fibonacci.txt"));
String rs;
// 读取文件内容并打印
while ((rs = br.readLine()) != null) {
System.out.println(rs);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭所有资源
try {
if (bw != null) bw.close();
if (br != null) br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class App1718 {
public static void main (String[] args) throws Exception{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("D:/L.txt"));
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("D:/L.txt"));
LinkedList L,newL;
L=new LinkedList();//假设输入 1 2 3 4 -1
System.out.print("序列化前,链表为:");
L.showInfo();
System.out.print("\n 序列化……");
oos.writeObject(L);
newL=(LinkedList) ois.readObject();
//_(_2_) /* 将链表 L 借助序列化机制写入文件 L.dat */
//_(_3_) /* 用反序列化从文件 L.dat 复原链表,表头名称为 newL */
System.out.print("反序列化后,链表为:");
newL.showInfo();
}
}