1. 本周学习总结
1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容。
异常(补充):
- 不要滥用异常
1) 异常会带来程序性能的降低,不要用异常代替正常的程序流程
2) 显而易见的异常可以在编写程序的时候自己添加条件 - 调试技术
调试与异常是相关的
1)调试方法
——使用System.out.println("x="+x);
打印变量值
——每个需要测试的类中放一个main方法
——JUnit(单元测试框架)
——日志(现在用的更多使用第三方日志框架Log4j2)
——Throwable的printStackTrace方法(可看)
——System.err...
——将错误信息保存到文件中(java Test 2 >errors.txt)
2)调试器的使用
——断点的设置与清除
——使用快捷键进调试
多线程:
2. 书面作业
——本次PTA作业题集异常
、多线程
1. finally——题目4-2
1.1 截图你的提交结果(出现学号)
1.2 4-2中 finally中捕获异常需要注意什么?
答: 在4-2中,根据题意——无论向系统申请资源成功与否都要释放资源,因此释放资源的相关代码要放在finally中;无异常时打印resource release success
,在捕获异常成功时用System.out.println(e)
打印释放资源错误信息。
2. 用异常改进ArrayIntegerStack——题目4-3
2.1 截图你的提交结果(出现学号)
2.2 实验总结
我的总结: 本题考查运用异常,在已经编好的程序中添加出错时抛出异常的功能。 使用异常来提示用户出错,可以让用户清晰地明白哪个地方甚至哪个自己输入的点有错,从而注意或改进,比起只是返回 null的实用性大大增强了;所以本题也更好的启发我如何运用异常来改进自己的程序,增加实用性。
3. 自定义异常——题目5-4
4.1 截图你的提交结果(出现学号)
4.2 自定义异常有哪几个关键点?
答:
- 自定义异常是 Throwable类的子类;
- 要让该异常明确提示用户错误的原因;
- 自定义的异常是属于 Unchecked Exception还是 Checked Exception(一般继承 Exception);
- 根据程序需求自定义异常,不要滥用。
4. 读取文件并组装对象——实验任务书中中的题目3:读取文件并组装对象
给出关键代码(需出现你的学号)
4.1 跳过错误行:
- 相关代码
try {
String a1 = lineScanner.next();// 姓名
String a2 = lineScanner.next();// 身份证号
String a3 = lineScanner.next();// 性别
String a4 = lineScanner.next();// 年龄
String a5 = lineScanner.next();// 地址
while (lineScanner.hasNext()) {// 谨防地址只有一段
a5 += lineScanner.next();
}
System.out.println(a1 + a2 + a3 + a4 + a5);
} catch (Exception e) {
}
4.2 定位错误:
- 相关代码
public class ReadFileUsingScanner201521123094 {
public static void main(String[] args) throws FileNotFoundException {
List<User> student = new ArrayList<User>();
Scanner in = new Scanner(new File("身份证号.txt"));// 为myfile.txt这个File创建一个扫描器in
while (in.hasNextLine()) {
try {
String line = in.nextLine();// 读出myfile.txt的下一行
Scanner lineScanner = new Scanner(line);// 为每一行建立一个扫描器
// System.out.println("lineScanner="+lineScanner);
lineScanner.useDelimiter(" ");// 使用空格作为分隔符
// System.out.println(line);
try {
String a1 = lineScanner.next();// 姓名
String a2 = lineScanner.next();// 身份证号
String a3 = lineScanner.next();// 性别
String a4 = lineScanner.next();// 年龄
String a5 = lineScanner.next();// 地址
while (lineScanner.hasNext()) {// 谨防地址只有一段
a5 += lineScanner.next();
}
System.out.println(a1 + a2 + a3 + a4 + a5);
if (a1.length() == 0 || a1.length() > 10) {
throw new NoNameException("没有填写姓名");
}
if (a2.length() == 0) {
throw new NoIDcardException("没有填写身份证号码");
}
if (!a3.equals("男") && !a3.equals("女")) {
throw new NoGenderException("没有填写性别");
}
student.add(new User(a1, a2, a3, Integer.parseInt(a4), a5));
} catch (NumberFormatException e) {
System.err.println(line + "\n" + e + " :信息格式错误");
} catch (NoSuchElementException e) {
System.err.println(line + "\n" + e + " :信息多处缺失");
} catch (Exception e) {
System.err.println(line + "\n" + e);
continue;
}
} catch (Exception e) {
e.printStackTrace();
}
}
......
}
4.3 按年龄排序:
- 相关代码
List<User> student = new ArrayList<User>();
Collections.sort(student, new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getAge() - o2.getAge();
}
});
for (User user : student) {
System.out.println(user.toString());
}
5. 学会使用Eclipse进行调试——观看相关调试视频
5.1 简述使用Eclipse进行调试需要几步?
答:
(1)在程序可能发生错误的地方设置断点:双击可能出错行数前的空白位置。
(2)启动调试模式:点击“昆虫”图标,进入Eclipse专门进行调试的debug perspective。
(3)查看状态值:在debug模式中在可能出现错误的行数上一一检查。
(4)清除所有断点,结束该程序。
5.2 调试时F5, F6, F7快捷键各有什么不同?什么情况该使用哪个快捷键?
答:
F5快捷键:跳入函数或方法中(step into)——问题出现在这个方法中,跳入调试
F6快捷键:跳过这个函数或语句(step over)——确定问题不是出现在当前语句,跳过这个语句
F7快捷键:从函数中跳出(step return)——确定问题不是出现在这个函数中,且函数语句多,一行行跳出不现实
5.3 除了Eclipse的调试器,你还使用什么方法调试程序?
答:
(1)根据系统崩溃时出现的提示,在那一行或者几行进行检查,看是否能够解决错误。
(2)新学习的System.out.println()调试。
5.4 选做:实验任务书中的题目5:使用Eclipse进行调试
中的选做——使用Eclipse调试技巧,调试MessageBoard.zip中的系统直至可以正常运行。
- 错误点1:没有将用户名和密码传入mmm
- 修改:
将new User(name, pas);
改成mmm.setUser(new User(name, pas));
将name和pas的输入形式改为sc.next();
否则出现如下错误:
- 错误点2:没有传入用户完整的信息,mealist的size为0
- 修改:
将meslist.add(new Message(mes,user.getUsername()));
改成meslist.add(new Message(mes, user));
- 正常运行结果
6. 题集多线程
6.1 程序填空3-1、3-2。(截图提交结果,出现你的学号)
6.2 函数4-1(Thread)、4-2(Runnable)(截图提交结果,出现你的学号)
6.3 函数4-3(Runnable与匿名内部类)(截图提交结果,出现你的学号),并使用Labmda表达式改写。
Labmda表达式改写代码
6.4 实验总结
- 程序填空3-1:本题考查——守护线程。
前台线程死亡,守护线程自动结束。使用setDaemon()将t1设为守护线程。 - 程序填空3-2:本题考查——等待线程终止。
使用join()方法使t1结束后才执行主线程。 - 函数4-1:本题考查——多线程的创建。
MyThread类继承自Thread,其中定义run()方法,操作为:循环输出。(自定义循环次数)。 - 函数4-2:本题考查——Runnable与停止线程。
定义的MonitorTask类实现Runnable接口;一开始无从下手,然后老师改了题目就按部就班的做;注意因为对每个传入的word只能检查一遍,检查过后的word要置空。 - 函数4-3:本题考查——Runnable匿名内部类的写法。
一开始就忘了匿名内部类格式,通过PPT回顾后,加深知识点的记忆。这题还有一点不同new Runnable()
的放置——Thread t1 = new Thread(new Runnable()...
7. 源代码阅读:多线程程序 BounceThread
7.1 哪个类是支持多线程的类,它实现了什么接口。这个类做了些什么?
答:
(1)BallRunnable类是支持多线程的类;
(2)BallRunnable类实现了Runnable接口;
(3)BallRunnable类运行弹球。
① 声明属性;② run()方法:(循环1000次)move(小球移动的函数)->重画组件->暂停5milliseconds
7.2 Ball.java这个程序只做了两件事,这两件事分别是什么?
答:
(1)定义了move()方法:移动球的位置,如果达到边缘值,使其反向运动
(2)定义了getShape()方法:获取小球的大小和位置
7.3 BallComponent也只做了两件事,这两件事分别是什么?
答:
(1)定义了add()方法:添加小球
(2)定义了paintComponent()方法:画出小球
7.4 BounceThread中,什么时候启动了新线程?
答:
在BounceFrame中的addBall()方法中的t1.start()启动线程。
7.5 这个程序是如何实现?一个大致的执行流程是什么?
答:大致流程
(1)搭建图形界面
(2)点击start按钮,运行小球
(3)每点击一次就出现一个小球(点击次数不超过1000)
(4)小球到一定步数时就停止在界面上
(5)点击close按钮,停止运行
8. 购物车系统中的多线程
8.1 购物车系统中可能存在哪些多线程问题?
答:多用户多线程
- 用户同时登陆购物车系统
- 用户同时购买最后一件物品
9. 选做:单元测试JUint4——实验任务书中的题目6:单元测试使用JUnit4
。(待)
- 自己编写的冒泡排序
- 系统类库的Arrays.sort()
10. 选做:JavaFX入门(待)
——如果未完成作业1、2的请先完成。如果已完成的请完成第五部分:将数据用 XML 格式存储或第六部分:统计图(漂亮的图表)。注:内有代码,可在其上进行适当的改造。建议按照里面的教程,从头到尾自己搭建。
3. 码云上代码提交记录
——题目集:异常、多线程(3-1, 3-2, 4-1, 4-2, 4-3)
3.1. 码云代码提交记录
——在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 然后搜索并截图
4. 选做:课外阅读(待)
4.1 Java Concurrent Animated
4.2 线程的高级知识笔记
阅读理解