//91-面向对象-异常-异常的发生和简单应用。
/*
异常:
java运行时期发生的问题就是异常。 Java中运行时的除了异常Exception含有错误Error. 异常:通常发生后可以有针对性的处理方式的。
错误:通常发生后不会有针对性的处理方式。
Error的发生往往都是系统级别的问题,都是jvm所在系统发生的并反馈给jvm
无法修正处理,只能修改源代码。
*/ class ExceptionDemo
{
public static void main(String[] args)
{
int[] arr = new int[1024*1024*1000];//Exception in thread "main" java.lang.OutOfMemoryError:
System.out.println(arr[0]);
System.out.println(arr[3]);//改句运行时,发生了异常Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
//导致程序无法执行,程序结束。
System.out.println("over");
}
}
//92-面向对象-异常-异常的发生和简单应用。
class Person
{
private String name;
private int age;
Person(String name,int age)
{
//加入逻辑判断。
if(age<0 || age>200)
{
/*
这样做虽然可以编译运行看到提示消息,但是问题却没有发生,
程序还在继续执行,并打印了p对象,这是不合理的,人对象初始化过程
中已经出了问题,为什么还要对人对象进行操作。
所以应该将问题暴露出来,让使用改程序的调用者知道,
所以要用异常来解决。
*/
// System.out.println("年龄数值错误");
// return;//终止初始化。
throw new IllegalArgumentException(age+",年龄数值非法");
}
this.name = name;
this.age = age;
}
//定义Perosn对象对应的字符串表现形式,覆盖Object中的toString方法,
public String toString()
{
return "Person[name="+name+",age="+age+"]";
}
} class ExceptionDemo2
{
public static void main(String[] args)
{
Person p = new Person("XiaoMing",-20);
System.out.println(p); }
}
//93-异常的定义&体系。
/*
ExceptionDemo2.java中的异常不好认,能不能定义一个符合我的程序要求的问题。 异常的信息都可以自己定义,那么异常的名字是否可以自己定义呢?是否可以更
符合自己程序的阅读呢? 之前的几个异常都是java通过类进行描述,并将问题封装成对象,这是符合面向对象的
思想的。
其实:异常就是讲问题封装成了对象。 所以我也准备对自己所需要的问题进行类的描述。 发生了编译失败:
ExceptionDemo3.java:43: 错误: 不兼容的类型: NoAgeException无法转换为Throwable
throw new NoAgeException(age+",年龄数值非法");
^
1 个错误 不兼容,不明白,查阅API文档,提示说无法转换为Throwable,啥东西?
搜索API,看到Throwable描述,发现,它是异常和错误的超类。
原来它是异常体系的顶层类。
Throwable
|--Error
|--Excepton. 通过阅读,自定义异常被抛出,必须是继承Throwable,或者继承Throwable的子类
该对象才可以被throw抛出。 原来这个异常体系局部一个特有的特性,可抛性,可以被throw关键字操作。 继承选择父类时,更为确切的是继承Exception。
但是发现编译又异常失败了。 ExceptionDemo3.java:61: 错误: 未报告的异常错误NoAgeException; 必须对其进行捕获或声明 以便抛出
throw new NoAgeException(age+",年龄数值非法");
^
1 个错误 通过这个编译失败提示,发现自定义的异常和之前所使用的异常(空指针异常,
角标越界异常,无效参数异常有不同。)
抛出那些异常没有这个失败提示,那么之前的异常和自定义的异常有什么区别呢?
通过查看API文档的继承体系发现,之前的异常都是Exception下面的RuntimeException子类
的子类。
阅读RuntimeException描述中有明确说明,这个运行时异常以及其子类都无需进行声明。 可以将自定义的异常继承RuntimeException。 */ //自定义异常。描述Person的年龄数值非法。
/**
只要是本项目中的Person的年龄出现非法值,就会发生该异常。
*/
class NoAgeException extends RuntimeException
{
/*
为什么要定义构造函数,因为看到java中的异常描述类中有提供对问题的构造方法。
*/
NoAgeException()
{
super();
} NoAgeException(String message)
{
super(message);//如果自定义异常需要异常信息,可以通过调用父类带有
//字符串参数的构造函数即可。
}
} class Person
{
private String name;
private int age;
Person(String name,int age)
{
//加入逻辑判断。
if(age<0 || age>200)
{
throw new NoAgeException(age+",年龄数值非法");
}
this.name = name;
this.age = age;
}
//定义Perosn对象对应的字符串表现形式,覆盖Object中的toString方法,
public String toString()
{
return "Person[name="+name+",age="+age+"]";
}
} class ExceptionDemo3
{
public static void main(String[] args)
{
Person p = new Person("XiaoMing",-20);
System.out.println(p); }
}
//94-编译时异常和运行时异常
/*
ExceptionDemo3.java中涉及的问题。
1,继承Exception和继承RuntimeException为什么差距那么大?
2,啥是捕获,啥事声明?
*/ class Demo
{
void show()
{
//如果在函数内抛出Exception//编译失败,因为编译器在检查语法时发生了错误。
/*
该抽象已经出现问题,java认为这个程序本身存在隐患,需要捕获或者声明出来。
(要么捕获,要么声明出来,让调用者知道。)
*/
// throw new Exception(); /*
为什么抛出RuntimeException就不需要捕获,不需要声明呢?
不是功能本身发生的异常,而是因为比如调用者传递参数错误
而导致功能运行失败。
这时也是问题,需要通过异常来体现,但是这个异常时不需要声明
出来的。
声明的目的是为了让调用者进行处理。
不声明的目的是不让调用者进行处理。就是为了让程序停止,让调用
者看到现象,并进行代码的修正。☆☆☆☆☆ 异常分两种
1.编译时异常。编译器会检测。
2.运行时异常。编译器不会检测,不需要声明。声明也可以,如果声明了
无外乎,就是让调用者给出处理方式。
常见的异常;
ArrayIndexOutOfBoundsEception
IllegalArgumentException
NullPointerException
ClassCastException */
throw new RuntimeException();
}
}
class ExceptionDemo4
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
//95-异常-声明&捕获
/*
声明和捕获:
声明:将问题标识出来,报告给调用者。
如果函数内,通过throw抛出了编译时异常,而没有捕获,
那么必须通过throws进行声明,让调用者去处理。 捕获:java中对异常有针对性的语句进行捕获。
语句:
try
{
//需要被检测的代码或者语句。
}
catch(异常类 变量)//参数。
{
//异常的处理语句。
}
finally
{
//一定会被执行的语句。
} */
class Demo
{
/*
如果定义功能时,有问题发生,需要报告给调用者,可以在函数
上使用throws进行声明。
*/
void show(int x)throws Exception
{
if(x>0)
throw new Exception();
else
System.out.println("show run");
}
} class ExceptionDemo5
{
public static void main(String[] args)//throws Exception//在调用者上继续声明
{
Demo d = new Demo();
try
{
d.show(2);//当调用了声明异常的方法时,必须有处理方式,要么捕获,要么声明。
}
catch (Exception ex)//括号中,需要定义什么呢?对方抛出的是什么问题,在括号中就定义什么问题的引用。
{
System.out.println("异常发生了");
} System.out.println("Hello World!");
}
}
//96-声明&捕获在例子中的应用。 class NoAgeException extends RuntimeException
{
/*
为什么要定义构造函数,因为看到java中的异常描述类中有提供对问题的构造方法。
*/
NoAgeException()
{
super();
} NoAgeException(String message)
{
super(message);//如果自定义异常需要异常信息,可以通过调用父类带有
//字符串参数的构造函数即可。
}
} class Person
{
private String name;
private int age; /*
构造函数到底抛出的NogAgeException是继承Exception呢?还是继承
RuntimeException呢?
继承Exception就必须要throws声明,一旦声明就告知调用者要进行捕获,
一旦问题处理完了,调用者的程序会继续执行,但是,如果使用到了Person
对象的数据,会导致代码都是失败的。
如果继承RuntimeException是不需要throws声明的,那么这时,调用者是不可
能编写捕获代码的,因为调用者根本不知道有问题。
一旦发生NoAgeExcepton,调用者程序会停掉,并由jvm将信息显示到屏幕上。
让调用者看到,然后调用者去修改源代码。
*/
Person(String name,int age)//throws NoAgeException
{
//加入逻辑判断。
if(age<0 || age>200)
{
throw new NoAgeException(age+",年龄数值非法");
}
this.name = name;
this.age = age;
}
//定义Perosn对象对应的字符串表现形式,覆盖Object中的toString方法,
public String toString()
{
return "Person[name="+name+",age="+age+"]";
}
} class ExceptionDemo6
{
public static void main(String[] args)
{
// try
// {
Person p = new Person("XiaoMing",20);
System.out.println(p);
// }
// catch (NoAgeException ex)
// {
// System.out.println("异常发生了");
// } System.out.println("over"); }
}
//97-运行时异常的应用。
/*
描述长方形:
属性:长和宽。
行为:获取面积。 考虑健壮性问题:
万一长和宽数值非法。
描述问题:将问题封装成对象,用异常的方式来表示。
*/ /*
不知道要继承编译时异常还是运行时异常。
*/ class NoValueException extends RuntimeException
{
NoValueException()
{
super();
}
NoValueException(String message)
{
super(message);
}
}
class Rec
{
private int length;
private int width;
Rec(int length,int width)
{
if(length<=0 || width<=0)
{
//抛出异常,但是不用声明,不需要调用者处理,就需要一旦问题日发生,让调用者端进行停止,修改代码去。
throw new NoValueException("长或者宽的数值非法,请修正。");
}
this.length = length;
this.width = width;
}
/**
定义面积函数。
*/
public int getArea()
{
return length*width;
}
}
class ExceptionDemo7
{
public static void main(String[] args)
{
Rec r = new Rec(-3,4);
int area = r.getArea();
System.out.println("area="+area); }
}
//98-99--编译时异常和异常的转换
/*
案例二:毕老师用电脑讲课。
两个对象:
老师:
属性:姓名。
行为:讲课。
电脑:
行为:运行。 考虑问题:
1.电脑蓝屏--->异常 2.电脑冒烟了-->异常
*/
//可以声明出来,让调用者给出处理方式。
class LanPingException extends Exception
{
LanPingException()
{
super();
}
LanPingException(String message)
{
super(message);
}
} class MaoYanException extends Exception
{
MaoYanException()
{
super();
}
MaoYanException(String message)
{
super(message);
}
}
/*
讲课中冒烟,问题可以临时解决,但是冒烟问题没有直接处理,所以就使用throws声明。
但是发现,这个问题不应该属于讲课的问题,调用讲课方法的调用者处理不了这个问题,
该调用者能处理的应该是冒烟导致的课程进行不下去的问题。
应该在列出一个异常,课时停止异常。
*/ class NoPlanException extends Exception
{
NoPlanException()
{
super();
}
NoPlanException(String message)
{
super(message);
}
} class NoteBook
{
private int state=2;
public void run()throws LanPingException,MaoYanException
{
System.out.println("笔记本电脑运行");
if(state == 1)
throw new LanPingException("电脑蓝屏了");
if(state == 2)
throw new MaoYanException("电脑冒烟了"); }
public void reset()
{
state = 0;
System.out.println("电脑重启");
}
} class Teacher
{
private String name;
private NoteBook book;
Teacher(String name)
{
this.name = name;
book = new NoteBook();
} //讲课:
public void prelect()throws NoPlanException
{
/*
调用到了声明异常的方法,在这里到底是捕获好呢?还是声明好呢?
有具体的捕获处理方法吗?有,那就捕获,没有,那就声明。
我可以处理,重启电脑就可以了,重启是电脑的功能。
*/
try
{
book.run();//对于声明多个异常的方法,在处理,需要定义多个catch与之对应。
}
catch (LanPingException e)//LanPingException e = new LnaPingException("电脑蓝屏了")
{
//重启;
System.out.println(e.toString());
e.printStackTrace();
book.reset();
}
catch(MaoYanException e)//MaoYanException e = MaoYanException("电脑冒烟了");
{
System.out.println(e.toString());
test();
//冒烟问题没有解决。继续声明throws出去。
// throw e;
throw new NoPlanException(e.getMessage()+",课时停止");//异常转换。 }
System.out.println("讲课");
}
//留练习题
public void test()
{
System.out.println("做练习");
}
} class ExceptionDemo8
{
public static void main(String[] args)
{
Teacher t = new Teacher("毕老师");
try
{
t.prelect();
}
catch (NoPlanException e)
{
System.out.println(e.toString());
System.out.println("换老师");
}
System.out.println("Hello World!");
}
}
//100-throw和throws的区别。
/*
throw和throws的区别: 1,throw用在函数内,
throws用在函数上。
2,throw抛出的是异常对象。
throws用于进行异常类的声明,后面异常类用逗号隔开。
*/
class Demo
{
void show()throw Exception
{
throw new Exception();
}
}
class
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}