java学习面向对象之异常之一
一、异常的概述:
什么是异常?在我们编写java程序的时候,会出现一些问题,比如内存溢出啊或者数组索引超出最大索引啊,这些编程当中出现的这些个问题就是异常。但是异常也分为可以处理的和不可以处理的。比如JVM虚拟机出现的异常就是不可以处理的。可以处理的异常就是指,在我们java程序当中的数组最大索引超出啊,这些问题我们是可以处理的。同时异常也分为Error和Exception。从字面意义上来理解的话,可以理解成错误和异常。Error指在JVM运行当中出现异常,程序自动退出。下面我们来写个例子看下什么是异常?
- class Demo1
- {
- int[] arr = new int[];
- }
- class ExcepDemo1
- {
- public static void main(String[] args) {
- Demo1 demo = new Demo1();
- System.out.println(demo.arr[]);
- }
- }
因为这个地方我们的数组索引超出了最大值,这里就提示我们:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
如果我们这里出现语法错误又会怎样呢?
既然出现了异常,我们就要去修正。修正的方法有哪些呢,比如上面的索引溢出异常,这个时候,我们就得在代码当中来判断,如果索引大于最大值,我们应该怎么办。在处理错误的时候就得写很多的代码,来描述现在反生的异常是怎样的,在什么地方等等异常的信息。java是一门面向对象的语言,面向对象的特点之一就是封装,也就是把属性还有方法封装到一个类当中,这样就方便了我们的调用,以前是正常代码和异常处理代码结合,现在是把正常代码和异常处理代码分离,同时也提高了代码的复用性。在java当中,为了方便我们来处理异常,提供了一个异常类Exception给我们。其实异常就是java通过面向对象的思想将问题封装成对象,然后用异常类来描述。不同的问题,用不同的异常类进行描述。
问题很多,意味着描述类也很多,将其共性不断向上抽取,就形成了异常体系。对于体系而言,父类当中定义的都是最共性的东西。
最终问题 不正常情况分为两大类:
1、一般不可处理的。用Error类来表示。比如java xx 如果xx这个javaclass 不存在就会Error。一般由JVM抛出的,这种问题发生不会针对性处理,直接修改程序。
2、可处理的。用Exception类来表示, 可以进行针对性的处理
无论Error还是Exception,发生问题后,都要抛出。该体系的特点是throwable及其所有他的子类都有可抛性。
就像人生活中得病一样,一种是可治愈的,一种是不可治愈的。Error就是不可治愈的范畴了,Exception可以治愈的。
子类都是以其父类名作为后缀,阅读性就很强。
但是两者都有共性,向上抽取之后就是throwable。那么怎么体现可抛性呢?通过两个关键字来体现的,一个是throws,一个是throw。凡是可以被这两个关键字可以操作的类或者对象,都具有可抛性。
那么异常的执行流程也就是内部原理是怎样的呢?当出现异常的时候,首先调到功能定义的部分,如果功能定义的部分没有处理,继续网上抛出,直至被处理。如果自始至终都没有被处理的话,这个时候,就会把异常抛给虚拟机。虚拟机收到异常之后,停止程序的执行然后把异常的相关信息直接打印到控制台上面。
比如上述索引越界,我们可以这个样子来写:
- class Demo1
- {
- int[] arr = new int[];
- }
- class ExcepDemo1
- {
- public static void main(String[] args) {
- Demo1 demo = new Demo1();
- int num=;
- if(num>demo.arr.length){
- throw new Exception("the num is too large");//我们new完了异常之后,这个时候为了能够让调用者知道异常原因,这个时候我们引入了throw这个关键字
- }else{
- System.out.println(demo.arr[num]);
- }
- }
- }
throw和return的区别,有的人会说我们不用throw用return,这个就涉及工作的一个完成一个未完成,一个事情的完成是有结果的,使用return的作用就是返回结果。throw的作用就是终止现在的事情出异常了,没法继续下去了,没有结果就。比如,你让一个人去做一件事情,做到一半的时候,那个人感冒了,没法做下去了,就把信息返回给你说“我感冒了,这件事做不下去了”,这个时候这件事没有结果了就。所以不能用return。但是throw是有前提的,必须具有可抛性。
这个时候我们javac编译的话,真的出现异常啦:
这里提示我们要对未报告的异常错误进行捕捉或者声明,那么为什么要声明一个异常呢,声明的意思就是说他可能会出现什么错误。我们设计一个功能,这个功能(函数)可能会出现异常,我们知道他可能出现哪些异常,比如你买了一个面包要给我吃,面包放了三天了,你得最起码要在面包上面贴个标签说:面包可能坏了。这个就是声明,方便我就可以采取相应的措施进行处理。如何声明一个异常呢?这里又用到了一个关键字叫做throws,但是这个声明是有条件的,thorws是给函数修饰的,谁可能出现异常就声明谁。如果函数可能会出现异常,我们要在函数上声明异常,否则会编译失败。如果调用了声明异常的函数,你必须要处理,不处理一样也是编译失败,处理问题之一就是抛出问题。最终把异常抛给虚拟机了。
也就是说要想让一个类成为异常类,必须先让他继承异常体系,因为只有具备异常体系的共性,才具有可抛性,才可以被throws 还有 throw来操作。
修改代码如下:
- class Demo1
- {
- int[] arr = new int[];
- }
- class ExcepDemo1
- {
- /**
- *这个main方法可能出现错误,所以这个时候就该throws Exception 声明这个异常
- */
- public static void main(String[] args) throws Exception
- {
- Demo1 demo = new Demo1();
- int num=;
- if(num>demo.arr.length){
- throw new Exception("the num is too large");
- }else{
- System.out.println(demo.arr[num]);
- }
- }
- }
抛出的异常结果为:
这里就是我们自定义的异常信息。但是我们发现这个异常信息提示的是java.lang.Exception,如果冷不丁来这么个异常,我们也不知道问题出在那里哇?肿么办?我们自定义个非常好理解的异常来说下,如何定义一个异常?我们只需要定义一个类然后继承自Exception,然后覆盖相应的方法就可以了。下面我们来自定义一下:
- /**
- *这个地方我们命名的时候最好是以Exception结尾,这样可以增强阅读性
- */
- class MyOutofArrayIndexException extends Exception
- {
- /**继承完之后,我们来覆盖下Exception当中的方法,具体方法去查手册可知**/
- public MyOutofArrayIndexException(String s)
- {
- super(s);
- }
- }
- class Demo1
- {
- int[] arr = new int[];
- }
- class ExcepDemo1
- {
- /**
- *这个main方法可能出现错误,所以这个时候就该throws Exception 声明这个异常
- */
- public static void main(String[] args) throws MyOutofArrayIndexException
- {
- Demo1 demo = new Demo1();
- int num=;
- if(num>demo.arr.length){
- throw new MyOutofArrayIndexException("the num is too large");
- }else{
- System.out.println(demo.arr[num]);
- }
- }
- }
此时运行之后就体现了我们自定义的异常信息了。
那么我们每次调用个自定义的异常多麻烦啊,我们要是不用声明异常该多好啊。我们知道在我们第一个写的来演示异常的代码的时候,我们并没有声明异常啊,不也是照样过了。为什么自定义就要声明呢?这是因为啊,在我们没写的情况下,当时调用的是RuntimeException这个对象有个特点就是,编译的时候并不对他进行检查,只有在执行的时候才检查,如果有异常就调用。这样多好,我们不用声明啦,直接继承他看看。
- /**
- *这个地方我们继承了RuntimeException,也就是运行时异常,编译时并不检查
- */
- class MyOutofArrayIndexException extends RuntimeException
- {
- public MyOutofArrayIndexException(String s)
- {
- super(s);
- }
- }
- class Demo1
- {
- int[] arr = new int[];
- }
- class ExcepDemo1
- {
- public static void main(String[] args)
- {
- Demo1 demo = new Demo1();
- int num=;
- if(num>demo.arr.length){
- throw new MyOutofArrayIndexException("the num is too large");
- }else{
- System.out.println(demo.arr[num]);
- }
- }
- }
这个是编译通过的。
异常的分类:
1、编译时被检测异常:Exception 和 其子类 除了 RuntimeException类除外都是。这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应针对的处理方式。
2、编译时不检测异常(运行时检测)RuntimeException 及其子类都是,编译器并不检测这个。这种问题的发生,无法让功能继续,运算无法进行,更多是因为调用者的原因导致的,或者引发了内部状态的改变导致的。这种问题一般不处理,在运行时,让程序强制停止,让调用者对代码进行修改。RuntimeException是在正常运行之中,出现异常。而Error直接让虚拟机停掉。
自定义异常一个是继承Exception一个是继承自RuntimeException。
throw throws的区别
throws使用在函数上,throw是用在函数当中。
throws 声明异常类,可以声明多个,throw抛出的是异常对象。
java学习面向对象之异常之一的更多相关文章
- java学习面向对象之异常之二
我们知道当我们处理异常的时候,一个是声明,另外一个是捕捉. 捕捉:异常处理的捕捉方式,这是可以对异常进行针对性处理的方式.具体格式是: try { //需要被检测的异常 } catch(异常类 变量) ...
- Java学习---面向对象的远程方法调用[RMI]
基础知识 分布式计算是一门计算机科学,它研究如何把一个需要非常巨大的计算能力才能解决的问题分成许多小的部分,然后把这些部分分配给许多计算机进行处理,最后把这些计算结果综合起来得到最终的结果. 常见的分 ...
- 1.13(java学习笔记)异常机制
异常不同于错误,它是程序运行时产生的未知问题. 如果把程序比喻成一辆汽车,那么汽车开着开着突然前面出现了一个大石头挡住了路,这就叫异常. 那么出现了这个异常我们需要去处理,比如打电话给公路管理局,让它 ...
- Java学习 面向对象(下)——Java疯狂讲义th4
面向对象(下) [TOC] 包装类 通过包装类可以把8个基本类型的值包装成对象使用. 自动拆箱.自动装箱 把字符串类型值转换成基本类型的值: 包装类的 parseXxx(String s)静态方法 包 ...
- java学习面向对象之匿名内部类
之前我们提到“匿名”这个字眼的时候,是在学习new对象的时候,创建匿名对象的时候用到的,之所以说是匿名,是因为直接创建对象,而没有把这个对象赋值给某个值,才称之为匿名. 匿名对象回顾: class N ...
- java学习面向对象之内部类
什么是面向对象内部类呢?所谓的内部类,即从字面意义上来理解的话,就是把类放到类当中. 那么内部类都有什么特点呢? 1.内部类可以访问包裹他的类的成员. 2.如果包裹他的类想访问被其包裹的类的话就得实例 ...
- java学习面向对象之多态
如何理解多态,让我们举个例子来描述一下,因为单纯的说多态大家可能不理解: abstract class Animal { ; abstract void eat(); public void run( ...
- java学习面向对象之接口
上一节当中我们说道抽象类,抽象类当中的方法可以是抽象的也可以是非抽象的,那么当抽象类中所有方法都是抽象的时候,我们就可以把它重新定义为接口.代码示例: abstract class Animal { ...
- java学习面向对象之父子构造函数初始化
在之前讲到java面向对象继承的时候,我们只讲到了两个比较重要的知识点,一个是父子类当中有同名的成员变量,这个时候,我们引入了super这个关键字来区分这两个同名成员变量,除此之外,我们还讲到了父子同 ...
随机推荐
- Razor的理解
[原创]Razor非常智能非常实用,不了解的人可能会觉得有没有都无所谓,其实不然,起初对Razor不是太了解,现在想想Razor就是来标示出C#语法的,但是HTML和C#混合输出时到底@这个小老鼠到底 ...
- ArcGIS 设置地图显示范围大小
Arcmap的FullExtent默认是地图加载的时候的extent.其实这个fullExtent是可以设置的. 打开ArcMap,选择左边图例的Layers ,右键点击,选择“Properties. ...
- Windows I/O模型、同步/异步、阻塞/非阻塞
转载自:http://www.cppblog.com/tx7do/articles/5954.html 同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.按照这个定义,其实 ...
- 【转】Objective-C中的instancetype和id关键字
原文:http://blog.csdn.net/wzzvictory/article/details/16994913 一.什么是instancetype instancetype是clang 3.5 ...
- a+b(用子函数)
今天编的一个较简单的函数调用的程序 题目:a+b(用子函数) 程序 #include<stdio.h> void addition() { int a,b; scanf("%d ...
- a*b(高进度乘以int类型的数)
以下是我今日的a-b(高精度)的程序,\(^o^)/偶也偶也偶也偶也! 程序: #include<stdio.h> #include<string.h> char s[1000 ...
- 100. Same Tree(C++)
100. Same Tree Given two binary trees, write a function to check if they are equal or not. Two binar ...
- js 判断一个点是否在一个多边形之内
出处: https://github.com/substack/point-in-polygon/blob/master/index.js github: https://github.com/sub ...
- 20 Valid Parentheses(匹配括号)
题目意思:判断一个字符串(){}[]是否符合 思路:用栈ps:实习一个多月了,代码也刷不动了,状态真不是一般的差 class Solution { public: bool isValid(strin ...
- demo_04绘制三角形
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...