第1关:了解异常 - ID检测
任务描述
本关的任务是通过Java
中的异常机制,来实现对ID
合法性的检测。若ID
长度为7
,则定义为合法;否则定义为不合法。
相关知识
什么是异常?
异常实际上是程序中错误导致中断了正常的指令流的一种事件。
和传统的方法比较,异常的优点如下:
- 把错误代码从常规代码中分离出来
- 把错误传播给调用堆栈
- 按错误类型和错误差别分组
- 系统提供了对于一些无法预测的错误的捕获和处理
- 克服了传统方法的错误信息有限的问题
异常的分类
Java
定义了一个异常类的层次结构,以Throwable
开始,扩展出Error
和Exception
,而Exception
又扩展出IOException
类和RuntimeException
类.
Error
:由Java
虚拟机生成并抛出,Java
程序不做处理。Exception
(程序中的问题,可预知的):Java
编译器要求Java
程序必须捕获或声明所有的非运行时异常。Runtime Exception
(被0
除等系统错误,数组下标超范围):由系统检测,用户的Java
程序可不做处理,系统将它们交给缺省的异常处理程序。IOException
:流异常,通常用于文件读取中。
常见的异常如下图所示:
异常的抛出
异常有两个过程,一个是抛出异常,另一个是捕捉异常。
抛出异常有三种形式:系统自动抛异常、throw
和throws
。
系统自动抛出异常
当程序语句出现一些逻辑错误、主义错误或类型转换错误时,系统会自动抛出异常。如:
public static void main(String[] args) {
int a = 5, b = 0;
System.out.println(a / b);
}
系统会自动抛出ArithmeticException
异常:
throw
throw
是语句抛出一个异常。 语法:
throw (异常对象);
一般会用于程序出现某种逻辑错误时程序员主动抛出某种特定类型的异常。如:
public static void main(String[] args) {
String s = "abc";
if (s.equals("abc")) {
throw new NumberFormatException();
}
else {
System.out.println(s);
}
}
会抛出异常:
throws
throws
用在声明方法时,表示该方法可能要抛出异常。 语法:
[(修饰符)](返回值类型)(方法名)([参数列表])[throws(异常类)] {
...
}
例如:
public void function() throws Exception{......}
当某个方法可能会抛出某种异常时用于throws
声明可能抛出的异常,然后交给上层调用它的方法程序处理。如:
public static void function() throws NumberFormatException{
String s = "abc";
System.out.println(Double.parseDouble(s));
}
public static void main(String[] args) {
try {
function();
}
catch (NumberFormatException e) {
System.err.println("该字符串不包含可解析的double");
}
}
处理结果如下:
字符串不包含可解析的double
编程要求
本关的编程任务是补全右侧代码片段中Begin
至End
中间的代码,具体要求如下:
- 利用
throw
关键字声明输入可能出现的异常。 - 如果输入的
ID
格式正确,则输出ID格式正确:+ ID内容
;反之输出ID长度应为7
。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是测试样例:
测试输入:1234567
测试输出:ID格式正确:1234567
测试输入:vddft56657
测试输出:ID长度应为7
package step1;
import java.util.Scanner;
public class ThrowException {
public static void function(String id) { //利用throws关键字声明该方法可能出现异常IllegalArgumentException
/********** Begin *********/
if (id.length() == 7) {
//输出ID合法时的语句
System.out.println("ID格式正确:"+id);
}
else {
//利用throw关键字抛出异常IllegalArgumentException
System.out.println("ID长度应为7");
}
/********** End *********/
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
String id=sc.nextLine();
try {
function(id);
}
catch (IllegalArgumentException e) {
/********** Begin *********/
//输出ID不合法时的语句
System.out.println(e.getMessage());
/********** End *********/
}
}
}
第2关:异常的捕获与处理 - 文本统计
任务描述
本关的任务是通过异常捕获的方式,完成一个程序,实现输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数的功能。
相关知识
捕获并处理异常
使用try
和catch
关键字可以捕获异常。try/catch
代码块放在异常可能发生的地方。try/catch
代码块中的代码称为保护代码,使用try/catch
的语法如下:
try {
//接受监视的程序块,在此区域内发生的异常,由catch中指定的程序处理;
}
catch(要处理的异常种类和标识符) {
//处理异常;
}
catch
语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try
后面的catch
块就会被检查。如果发生的异常包含在catch
块中,异常会被传递到该catch
块,这和传递一个参数到方法是一样。
如果此程序块可能发生多个不同的异常,可以采取以下catch
嵌套语句用以捕获。
try {
//接受监视的程序块,在此区域内发生的异常,由catch中指定的程序处理;
}
catch(要处理的异常种类和标识符) {
//处理异常;
}
catch(要处理的异常种类和标识符) {
//处理异常;
}
如何判断指定字符是否为字母
isLetter(Char ch)
方法可以用于判断指定字符是否为字母。
参数ch
为字母,则返回 true
;否则返回 false
。
示例:
System.out.println(Cha\fracter.isLetter('c'));
System.out.println(Cha\fracter.isLetter('5'));
输出:
true
false
如何获取一个字符是否为空格字符
isSpaceChar(char ch)
方法可以用于判断指定字符是否为空格。
参数ch
为空格,则返回true
;否则返回false
示例:
char ch1 = ' ';
char ch2 = 'u2028';
System.out.println(Cha\fracter.isSpaceChar(ch1))
System.out.println(Cha\fracter.isSpaceChar(ch2))
输出:
true
false
如何判断一个字符是否为数字
使用isDigit(Char ch)
即可,使用方式和上述两个函数类似。
编程要求
本关的编程要求是补全右侧代码片段中Begin
至End
中间的代码,具体要求如下:
- 从命令行输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
- 输出格式参见测试样例。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是测试样例:
测试输入:abc123###
测试输出:letter=3,space=0,number=3,other=3
测试输入:777783 34 @ %( sds
测试输出:letter=3,space=4,number=8,other=3
package step2;
import java.io.*;
public class CatchException {
public static void main(String[] args) {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str;
/********** Begin *********/
//补全try/catch块,异常类型为IOException
try {
str = reader.readLine();
int letter = 0;
int space = 0;
int number = 0;
int other = 0;
for(int i = 0;i<str.length();i++)
{
if(Character.isLetter(str.charAt(i)))
{
letter++;
}
else if(Character.isSpaceChar(str.charAt(i)))
{
space++;
}
else if(Character.isDigit(str.charAt(i)))
{
number++;
}
else other ++;
}
System.out.println("letter="+letter+",space="+space+",number="+number+",other="+other);
}
catch(IOException e)
{
e.printStackTrace();
}
/********** End *********/
}
}
第3关:自定义异常 - 正负数
任务描述
本关的任务是通过用户自定义异常的机制,判断一个数是否合法,我们定义为若该数为正数,则合法;反之则不合法。
相关知识
自定义异常
在Java
中,除了由Java
系统监测到的异常(下标越界,被0除等),用户也可以自定义异常。
用户定义的异常同样要用try{} catch{}
捕获,但必须由用户自己抛出 throw new MyException
。
异常是一个类,用户定义的异常必须继承自Throwable
或Exception
类,建议用Exception
类。
语法结构如下所示:
class MyException extends Exception {
…
}
一般的,我们会这么定义一个异常:
class MyException extends Exception {
public MyException(String m) {
super(m);
}
}
上述代码中的构造方法MyException(String m)
中通过super()
调用了父类的构造方法,效果是输出以下结果:
MyException: 字符串m中的内容
在程序中,其抛出异常的语法为:
throw new MyException(""); //""为字符串m中的内容,由用户自定义
编程要求
本关的编程要求是补全右侧代码片段中Begin
至End
中间的代码,具体要求如下:
num
变量为命令行输入的int
型数据,若num
为正数,输出The number you entered is:
+num
;反之捕获该异常。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是测试样例:
样例输入:-60
样例输出:chapter8.step3.MyException: Number cannot be negative!
样例输入:60
样例输出:The number you entered is: 60
package step3;
import java.util.Scanner;
class MyException extends Exception {
public MyException(String m) {
super(m);
}
}
public class MyExceptionTest {
public static void main(String[] args) {
try {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
/********** Begin *********/
if(num<0){
throw new MyException("Number cannot be negative!");
}
else if(num>0){
System.out.println("The number you entered is: "+num);
}
/********** End *********/
}
catch(MyException e) {
System.out.print(e);
}
}
}