20155313 2016-2017-2 《Java程序设计》第五周学习总结
教材内容学习
第八章 异常处理
程序中总有些意想不到的状况所引发的错误,Java中的错误也以对象方式呈现为java.lang.Throwable 的各式子类实例。只要你能捕捉包装的对象,就可以针对该错误做一些处理,例如:试回复正常流程、进行日志记录、以某种形式提醒用户。
下面的例子是求输入数的平均数:
package cc.openhome;
import java.util.Scanner;
public class Average {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
double sum = 0;
int count = 0;
while(true) {
int number = console.nextInt();
if(number == 0) {
break;
}
sum += number;
count++;
}
System.out.printf("平均 %.2f%n", sum / count);
}
}
如果我们输入:10 20 30 0(回车)会得到平均数20,但是如果我们在键入的时候出现错误,若键入:1o 20 30 0(回车),则我们会得到下面的错误提示:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at cc.openhome.Average.main(Average.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Process finished with exit code 1
因此我们可以try...catch来避免因为输入错误造成的程序中断,下面举了一个例子:
package cc.openhome;
import java.util.*;
public class Average2 {
public static void main(String[] args) {
try {
Scanner console = new Scanner(System.in);
double sum = 0;
int count = 0;
while (true) {
int number = console.nextInt();
if (number == 0) {
break;
}
sum += number;
count++;
}
System.out.printf("平均 %.2f%n", sum / count);
} catch (InputMismatchException ex) {
System.out.println("必須輸入整數");
}
}
}
这个例子中,对于处理错误是采取要求重新输入的方式,当然你也可以采取比如略过非法输入进行求平均值计算等方法进行异常处理。
如果在方法设计流程中发生异常,而你设计时并没有充足的信息知道该如何处理,那么可以抛出异常,让条用方法的客户端来处理。例如:
package cc.openhome;
import java.io.*;
import java.util.Scanner;
public class FileUtil {
public static String readFile(String name) throws FileNotFoundException {
StringBuilder text = new StringBuilder();
try {
Scanner console = new Scanner(new FileInputStream(name));
while(console.hasNext()) {
text.append(console.nextLine())
.append('
');
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
throw ex;
}
return text.toString();
}
}
上面的程序中throws FileNotFoundException(声明方法中会抛出异常)与throw ex(执行时抛出异常)两处关键语句让try...catch处理不了异常的时候,可以抛出由调用方法的客户端处理,并且可以实现先处理部分事项再抛出。
在多重方法调用下,异常发生点可能时在某个方法之中,若想得知发生的根源,以及多重方法调用下异常的堆栈传播,可以利用异常对象自动收集的堆栈追踪来取得相关信息。
查看堆栈追踪最简单的方法,就是直接调用异常对象printStackTrace()。例如:
package cc.openhome;
public class StackTraceDemo {
public static void main(String[] args) {
try {
c();
} catch(NullPointerException ex) {
ex.printStackTrace();
}
}
static void c() {
b();
}
static void b() {
a();
}
static String a() {
String text = null;
return text.toUpperCase();
}
}
程序执行的某个时间点或某个情况下,必然处于或不处于何种状态,这是一种断言,例如某个时间点程序某个变量值一定时多少。断言的结果一定时成立或不成立,预期结果与实际程序状态相同时,断言成立,否则断言不成立。
下面有两种使用语法:
assert boolean_expression;
assert boolean_expression : detail_expression;
boolean_expression 若为true,则什么事都不会发生,如果为false,则会发生java.lang.AssertionError,此时若采取的是第二个语法,则会将detail_expression的结果显示出来,如果当中是个对象,则调用toString()显示文字描述结果。
finally可以搭配try...catch来执行关闭资源的动作,无论try区块中有无发生异常,若撰写有finally区块,则finally区块一定会被执行。例如:
package cc.openhome;
import java.io.*;
import java.util.Scanner;
public class FileUtil_2 {
public static String readFile(String name) throws FileNotFoundException {
StringBuilder text = new StringBuilder();
Scanner console = null;
try {
console = new Scanner(new FileInputStream(name));
while (console.hasNext()) {
text.append(console.nextLine())
.append('
');
}
} finally {
if(console != null) {
console.close();
}
}
return text.toString();
}
}
第九章 Collection与Map
list是一种Collection,作用是收集对象,并以索引方式保留收集的对象顺序,其操作类之一是java.lang.ArrayList。List有两种不同的类ArrayList与LinkedList,在使用过程中前者是偏向于使用数组的特性,后者则是采用了链接结构。
关于收集对象,在收集过程中若有相同对象,则不再重复收集,若有这类需求,可以使用Set接口的操作对象。例如:
static Set tokenSet(String line) {
String[] tokens = line.split(" ");
return new HashSet(Arrays.asList(tokens));
}
这个只是一个程序中的片段,一个子函数,其中就使用了HashSet收集不重复的字符串。
如果希望收集对象时以队列方式,收集的对象加入至尾端,取得对象时从前端,则可以使用Queue接口的操作对象。如果对象有操作Queue,并打算以队列方式使用,且队列长度受限,通常建议使用offer()、poll()与peek()等方法。
Queue与Deque等义方法
Queue方法 | Deque等义方法 |
---|---|
add() | addLast() |
offer() | offerLast() |
remove() | removeFirst() |
poll() | pollFirst() |
element() | getFirst() |
peek() | peekFirst() |
如果项取得Map中所有的键,可以调用Map的KeySet()返回Set对象。由于键时不重复的,所以用Set操作返回时理所当然的做法,如果想取得Map中所有的值,则可以使用values()返回Collection对象。
教材学习中的问题和解决过程
本周的教材学习中出现了很多的问题,很大一方面是概念的问题,课本中提出的新概念无法通过阅读课本弄清楚,然后在后面的学习中就很迷茫。直到周末快结束我还没有整理完教材学习的问题,会在新的一周前几天尽快整理、解决并上传。
代码调试中的问题和解决过程
代码调试问题:课本中命名为SimpleLinkedList的java文件写入我在Idea中创建的工程以后,工程内其他的java文件都无法正常运行。截图如下:
解决方案:在同学的提示下,我将SimpleLinkedList文件最后的返回值由elem修改成了o以后,其他的java文件又可以重新运行。
代码托管
- 代码提交过程截图:
- 运行 git log --pretty=format:"%h - %an, %cd : %s" 并截图
- 代码量截图:
- 运行 find src -name "*.java" | xargs cat | grep -v ^$ | wc -l 并截图
上周考试错题总结
- 填空:使用JDB进行调试时单步执行命令有step和next,我们优先使用(next)。
- 填空:System.out.println( “HELLO”.( toLowerCase() ) ) 会输出“hello”...
- 填空:父类和子类要有(ISA 或“是一种”)关系
- 填空:写出编译P165 RPG.java的命令(javac –d RPG.java)
- 填空:面向对象中,设计经验可以用(设计模式)表达
- 填空:用enum定义一个Season的类型表示四季(public enum Season{SPRING, SUMMER, AUTUMN,WINTER})
- 实现接口表示(拥有行为),但不是ISA关系。
- 填空:Java中类可以实现两个以上的(接口),也就是拥有多种行为
- 填空:实现一个类中的equals()方法时,一定要同时实现(hashCode())方法
- 判断:Math中的abs()方法可以Override.(X)
结对及互评
与20155201李卓雯同学结对
点评过的同学博客和代码
20155201
20155208
20155314
20155303
感悟与思考
这一周主要学习了第八章的错误处理,java系统内置的错误处理与c语言手动编译的if判断错误有很大的不同,体现了java语言面向对象的特点,同时也体现了java更加丰富的内置功能。此外,最近这几周的java学习确实压力很大,因为我并没有如老师说的课后每周40个学时去学习= =,所以很多的老的内容还没弄懂新的知识就补充进来,让我压力很大。不过老师上周提出的partner学习模式可能可以给我很大的帮助,借助同是萌新的同学的解释能让我更容易去理解一些新的内容。上个星期,之前一起做挑战杯项目的同学商量再一起做接下来的大创项目,我们的课题就是借助java平台开发学生生活服务平台终端,那些同学有java学得非常棒的,希望这个项目能对java的课程学习有所帮助。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 50/100 | 1/2 | 10/20 | |
第二周 | 150/200 | 1/2 | 20/30 | |
第三周 | 168/200 | 1/2 | 15/20 | |
第四周 | 300/500 | 1/2 | 20/20 | |
第五周 | 885/1000 | 1/2 | 30/30 |
参考资料
《Java学习笔记(第8版)》学习指导
Java多线程之Runable与Thread
2016-2017-2 《Java程序设计》教学进程