`
wtt2312
  • 浏览: 14847 次
  • 性别: Icon_minigender_2
最近访客 更多访客>>
社区版块
存档分类
最新评论

黑马程序员----面向对象---异常

 
阅读更多
[size=small]

-------http://www.itheima.comjava培训、android培训期待与您交流!-------


继续学习面向对象,,,,,

八、异常

1、概述
异常就是程序在运行时出现的不正常情况。
在现实生活中,我们也会遇到很多不正常情况。其中有的是可以解决的,有的则没有解决必要。比如,电脑的运行速度慢,我们可以清理清理电脑灰尘或对电脑进行垃圾清理。但是,要是,某天不小心将电脑摔地上了,如果幸运,可以修修,如果不幸运,那么,对不起,就不用修了。
而在java语言中,也有对问题的描述。因为问题也可以归结为一类事物,那么,就可以通过java类的形式对问题进行描述,并封装成对象,也就是说,异常时java对不正常情况进行描述后的对象体现。
问题分为两种:严重的问题:Error  一般不编写针对性的代码对其进行处理
                     非严重的问题:Exception  可以针对性处理
而对于这些问题,Error或Exception,都有一些共性内容,如,不正常情况的信息,引发原因等。所以,将这些共性内容向上抽取就形成了一个体系:
可抛的:Throwable:Error/Exception

2、异常的处理
(1)使用 try - catch - finally  语句进行异常处理
        try {  需要被检测的代码  }catch( 异常类 变量 ){ 处理异常的代码(处理方式) }finally{ 一定 会被执行的语句 }

下面用一个例子解释:
首先定义一个简单的算数运算,求两个数的商(不考虑小数)。我们知道,在进行除法运算时,除数不能为0。所以,我们要遵循这个规则。如果出现了除数为0 ,则报异常,否则程序继续运行。
//定义一个类,用于封装除法运算
class Div
{
        //定义一个方法,用于计算两个数的商
int div(int x,int y)
{
return x/y;
}
}
class  ExceptionDemo
{
public static void main(String[] args)
{
Div d=new Div();
try
{
int x=d.div(4,0);
System.out.println("x="+x);
}
catch (Exception e)//Exception e=new ArithmeticException();
                                           //父类引用指向子类对象   多态的运用
{
System.out.println("除零了,不符合规则");
System.out.println(e.getMessage());//获取异常的信息
e.printStackTrace();//打印异常的堆栈的跟踪信息
}
System.out.println("over");
}
}

分析一下处理异常的流程:
Div d=new Div();在内存中创建对象
int x=d.div(4,0);调用div方法,这时,将4 0传给x、 y,由于除数为0,不符合规则,虚拟机检测到异常(java语言自定义的异常),那么就会出现ArithmeticException,出现了异常,下面的程序就不会执行,将异常转加给catch语句,让他对算法异常进行处理。Exception e=new ArithmeticException();     父类引用指向子类对象   多态的运用
然后,将处理的结果打印出来,这时,异常处理结束。接下来运行异常处理语句外的程序:
System.out.println("over");
                                    
(2)将异常声明(在函数体上声明异常),也就是抛出异常(throws)
还是上面那个例子。我们知道,x和y的值是用户输入的值,那么,传入的值就不明确。如果传入的是符合规则的,程序就不会有什么问题,但如果传入的是不合规则的,程序就会停掉。这是我们不希望的。
所以,我们在方法上将可能出现的问题通过关键字throws标识一下,这时编译时会出现错误信息:必须将异常捕获或声明。
一种方式是:在主函数上将异常抛出(这时是将异常抛给了JVM)
      int div(int x,int y)   throws Exception
一种方式是:在调用方法处捕获异常。
      try - catch
声明异常便于极高安全性,让调用者进行处理,不处理则会失败

(3)多异常处理
    显然,上面的例子只出现了一个异常。但在实际的开发过程中会出现很多异常。所以,要对多个异常进行处理。
A、也就是在函数上声明多个可能出现的异常(一般不同异常类用逗号","隔开),这     样会更具体地处理异常。
如,throws ArithmeticException ,ArrayIndexOutOfBoundException
    那么在处理异常时或捕获或声明异常。
B、在函数上声明几个,那么就要有几个catch块,且声明的和处理的要一致。
   要注意:若多个catch中出现继承关系,父类的异常catch要放在最下面(若放在最上面,出现的异常 父类会处理完,一下的catch块就不会执行,且报错)。
C、若捕获异常,则每个catch语句中要传入具体的异常类(函数上声明什么异常,
     catch中就要处理什么异常),且处理的方法要具体,
     不能输出默认的e.printStackTrace信息,也不能简单地打印自定义的异常信息。
D、当然,在实际开发中不会将出现的异常信息打印出来,这时会用文件记录每个异常发生的时间,情况等信息,存放在异常日志中。

(4)自定义异常
虽然java语言自定义了很多异常类,但是,在实际开发中我们还是会遇到很多意想不到的异常。这时,就需要我们定义属于我们自己的异常处理方式。
还是上面那个例子:java异常体系中只对除数为0的情况定义了异常。但如果除数为负数,这个运算方法也会出错。为了解决这个问题,就要自定义一个异常类,用于封装新出现的异常问题。
class FuShuException  extends Exception
{
   //函数一初始化就会有信息
   FuShuException(String message){
      //因为父类中已经定义了显示异常信息的方法,所以我们可以直接用
      super(message);
     }
}
class Div
{
	int div(int x,int y) throws FuShuException
	{
		if (y<=0)
            //手动通说关键字throw抛出自定义异常对象
			throw  new FuShuException("除数为负数");
		return x/y;
	}
}

在抛出自定义异常对象后,我们可以有两种解决方式:
A、在函数内部使用try - catch处理
B、在函数上声明
这里我们直接在函数上声明了
测试一下:
public static void main(String[] args) throws FuShuException
	{
		Div d=new Div();
		int x=d.div(4,0);
		System.out.println("x="+x);
}


3、RuntimeException
  RuntimeException是java语言异常体系中比较特殊的一个异常类。为什么说他特殊呢?我们通过上面的例子解释一下:
class Div
{
	int div(int x,int y) 	{
		if (y==0)
           			throw  new ArithmeticException("除数为0");
		return x/y;
	}
}

测试一下:
public static void main(String[] args) 	{
		Div d=new Div();
		int x=d.div(4,0);
		System.out.println("x="+x);
}

这里我们只是在函数内部将ArithmeticException这个异常对象抛出去,并没有在函数上声明,也没有在函数内部通过try - catch进行处理,但是在编译时(javac)并没有出现出错提示。这是为什么呢?
这里就涉及到ArithmeticException这个异常类的特点,
也就是RuntimeException的特殊之处:
A、若在函数内抛出该异常(这里所说的异常是RuntimeException异常及RuntimeException  的子类异常:空指针异常、算法异常、角标越界异常等),函数上可不用声明,编译能通过
B、若在函数上声明了该异常,调用者可不用进行处理,编译一样通过。
分析一下原因:
我们定义的这个算数方法是提供给用户使用的。用户并不知道他们输入的数值(这里只限数值)是怎样的。所以,输入合法的数值程序就会正常运行,若输入的数值不合法,那么JVM就会检测出输入的数值不合法,就会使用自定义的异常方式处理。但不需要将检测后的处理过程暴露给用户,只要将程序停止,那么用户就会意识到输入的数值不合法(不对),从而就会重新输入。

那么对于自定义异常,若该异常发生无法再继续进行运算,就让自定义异常继承RuntimeException。

异常分两种:
编译时检测异常(能处理的可标识出去)
运行时异常(编译时不被检测异常RuntimeException及其子类)

4、finally代码块
   finally代码块中定义的是一定要执行的语句,同常用于关闭资源。
处理语句的其他搭配:
try{}catch(){}
try{}catch(){}finally{}
try{}finally{}

5、覆盖时的异常特点
   我们知道,一般解决异常要么在函数上声明,要么在函数(方法)内抛出异常对象,要么在函数内使用try - catch进行处理。而函数(方法)具有覆盖的特点,那么,当子类覆盖父类的方法时,父类又有异常处理,子类在覆盖时应该注意那么问题呢?
(1)子类在覆盖父类方法时,如果父类中方法抛出异常,则子类在覆盖时抛出的异常必须是 父类方法抛出的异常或父类抛出异常的子类或者不抛。
(2)当父类方法中抛出多个异常时,子类覆盖父类方法时抛出的异常要能被父类处理(只能抛 出父类方法中异常的子集)
(3)如果父类或接口的方法中未抛出异常,则子类在覆盖方法时也不可抛出异常。
若此时子类发生了异常则必须进行try处理,且绝对不能抛(没有接的)

6、异常练习
异常可以将正常流程与出现的问题分离。
定义一个方法,用于计算圆(Circle)和长方形(Rectangular)的面积。由于计算的都是图形的面积,但是圆和长方形的面积公式不同,及实现的具体内容不同,可以定义一个接口,在接口中定义一个没有主体的方法,让子类具体实现(当然,也可以将计算面积的功能视为基本功能,定义抽象类和抽象方法,让子类复写父类的方法,并定义自己的具体计算方式)。
由于我们编写的程序是供用户使用的,他们不知道输入的内容具体是什么,如输入的数值是小于0的数,这时有可能出现问题。所以,要定义异常处理方式来避免问题的发生。
//定义异常
class NoValueException extends RuntimeException{
	NoValueException(String message){
		super(message);
	}	}
interface Shape
{
  //因为计算图形的面积公式不同,且要传递的参数也不同,
  //计算要使用到图形自身的长、宽或半径
	void getArea();//double getArea();无参 
}
class Rec implements Shape{
	//定义长方形的属性
	private int len,wid;
	//构造函数 初始化
	Rec(int len,int wid) //throws NoValueException 
						//继承RuntimeException 不用声明
	{
		if (len<=0 || wid<=0)
			throw new  NoValueException("非法值");
				//程序结束
		{
			this.len = len;
			this.wid = wid;
		}	
	}
	//覆盖getArea()方法
	public void getArea()
	{
		System.out.println("S(rec)="+len*wid);
	}
}

class Circle
{
	private int  radius;
  //全局常量,
	public static final double  PI=3.14;
	Circle(int radius)
	{
		if (radius<=0)
			throw new RuntimeException("非法值");//NoValueException 提示不同
		this.radius = radius;
	}
	public void  getArea()
	{
	System.out.println("S(circle)="+radius*radius*PI);
	}
}
class  ExceptionTest2
{
	public static void main(String[] args) 
	{
		
			Rec r = new Rec(3,8);//当长方形的长或宽出现负数时,若不做任何处理,程序继续运行,并打印结果,不合逻辑。
								 //故添加异常处理
			r.getArea();

			Circle c = new Circle(-2);
			c.getArea();
		//若此处处理,则程序继续运行到 over ,
		/*
		try
		{
			Rec r = new Rec(-3,8);
			r.getArea();
		}
		catch (NoValueException e)
		{
			System.out.println("over");
		}
		
	*/
	}   }







-------http://www.itheima.comjava培训、android培训期待与您交流!-------
[/size]
分享到:
评论

相关推荐

    黑马程序员------代理类中invoke方法注意点

    在Java编程中,代理类(Proxy)是一种设计模式,它允许我们为已有对象创建一个代理对象,以便在调用实际对象的方法之前或之后添加额外的功能。`invoke`方法是Java动态代理中的核心方法,它位于`java.lang.reflect....

    黑马程序员Javase笔记

    Java是世界上最流行的编程语言之一,尤其在...总结来说,"黑马程序员Javase笔记"涵盖了Java的基础语法、内存管理、面向对象编程、集合框架以及泛型和Map等内容,这些都是成为一名合格Java开发者必须掌握的核心知识。

    黑马程序员匠心之作 C++教程_第7阶段-C++实战项目机房预约讲义.rar

    《黑马程序员匠心之作 C++教程_第7阶段-C++实战项目机房预约讲义》是为C++初学者量身定制的一份详细教学资源。这份讲义深入浅出地介绍了C++编程语言,并通过实际的机房预约系统项目,帮助学习者将理论知识与实践相...

    B站黑马程序员Python教程学习笔记.zip

    7. **面向对象编程**:了解类(class)和对象的概念,掌握继承、封装和多态等面向对象特性。 【Python进阶知识】 在学习过程中,你还会接触到Python的更多高级特性: 1. **文件操作**:学习读写文件,包括文本...

    黑马程序员入学Java精华总结

    ### 黑马程序员入学Java精华总结 #### 一、Java概述与基础知识 1. **何为编程?** - 编程是指通过编写计算机能够理解的指令来解决问题或完成特定任务的过程。这些指令通常被组织成算法,并使用某种编程语言实现。...

    黑马程序员入学面试题

    3. **Java基础知识提问**:考察应聘者对于Java基础知识的掌握程度,包括但不限于数据类型、控制结构、面向对象特性等。 #### 2. 面向对象的理解 面向对象是一种编程范式,它将数据和处理这些数据的方法封装在一起...

    黑马程序员Python视频中代码、课后习题等第二章内容

    在“黑马程序员Python视频中代码、课后习题等第二章内容”这个资源包中,我们聚焦于Python编程语言的学习,特别是第二章的核心知识点。这一章通常会涵盖基础语法和重要概念,对于初学者来说是至关重要的。下面,我们...

    B站《黑马程序员匠心之作-C++教程从0到1入门编程,学习编程不再难》 配套笔记

    【标题】:“B站《黑马程序员匠心之作-C++教程从0到1入门编程,学习编程不再难》 配套笔记” 【描述】提及的是一个针对初学者的C++教学资源,来自B站上的视频课程“BV1et411b73Z”。这门课程的特色在于提供了一份...

    黑马程序员匠心之作 C++教程_第2阶段实战-通讯录管理讲义.rar

    《黑马程序员匠心之作 C++教程_第2阶段实战-通讯录管理讲义》是一份针对C++初学者精心编写的教学材料,旨在帮助学习者掌握C++编程语言的基础知识,并通过实际的通讯录管理系统项目来提升编程技能。这份讲义以简洁...

    黑马程序员匠心之作 C++教程_第5阶段-C++提高编程资料讲义.rar

    1. **面向对象编程**:C++是面向对象的编程语言,它支持类、对象、封装、继承和多态等核心概念。学习这一阶段的内容,你需要理解如何定义和使用类,以及如何通过对象来操作数据和实现功能。 2. **类与对象**:类是...

    【传智播客黑马程序员】Javaweb课件.7z

    1. **Java基础**:首先,你需要对Java编程语言有扎实的理解,包括基本语法、面向对象编程(类、对象、继承、多态等)、异常处理和集合框架(如ArrayList、LinkedList、HashMap等)。 2. **Servlet与JSP**:JavaWeb...

    黑马程序员入学测试题

    4. **面向对象编程**:对于Java或C++等面向对象的语言,测试可能包括类与对象的概念、封装、继承、多态等特性。 5. **异常处理**:了解如何在代码中捕获和处理异常,以确保程序的健壮性。 6. **文件操作**:掌握...

    黑马程序员SpringMVC课堂笔记

    《黑马程序员SpringMVC课堂笔记》是一份详细记录了SpringMVC框架学习过程的资料,主要针对Java EE开发者,特别是那些希望通过黑马程序员的教程来提升自己SpringMVC技能的学员。SpringMVC作为Spring框架的重要组成...

    黑马程序员C++教程讲义-保真

    黑马程序员的C++教程讲义会系统地介绍这些概念,帮助初学者从0到1逐步掌握C++编程。"assets"目录可能包含相关的辅助材料,如示例代码、图片或课件,这些资源可以增强学习体验,使理论与实践相结合。

    黑马程序员Android学习笔记

    内容可能涵盖变量、数据类型、控制流语句、类和对象、异常处理等基本概念,以及面向对象编程的特性如继承、多态和封装。对于没有Java背景的初学者,这部分尤为重要。 在Java基础牢固之后,笔记将转向Android特有的...

    黑马程序员struts2框架2016版资料

    "黑马程序员"是一家知名的编程教育机构,他们提供的Struts2框架教程资料旨在帮助开发者深入理解和掌握这一技术。 Struts2的核心特性包括: 1. **Action类**:它是业务逻辑处理的主要载体,继承自`ActionSupport`类...

    黑马程序员_Java基础辅导班教程课件[第01期]第15天

    总结来说,《黑马程序员_Java基础辅导班教程课件[第01期]第15天》的内容可能涉及了Java语言的核心概念,包括面向对象编程、控制结构、异常处理、文件I/O、集合框架以及内存管理等。通过深入学习和实践这些知识点,...

    黑马程序员_hibernate框架开发2016版讲义和笔记资料_day02

    《黑马程序员_hibernate框架开发2016版讲义和笔记资料_day02》 本文将深入探讨2016年黑马程序员发布的Hibernate框架开发课程的第二天内容。Hibernate,一个强大的Java持久化框架,简化了数据库操作,为开发者提供了...

Global site tag (gtag.js) - Google Analytics