关于第五周大家学习问题的总结
第五周同学们学习了教材的第八章、第九章,在前面的学习过程中,我们大致了解了java中的基础语法,函数构造调用,以及当以项目为基础设计代码时我们该如何使用继承和接口,对java已有初步了解,因此第五周同学们进一步学习的是如何处理程序中的异常状况,下面是同学们学习过程中出现的各种问题。
1.问题1:
在看书时不知道Error与Exception的区别。
Exception或其子类实例代表程序设计本身的错误,所以通常称错误处理为异常处理(Exception Handling)。
Error与其子类实例代表严重系统错误,如硬件层面错误、JVM错误或内存不足等问题,虽然也可以使用try、catch来处理Error对象,但并不建议,发生严重系统错误时,Java应用程序本身是无力回复的。
2.问题2:
在编写书上课后习题的代码时经常遇见args[0],开始并不清楚args[0]代表什么,只记得在最开始学java时,要打开main方法就一定要写public static void main(String[] args),后面才知道args是一个字符串数组的变量名,不是关键字,是arguments的缩写,只是一个默认名。String[ ] args表示给主方法传一个字符串数组。
3.问题3:
看不懂Lambda的用法。
询问了一下同学,又通过几个实例了解到Lambda表达式的语法省略了接口类型与方法名称,->左边是参数列,而右边是方法本体;在Lambda表达式中使用区块时,如果
方法必须有返回值,在区块中就必须使用return。interator()方法提升至新的java.util.Iterable父接口。
4.问题4:
如果父类异常对象在子类异常前被捕捉,则catch子类异常对象的区块将永远不会被执行。catch括号中列出的异常不得有继承关系,否则会发生编译错误。
5.问题五:
throw和throws的区别?
throws是用来声明一个方法可能抛出的所有异常信息
throw则是指抛出的一个具体的异常类型。
通常在一个方法(类)的声明处通过throws声明方法(类)可能抛出的异常信息,而在方法(类)内部通过throw声明一个具体的异常信息。
throws通常不用显示的捕获异常,可由系统自动将所有捕获的异常信息抛给上级方法。
throw则需要用户自己捕获相关的异常,而后在对其进行相关包装,最后在将包装后的异常信息抛出。
6.问题6:
如何使用finally
无论try区块中有无发生异常,若撰写有finally区块,则finally区块一定会被执行。如果程序撰写的流程先return了,而且也有finally区块,finally区块会先执行完后,再将值返回。例如下面这个范例会先显示finally、、、,然后再显示1 。
代码如下:
public class FinallyDemo{
public static void main(String[] args){
System.out.println(test(true));
}
static int test(boolean flag){
try{
if(flag){
return 1;
}
}finally{
System.out.println("finally...");
}
return 0;
}
}
7.问题7:
若编程过程中出现了“unrepored exception IOException must be Caught or declare to be thrown···”
使用try、catch打包System.in.read(),声明throws java.io.IOException。
8.问题8:
断点的使用:
①断言客户端调用方法前,已经准备好某些前置条件(通常在private方法之中)
②断言客户端调用方法后,具有方法承诺的结果。
③断言对象某个时间点下的状态。
④使用断言取代批注。
⑤断言程序流程中绝对不会执行到的程序代码部分。
9.问题9:
访问Map键值
如果想取得Map中所有的键,可以调用Map的keySet()返回Set对象。
10.问题10:
Exception与RuntimeException的区别:
Exception:在程序中必须使用try、catch进行处理。
RuntimeException:可以不使用try、catch进行处理,但是如果有异常产生,则异常将由JVM进行处理。
11.问题11:
第八章课后习题8.
public class Main {
public static void main(String[] args) {
try {
int number = Integer.parseInt(args[0]);
System.out.println(number++);
} catch(RuntimeException | NumberFormatException ex) {
System.out.println("必须输入数字");
}
}
}
执行时若没有指定命令行自变量,以下描述何者正确?
A、 编译错误
B、 显示"必须输入数字"
C、 显示ArrayIndexOutOfBoundException堆栈追踪
D、 不显示任何讯息
为什么选择A,而不是B?
12.问题12:
在学习使用Properties的时候一开始不知道如何从文档中加载属性,代码如下:
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class MapLoadProperties {
public static void main(String[] args) throws IOException {
Properties props = new Properties();
props.load(new FileInputStream(args[0]));
System.out.println(props.getProperty("CH5.username"));
System.out.println(props.getProperty("CH5.password"));
}
}
从代码发现,后面输出的变量是props.getProperty,所以我觉得应该从这个变量入手,也就是从代码段props.load(new FileInputStream(args[0]));来研究输出的变量,我通过API中了解FileInputStream()调用的应该就是前面说的文档,那么该如何调用呢?
一开始我尝试了直接用properties文件名替换掉args[0],但是程序无法编译了,思考了一下我觉得应该是在调用文档的时候,文档名少了""的关系,果然加上了就可以编译了
13.问题13:
finally块中的代码一定会被执行吗?
public class TryCatchFinallyAutoClosableDemo {
public static void main(String[] args) {
try (Resource res = new Resource()) {
res.doSome();
} catch (Exception ex) {
ex.printStackTrace();
}
finally {
System.out.println("finally…");
}
}
}
class Resource implements AutoCloseable {
void doSome() {
System.out.println("做一些事情");
}
@Override
public void close() throws Exception {
System.out.println("资源被关闭");
}
}
finally块应该是都会被执行的。
但是在网上看到一种情况可以让finally块不执行,就是加上System.exit()
14.问题14:
Comparable与Comparator
1.Collection的sort()方法要求被排序的对象必须操作java.lang.Comparable接口。Collection的sort()方法在取得a对象与b对象进行比较时,会先将a对象扮演为Comparable,然后调用a.compareTo(b),如果a对象顺序上小于b对象则返回小于0的值,若顺序上相等则返回0,若顺序上a大于b则返回大于0的值。
2.Collections的sort()方法有另一个重载版本,可接受java.util.Comparator接口的操作对象,如果使用这个版本,排序方式将根据Comparator的compare()定义来决定。
import java.util.*;
import static java.util.Comparator.*;
public class Sort6 {
public static void main(String[] args){
List words=Arrays.asList("B","X","A","M",null,"F","W","O",null);
words.sort(nullsFirst(reverseOrder()));
System.out.println(words);
}
}
15.问题15:
认识堆栈追踪
在多重方法调用下,异常发生点可能是在某个方法之中,若想得知异常发生的根源,以及多重方法调用下异常的堆栈传播,可以使用堆栈追踪来取得相关信息。
使用方法:直接调用异常对象的printStackTrace()。
堆栈追踪信息中显示了异常类型,最顶层是异常的根源,以下是调用方法的顺序,程序代码行数是对应于当初的程序原始码,如果想要取得个别的堆栈追踪元素进行处理,则可以使用getStackTrace(),在捕捉异常后什么都不做的话或者做了不适当的处理,这种程序代码会对应用程序维护造成严重伤害。在使用throws重抛异常时,异常的追踪堆栈起点,仍是异常的发生根源,而不是重抛异常的地方。如果想要让异常堆栈起点为重抛异常的地方,可以使用fillInStackTrace()方法,这个方法会重新装填异常堆栈,将起点设为重抛异常的地方,并返回Throwable对象。
public class StackTraceDemo3{
public static void main(String[] args){
try{
c();
}catch(NullPointerException ex){
ex.printStackTrace();
}
}
static void c(){
try{
b();
}catch(NullPointerException ex){
ex.printStackTrace();
Throwable t=ex.fillInStackTrace();
throw (NullPointerException) t;
}
}
static void b(){
a();
}
static String a(){
String text=null;
return text.toUpperCase();
}
}
16.问题16:
java.lang.AutoCloseable接口
JDK7的尝试关闭资源语法可套用的对象,必须操作java.lang.AutoCloseable接口。
AutoCloseable是JDK7新增的接口,仅定义了close()方法。只要操作AutoCloseable接口,就可以套用至尝试关闭资源语法。尝试关闭资源语法也可以同时关闭两个以上的对象资源,只要中间以分号间隔。
在try的括号中,越后面撰写的对象资源会越早被关闭。
17.问题17:
课本 TryCatch的两个程序比较:
第一个程序是将while循环语句放在try里面变量的定义都在try-catch里,而且当遇到错误输入时程序即停止。
try{
Scanner console =new Scanner (System.in);
double sum=0;
int count =0;
while(true){
int number=console.nextInt();
if(number==0)
{
break;// TODO code application logic here
}
sum+=number;
count++;
}System.out.printf("平均 %.2f%n",sum/count);
}catch (InputMismatchException ex){
System.out.println("必须输入整数");
}
}
}
18.问题18:
InputStream与Reader差别 OutputStream与Writer差别
InputStream和OutputStream类处理的是字节流,数据流中的最小单位是字节(8个bit)
Reader与Writer处理的是字符流,在处理字符流时涉及了字符编码的转换问题
import java.io.*;
public class EncodeTest {
private static void readBuff(byte [] buff) throws IOException {
ByteArrayInputStream in =new ByteArrayInputStream(buff);
int data;
while((data=in.read())!=-1) System.out.print(data+" ");
System.out.println(); in.close(); }
public static void main(String args[]) throws IOException {
System.out.println("内存中采用unicode字符编码:" );
char c='好';
int lowBit=c&0xFF; int highBit=(c&0xFF00)>>8;
System.out.println(""+lowBit+" "+highBit);
String s="好";
System.out.println("本地操作系统默认字符编码:");
readBuff(s.getBytes());
System.out.println("采用GBK字符编码:");
readBuff(s.getBytes("GBK"));
System.out.println("采用UTF-8字符编码:");
readBuff(s.getBytes("UTF-8")); }
}
Reader类能够将输入流中采用其他编码类型的字符转换为Unicode字符,然后在内存中为其分配内存
Writer类能够将内存中的Unicode字符转换为其他编码类型的字符,再写到输出流中。
19.问题19: