(1) 常见异常的捕获
(1) 编写一个程序,分别生成ArrayIndexOutOfBoundsException类型和ArithmeticException类型的异常。
(2) 改写程序,对ArrayIndexOutOfBoundsException和ArithmeticException类型异常进行捕获。
生成ArrayIndexOutOfBoundsException类型异常:
public class Exception {
public static void main (String args[])
{
int i=0;
int a[] = {5,6,7,8};
for(i=0;i<5;i++)
{System.out.print("a["+i+"]/"+i+"="+(a[i]));}
}
}
生成ArithmeticException类型的异常:
public class Exception {
public static void main (String args[])
{
int i=0;
int a[] = {5,6,7,8};
for(i=0;i<5;i++)
{System.out.print("a["+i+"]/"+i+"="+(a[i]/i));}
}
}
对ArrayIndexOutOfBoundsException和ArithmeticException类型异常进行捕获:
public class Try
{
public static void main (String args[])
{
int i=0;
int a[] = {5,6,7,8};
for(i=0;i<5;i++)
{
try
{System.out.print("a["+i+"]/"+i+"="+(a[i]/i));}
catch(ArrayIndexOutOfBoundsException e)
{System.out.print("捕获数组下标越界异常!");}
catch(ArithmeticException e)
{System.out.print("捕获算术异常!");}
finally
{ System.out.println(" i="+i);}
}
System.out.println("继续!");
}
}
思考:能否同时抛出ArrayIndexOutOfBoundsException类型和ArithmeticException类型的异常?为什么?
不能同时抛出,一次只能抛出一个异常,若同时抛出几个异常,相当于一个语句执行后有几个返回值,这是不正确的。
(2) 异常处理实验
在第二章Java语言基础实验中,我们曾经做过如下程序:
从输入对话框读入double型的华氏度,将其转换为摄氏度,并在消息框中显示结果。转换
如下: 摄氏度=(5/9)*(华氏度-32)对话框使用JOptionPane类。
(1) 编写实现上述功能的Java程序。(可参照以前的代码)
(2) 当弹出输入框的时候,输入123,看看输出结果?
(3) 当弹出输入框的时候,输入abc,看看输出结果有什么变化?
给上述程序增加异常捕获处理功能,当用户输入错误数据时候,提示用户输入错误,并要求用户重新输入内容
import javax.swing.JOptionPane;
public class Temperature {
/**
* @param args
*/
public static void main(String[] args) {
String inStr=JOptionPane.showInputDialog("请输入华氏度:");
double Huashi=Integer.parseInt(inStr);
double Sheshi=(5.0/9)*(Huashi-32);
System.out.println(Sheshi);
}
}
输入abc的输出结果:
修改后的程序:
import javax.swing.JOptionPane;
public class Temperature
{
static double Huashi;
public static void main(String[] args)
{
T();
double Sheshi=(5.0/9)*(Huashi-32);
System.out.println(Sheshi);
}
public static void T()
{
String inStr=JOptionPane.showInputDialog("请输入华氏度:");
try
{ Huashi=Integer.parseInt(inStr);}
catch(NumberFormatException e)
{JOptionPane.showMessageDialog(null, "输入错误,请重新输入");
T(); //递归调用
}
finally
{}
}
}
如果一直输入错误的话就会一直弹出提示框,直至输入正确的数值为止。
(三)自定义异常的定义、拋出和捕获试验
(1)自定义两个异常类非法姓名异常IllegaNameException和非法地址异常IllegalAddressException。
(2)定义Student类包含Name和Address属性,和setName、setAddress方法,当姓名长度小于1或者大于5抛出IllegaNameExceptio,当地址中不含有”省”或者“市”关键字抛出IllegalAddressException。
(3)在main方法中进行捕获试验。
1.定义异常:
public class IllegaNameException extends Exception
{
public IllegaNameException(String s)
{super(s);}
public IllegaNameException()
{this("");}
}
public class IllegalAddressException extends Exception{
public IllegalAddressException(String s)
{super(s);}
public IllegalAddressException()
{this("");}
}
2.测试IllegaNameException
public class Student {
public String Name;
public String Address;
public Student(String Name,String Address)throws IllegalAddressException, IllegaNameException
{
this.setName(Name);
this.setAddress(Address);
}
public void setName(String Name) throws IllegaNameException{
// TODO Auto-generated method stub
if(Name.length()>=1&&Name.length()<=5)this.Name=Name;
else
throw new IllegaNameException(""+Name);
}
public void setAddress(String Address) throws IllegalAddressException{
// TODO Auto-generated method stub
if(Address.contains("省")||Address.contains("市"))this.Address=Address;
else
throw new IllegalAddressException(""+Address);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Student S1=null;
try
{
S1=new Student("孙小鹏","山东省");
S1.setName("我叫做孙小鹏");
S1.setAddress("山东");
}
catch(IllegaNameException e)
{
System.out.println("捕获非法姓名异常");
e.printStackTrace();
}
catch (IllegalAddressException e) {
// TODO Auto-generated catch block
System.out.println("捕获非法地址异常");
e.printStackTrace();
}
finally
{
System.out.println(S1.Name+S1.Address);
}
}
}
测试IllegalAddressException
public class Student {
public String Name;
public String Address;
public Student(String Name,String Address)throws IllegalAddressException, IllegaNameException
{
this.setName(Name);
this.setAddress(Address);
}
public void setName(String Name) throws IllegaNameException{
// TODO Auto-generated method stub
if(Name.length()>=1&&Name.length()<=5)this.Name=Name;
else
throw new IllegaNameException(""+Name);
}
public void setAddress(String Address) throws IllegalAddressException{
// TODO Auto-generated method stub
if(Address.contains("省")||Address.contains("市"))this.Address=Address;
else
throw new IllegalAddressException(""+Address);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Student S1=null;
try
{
S1=new Student("孙小鹏","山东省");
S1.setAddress("山东");
S1.setName("我叫做孙小鹏");
}
catch(IllegaNameException e)
{
System.out.println("捕获非法姓名异常");
e.printStackTrace();
}
catch (IllegalAddressException e) {
// TODO Auto-generated catch block
System.out.println("捕获非法地址异常");
e.printStackTrace();
}
finally
{
System.out.println(S1.Name+S1.Address);
}
}
}
在测试两次异常时,只是将try语句中setName和setAddress顺序调换,便可单独测试两个异常,因其无法同时执行两个catch语句。
3.回答下述问
(1) 什么是异常?如何处理除数为0和数组下标异常?
异常是指在硬件和操作系统正常时,程序遇到的运行错。
对于整数除法中除数为0的语义错,在运行时能够发现该错误,抛出算术异常ArithmeticException,程序终止运行;
对于浮点数除法中除数为0的语义错,在运行时不能发现该错误,也不抛出异常,给出的结果为无穷大,程序继续运行。
数组下标异常时,会抛出数组下标越界异常ArrayIndexOutOfBoundsException,同时终止程序运行。
(2) 字符串转换数值类型会抛出什么异常?
会产生NumberFormat_Exception异常。
(3) 如何自定义异常?简要说明其步骤。
自定义的异常属于Exception的子类,只需要声明构造方法:
public class 异常类名 extends Exception
{
public异常类名(String s)
{super(s);}
public异常类名()
{this("");}
}
在主程序类中多个方法声明抛出自定义的异常类。