黑马程序员————面向对象5(day9)

----------------------ASP.Net+Android+IOS开发----------------------期待与您交流!

 

 

 

面向对象5

l  内部类访问规则

l  匿名内部类

l  异常

l  异常try – catch

l  异常声明throws

l  多异常处理

l  自定义异常

l  Throwthrows的区别

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这个体系中独有特点,只有这个体系中的类和对象才可以被throwsthorw操作。

 

 

Throwthrows的区别

Throwsthrow的区别:

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值