1. 书面作业
本次PTA作业题集异常
1. 常用异常
结合题集题目7-1回答
1.1 自己以前编写的代码中经常出现什么异常、需要捕获吗(为什么)?应如何避免?
- ArrayIndexOutOfBoundsException(数组下标越界)无需捕获,因为属于RuntimeException。
- NullPointerException(空指针),无需捕获,因为属于RuntimeException。在应用时要注意判断是否为空指针
- ClassCastException(类型转换错误)不需要捕获,在强制类型转换时要先进行判断
- IllegaArgumentException(输入参数错误)不需要捕获,注意输入
1.2 什么样的异常要求用户一定要使用捕获处理?
除了Error与RuntimeException及其子类,其他异常都需要捕获处理
2. 处理异常使你的程序更加健壮
题集题目7-2
2.1 实验总结。并回答:怎么样才能让你的程序更加健壮?
总结:输入非整型的数时不放入数组,则设定一个flag,当输入数为整型时存入,否则continue;
在可能报错的时候加上 try-catch语句。
3. throw与throws
题集题目7-3
阅读Integer.parsetInt
源代码
3.1 Integer.parsetInt
一开始就有大量的抛出异常的代码,这种做法有什么好处?
3.2 结合自己编写的程序与3.1,分析自己编写的方法抛出异常时一般需要传递给调用者一些什么信息?
题目7-3中抛出异常 IllegalArgumentException
时会传递给调用者知道,具体是哪个步骤(或输入)错误,这样下次调用时可以避免错误
4. 用异常改进ArrayIntegerStack
题集题目6-3
4.1 结合6-3代码,回答使用抛出异常的方式代表程序运行时出错有什么好处?比单纯的返回错误值,有何优点?
单纯返回错误值,让调用者很难直接找到错误点,使用抛出异常的方式更加直观,便于调用者修改,程序也不会终止
4.2 如果一个方法内部的内码抛出的是RuntimeException类型的异常,那么方法声明是否应该使用throws
关键字,如果使用throws
关键字声明该方法抛出的异常,能给我们带来什么好处吗?
可以不使用,因为不是checked Exception。
这样就可以在调用该方法的地方使用try-catch捕获其抛出的异常
5. 函数题-多种异常的捕获
题集题目6-1
5.1 结合6-1代码,回答:一个try块中如果可能抛出多种异常,且异常之间可能有继承关系,捕获时需要注意些什么?
catch的异常一定是子类在前,父类在最后
5.2 一个try块中如果可能抛出多种异常,使用Java8的多重异常捕获语法需要注意些什么?
6. 为如下代码加上异常处理
byte[] content = null;
FileInputStream fis = new FileInputStream("testfis.txt");
int bytesAvailabe = fis.available();//获得该文件可用的字节数 if(bytesAvailabe>0){ content = new byte[bytesAvailabe];//创建可容纳文件大小的数组 fis.read(content);//将文件内容读入数组 } System.out.println(Arrays.toString(content));//打印数组内容
6.1 改正代码,并增加如下功能。当找不到文件时,需提示用户找不到文件xxx,请重新输入文件名
,然后尝试重新打开。 如果是其他异常则提示打开或读取文件失败!
。
注1:里面有多个方法均可能抛出异常。
功能2:需要添加finally
关闭文件。无论上面的代码是否产生异常,总要提示关闭文件ing
。如果关闭文件失败,提示关闭文件失败!
public static void main(String[] args){ // TODO Auto-generated method stub byte[] content = null; FileInputStream fis = null; String file=null; Scanner sc=new Scanner(System.in); try{ file=sc.next(); fis = new FileInputStream(file); int bytesAvailabe = fis.available();//获得该文件可用的字节数 if(bytesAvailabe>0){ content = new byte[bytesAvailabe];//创建可容纳文件大小的数组 fis.read(content);//将文件内容读入数组 } }catch (FileNotFoundException e) { System.out.println("找不到文件,请重新输入文件名"); file=sc.next(); }catch(IOException e){ System.out.println("打开或读取文件失败!"); }finally{ System.out.println("关闭文件ing"); try { //关闭资源也有可能出错 fis.close(); } catch (Exception e) { System.out.println("关闭文件失败!"); } } System.out.println(Arrays.toString(content));//打印数组内容 }
6.2 结合题集6-2
代码,要将什么样操作放在finally块?为什么?使用finally关闭资源需要注意一些什么?
finally中是一定会被执行的,eg:将文件关闭,就可以写在finally中,要注意关闭是否关闭成功,是否也需要try-catch
6.3 使用Java7中的try-with-resources
来改写上述代码实现自动关闭资源。简述这种方法有何好处?
自动关闭,不用判断关闭过程中是否会产生异常
public static void main(String[] args){ Scanner sc=new Scanner(System.in); String str; byte[] content = null; //FileInputStream fis=null; try (FileInputStream fis = new FileInputStream("E://test/testfis.txt")){ //fis = new FileInputStream("testfis.txt"); int bytesAvailabe = fis.available();//获得该文件可用的字节数 if(bytesAvailabe>0){ content = new byte[bytesAvailabe];//创建可容纳文件大小的数组 fis.read(content);//将文件内容读入数组 } }catch(FileNotFoundException e){ System.out.println("找不到文件"); }catch(IOException e) { System.out.println("打开或读取文件失败"); } System.out.println(Arrays.toString(content));//打印数组内容 }
7. 读取文件并组装对象
实验任务书中中的题目3:读取文件并组装对象
7.1 给出关键代码(需出现你的学号)。额外要求:捕获异常时,将错误的信息按照出错原因:行号:该行内容格式输出。
/*201721123095*/ public static void main(String[] args){ Scanner in =null; ArrayList<User>student=new ArrayList<User>(); try { in= new Scanner(new File("E://test/身份证号.txt"));//为myfile.txt这个File创建一个扫描器in int count=0; while(in.hasNextLine()){ String line = in.nextLine();//读出myfile.txt的下一行 count++; Scanner lineScanner = new Scanner(line);//为每一行建立一个扫描器 //System.out.println("lineScanner="+lineScanner); lineScanner.useDelimiter(" ");//使用空格作为分隔符 //System.out.println(line); try { String a1 = lineScanner.next();//姓名 if(a1.length()==0||a1.length()>10) { throw new IllegalArgumentException("a1.length = " + a1.length()); } String a2 = lineScanner.next();//身份证号 if(a2.length()==0) { throw new IllegalArgumentException("a2.length = " + a2.length()); } String a3 = lineScanner.next();//性别 if(!a3.equals("男")&&!a3.equals("女")) { throw new IllegalArgumentException("性别出错:" + a3); } String a4 = lineScanner.next();//年龄 String a5 = lineScanner.next();//地址 while(lineScanner.hasNext()){//谨防地址只有一段 a5 += lineScanner.next(); } User user=new User(a1,a2,a3,Integer.parseInt(a4),a5); student.add(user); }catch(IllegalArgumentException e) { System.out.println("出错类型:"+e+"出错在"+count+"行:"+line); } //System.out.println(a1+a2+a3+a4+a5); } }catch(FileNotFoundException e) { e.printStackTrace(); }finally { if(in!=null) in.close(); } Collections.sort(student,new AgeComparator()); for (User e : student) { System.out.println(e.toString()); } }
运行结果:
7.2 如果文件有上万行文本,出错的信息可能有很多行,如果将出错信息直接输出到控制台容易被忽略,请问如何解决?
可以改成抛出异常,让调用者清晰知道是哪里出错