----------------------ASP.Net+Android+IOS开发----------------------期待与您交流!
面向对象5
l 内部类访问规则
l 匿名内部类
l 异常
l 异常try – catch
l 异常声明throws
l 多异常处理
l 自定义异常
l Throw和throws的区别
l RuntimeException
内部类访问规则
现在已经知道,在类内部可以定义成员变量与方法,有趣的是,在类内部也可以定义另一个类。如果在类Outer的内部再定义一个类Inner,此时类Inner就称为内部类,而类Outer则称为外部类。
例:
class Outer{
private int x = 1;
//定义内部类
class Inner{
int x = 2;
void function(){
int x = 3;
//打印外部类x的值
System.out.println("inner:" + Outer.this.x);
}
}
void method(){
Inner in = new Inner();
in.function();
}
}
class InnerDemo{
public static void main(String[] args){
Outer out = new Outer();
out.method();
}
}
内部类的访问规则:
1. 内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式:外部类名.this
2. 外部类要访问内部类,必须建立内部类对象。
访问格式:
1. 当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。可以直建立内部类对象。
格式:外部类名.内部类名变量名 = new外部类对象().new 内部类对象();
Outer.Inner in = new Outer().new Inner();
2. 当内部类在成员位置上,就可以被成员修饰符所修饰。比如,private:就将内部类在外部类中进行封装。Static:内部类就具备static特性。
当内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。
在外部类其它类中,如何直接访问static内部类的非静态成员呢?
New Outer.Inner().function();
在外部类其它类中,如何直接访问static内部类的静态成员呢?
Outer.Inner.function()
注意:当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类时,内部类也必须是static的。
内部类定义在局部时:
1. 不可以被成员修饰符修饰。
2. 可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问它所在的局部中的变量,只能访问被 final修饰的局部变量。
匿名内部类
匿名内部类:
1. 匿名内部类其实就是内部类的简写格式。
2. 定义匿名内部类的前提:内部类必须是继承一个类或者实现接口。
3. 匿名内部类的格式:new父类或者接口(){定义子类的内容}
4. 其实匿名内部类就是一个匿名子类对象,而且这个对象有点胖,可以理解为带内容的对象。
5. 匿名内部类中定义的方法最好不要超过3个。
例1:
abstract class AbsDemo{
abstract void show();
}
class Outer{
int x = 1;
public void function(){
//匿名内部类
new AbsDemo(){
void show(){
System.out.println("x=" + x);;
}
}.show();
}
}
class InnerDemo{
public static void main(String[] args){
new Outer().function();
}
}
例2:
interface Inter{
void method();
}
class Test{
static Inter function(){
return new Inter(){
public void method(){
System.out.println("method run");
}
};
}
}
class InnerTest{
public static void main(String[] args){
/*
Test.function():Test类中有一个静态的方法function()
.method():function()这个方法运算后的结果是一个对象,而且是一个Inter类型的对象
因为只有是Inter类型的对象,才可以调用method()方法
*/
Test.function().method();
}
}
异常
即使在编译时没有错误信息产生,但在程序运行时,经常会出现一些运行时的错误,这种错误对Java而言是一种异常。有了异常就要有相应的处理方式。
异常:就是程序在运行时出现不正常情况。
异常由来:问题也是现实生活中一个具体的事物,也可以通过Java的类的形式进行描述,并封装成对象。其实就是Java对不正常情况进行描述后的对象体现。
对于问题的划分,两种:一种是严重的问题,一种是非严重的问题。
对于严重的,Java通过Error类进行描述。
对于Error一般不编写针对性的代码对其进行处理。
对于非严重的,Java通过Exception类进行描述。
对于Exception可以使用针对性的处理方式进行处理。
无论Error或者Exception都具有一些共性内容,比如:不正常情况的信息,引发原因等。
异常也称为例外,是在程序运行时过程中发生的、会打断程序正常执行的时间。下面是集中常见的异常:
1. 算数异常:ArithmeticException
2. 没有给对象开辟内存空间会出现空指针异常:NullPointerException
3. 找不到文件异常:FileNotFoundException
所以在程序设计时,必须考虑到可能发生的异常事件,并作出相应的处理,这样才能保证程序可以正常运行。
为何需要异常处理?
异常是在程序运行过程中发生的时间,比如除0溢出、数组越界、文件找不到等,这些时间的发生将组织程序的正常运行。为了加强程序的健壮性,在程序设计时,必须考虑到可能发生的异常时间,并作出相应的处理。
Java通过面向对象的方法来处理异常。在一个方法的运行过程中,如果发生了异常,则这个方法生成代表该异常的一个对象,并把它交给运行时系统,运行时系统寻找相应的代码来处理这一异常。我们把生成异常对象并把它提交给运行时系统的过程称为抛出(throw)一个异常。运行时系统在方法的调用栈中查找,从生成异常的方法开始进行,直到找到包含上相应异常处理的方法位置,这一个过程称为捕获(catch)一个异常。
异常try – catch
异常的处理:Java提供了特有的语句进行处理。
格式:try{
需要被检测的代码
}catch(异常类变量){
处理异常的代码:(处理方式)
}finally{
一定会执行的语句
}
对捕获到的异常对象进行常见的方法操作:String getMessage();获取异常信息
例:
class Demo{
int div(int a, int b){
return a/b;
}
}
class ExceptionDemo{
public static void main(String[] args){
Demo d = new Demo();
try {
int x = d.div(1, 0);
System.out.println(x);
} catch (Exception e) {
System.out.println("除零啦");
System.out.println(e.getMessage());//by zero
System.out.println(e.toString());// 异常名称,异常信息
e.printStackTrace();//异常名称,异常信息,异常出现的位置
//其实Jvm默认的异常处理机制,就是在调用printStackTrace()方法,打印异常的堆栈的跟踪信息
}
System.out.println("over");
}
}
异常声明throws
例:
class Demo{
int div(int a, int b)throws Exception{//在功能上通过thorws的关键字声明了该功能有可能会出现问题
return a/b;
}
}
class ExceptionDemo{
public static void main(String[] args){
Demo d = new Demo();
try {
int x = d.div(1, 0);
System.out.println(x);
} catch (Exception e) {
System.out.println("除零啦");
System.out.println(e.getMessage());//by zero
System.out.println(e.toString());// 异常名称,异常信息
e.printStackTrace();//异常名称,异常信息,异常出现的位置
//其实Jvm默认的异常处理机制,就是在调用printStackTrace()方法,打印异常的堆栈的跟踪信息
}
System.out.println("over");
}
}
多异常处理
对多异常的处理:
1. 声明异常时,建议声明更为具体的异常,这样处理的可以更具体。
2. 对方声明几个异常,就对应有几个catch()块,不要定义多余的catch()块。如果多个catch()中的异常出现继承关系,父类异常catch()块放在最先面。
建议在进行catch()处理时,catch()中一定要定义具体处理方式。不要简单定义一句:e.printStackTrace()也不要简单的就书写一条输入语句。
例:
class Demo{
int div(int a, int b)throws ArithmeticException, ArrayIndexOutOfBoundsException{//把异常描述的更具体些,这里是有可能发生算数异常和数组角标越界异常,所以可以同时声明另个异常
int[] arr = new int[a];
System.out.println(arr[5]);
return a/b;
}
}
class ExceptionDemo{
public static void main(String[] args){
Demo d = new Demo();
try {
int x = d.div(5, 0);
System.out.println(x);
} catch (ArithmeticException e) {
System.out.println(e.toString());// 异常名称,异常信息
System.out.println("除零啦");
}catch(ArrayIndexOutOfBoundsException e){
System.out.println(e.toString());//异常名称,异常信息
System.out.println("数组角标越界");
}
System.out.println("over");
}
}
当出现异常时,程序就会抛出异常,并且停止程序。
自定义异常
因为项目中会出现特有的问题,而这些问题并未被Java所描述并封装对象,所以对于这些特有的问题可以按照Java的对问题封装的思想。将特有的问题,进行自定义的异常封装。
为了处理各种异常,Java可通过继承的方式编写自己的异常类。因为所有可处理的而异常类均继承Exception类,所以自定义异常类也必须继承这个类。
需求:在本程序中,对于除数是-1,也视为是错误的是无法进行运算的,那么久需要对这个问题进行自定义的描述。
当在函数内部出现了thorw抛出异常对象,那么久必须要给对应的处理动作。要么在内部try catch()处理,要么在函数上声明让调用者处理。一般情况下,函数内出现异常,函数上需要声明。
例:
class FuShuException extends Exception{
}
class Demo01{
int div(int a, int b)throws FuShuException{
if(b<0)
throw new FuShuException();//手动通过 throw关键字抛出一个自定义异常对象
return a/b;
}
}
class ZiDingYiException{
public static void main(String[] args){
Demo01 d = new Demo01();
try {
int x = d.div(4, -1);
System.out.println(x);
} catch (FuShuException e) {
System.out.println(e.toString());
System.out.println("除数出现负数");
}
System.out.println("over");
}
}
运行结果:day09.MianXiangDuiXiang.FuShuException
除数出现负数
Over
发现打印的结果中只有异常的名称,却没有异常的信息,因为自定义的异常并未定义信息。
如何自定义异常信息呢?
因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时,将异常信息传递给父类通过super语句,那么久可以直接通过getMessage()方法获取自定义的异常信息。
例:
class FuShuException extends Exception{
private int value;
FuShuException(String msg, int value){
super(msg);
this.value = value;
}
public int getValue(){
return value;
}
}
class Demo01{
int div(int a, int b)throws FuShuException{
if(b<0)
throw new FuShuException("出现了除数是负数的情况",b);//手动通过 throw关键字抛出一个自定义异常对象
return a/b;
}
}
class ZiDingYiException{
public static void main(String[] args){
Demo01 d = new Demo01();
try {
int x = d.div(4, -1);
System.out.println(x);
} catch (FuShuException e) {
System.out.println(e.toString());
System.out.println("错误的负数是: " + e.getValue());
}
System.out.println("over");
}
}
运行结果:day09.MianXiangDuiXiang.FuShuException:出现了除数是负数的情况
错误的负数是: -1
over
自定义异常:
必须是定义类继承Exception
继承Exception原因:异常体系有一个特点:因为异常类和异常对象都被抛出。他们都具备可抛性,这个可抛性是Throwable这个体系中独有特点,只有这个体系中的类和对象才可以被throws和thorw操作。
Throw和throws的区别
Throws和throw的区别:
1. thorws使用在函数上。
throw使用在函数内。
2. thorws后面跟的异常类,可以跟多个,用逗号隔开。
throw后跟的是异常对象。
RuntimeException
Exception中有一个特殊的子类异常RuntimeException运行时异常。如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。
例:
class Demo02{
int div(int a, int b)throws ArithmeticException{
return a/b;
}
}
class RuntimeExceptionDemo {
public static void main(String[] args){
Demo02 d = new Demo02();
int x = d.div(1, 0);
System.out.println(x);
System.out.println("over");
}
}
上段程序编译通过。
之所以不用再函数声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。
自定义异常时:如果该异常的发生,无法在继续进行运算,就让自定义异常继承RuntimeException。
例:
class FuShuException extends RuntimeException{
FuShuException(String msg){
super(msg);
}
}
class Demo02{
int div(int a, int b){//throws ArithmeticException{
if(b<0)
throw new FuShuException("出现了除数为负数了 ");
if(b==0)
throw new ArithmeticException("出零啦");
return a/b;
}
}
class RuntimeExceptionDemo {
public static void main(String[] args){
Demo02 d = new Demo02();
int x = d.div(1, -1);
System.out.println(x);
System.out.println("over");
}
}
对于异常分为两种:
1. 编译时被检测的异常。
2. 编译时不被检测的异常(运行时异常。RuntimeException以及其子类)。
----------------------ASP.Net+Android+IOS开发----------------------期待与您交流!
详情请查看:http://edu.csdn.net