异常java

异常

  • 程序执行时,出现了不可预见的错误信息,被称为异常

  • java将该异常输出到控制台上,供程序员参考,进行程序的修改,使得程序更加健壮

  • 异常在java中以类形式存在,每一个异常类都可以创建异常对象 ——例题一

  • 异常的继承结构:使用UML图描述

    • UML是统一建模语言,UML描述类与类之间的关系,程序执行的流程,对象的状态
  • Exception是 Throwable(可抛出的)的子类

    • Throwable包括两个子类,另外一个是Error【不可处理,直接退出JVM】,而Exception是可处理的
    • exception包括ExceptionSubClass和RuntimeException两个之类
    • ExceptionSubClass属于编译时异常(受检异常),编译时异常表示必须在编译程序的时候预先对这种异常进行处理,如果不处理编译器报错。【语法错误】【编译异常和运行异常都发生在运行阶段,编译时异常发生概率较高,运行时异常发生概率较低。对于较高概率的异常,需要在运行之前对其进行预处理】
    • RuntimeException属于运行时异常(未受检异常) ——例题二
  • java语言对异常的处理包括两种方式 ——例题三

    • 方式一:在方法声明的位置上,使用throws关键字,抛给上一级【谁调用抛给谁】。
    • 方式二:使用try …catch进行异常捕捉。
  • 异常的重要方法: ——例题六

    • 获取异常简单的描述信息 String msg = exception.getMessage();
    • 打印异常追踪的堆栈信息 exception.printStackTrace();
      • 使用自动生成try catch方法的时候在catch语句块会打印异常信息。程序员理解异常信息可以帮助自己快速调解程序。【异常现象从上往下看,看自己编写的类,找到根源】
  • 关于try catch中的finally子句 ——见例七

    • 在finally子句中的代码最后执行,并且一定会执行,即使try语句块代码出现异常
    • finally语句必须和try一起出现,不能单独编写
    • finally子句的适用情况:通常在finally语句块完成资源的释放/关闭。
    • try中的return和fianlly执行顺序
    • try语句块中执行退出jvm,finally将不再执行!!
  • 子类继承父类,继续方法的重写,重写之后的方法不能比重写之前的方法抛出更多(更宽泛)的异常,可以更少。

    • 父类不抛,子类不能抛
    • 父类抛FileNotFoundException,子类不能抛Exception
    • 父类抛IOException,子类可以抛IOException,也可以抛FileNotFoundException等IOException的子类,也可以不抛。

  • 异常使用的关键字
    • try catch finally
    • throws 在方法声明时使用,表示上报异常信息给调用者
    • thorw是手动抛异常。

空指针异常

  • NullPointerException

数组下标越界异常

  • ArrayIndexOutOfBoundsException

类型转换异常

  • ClassCastException

数字格式化异常

  • NumberFormatException
  • Integer m1 = new Integer(“张掖”); //虽然Integer可以传入字符串,但是字符串要求是以数字类型组成的

例题一

package Advance.exception;

/**
 * @author 衣鱼
 *	java提供异常机制的作用
 *		程序执行时,出现了不可预见的错误信息,被称为异常
 *		java将该异常输出到控制台上,供程序员参考,进行程序的修改,使得程序更加健壮
 *
 *	异常在java中以类形式存在,每一个异常类都可以创建异常对象
 */
public class EXceptionTest01 {
	public static void main(String[] args) {
		//通过异常类,实例化异常对象
		NumberFormatException nfe = new 	NumberFormatException("数字格式化异常");
		System.out.println(nfe);		//toString方法
		
		ClassCastException cce = new  ClassCastException("类型转换异常");
		System.out.println(cce);
		
		ArrayIndexOutOfBoundsException aobe = new  ArrayIndexOutOfBoundsException("数组下标越界异常");
		System.out.println(aobe);
		
		NullPointerException npe = new NullPointerException("空指针异常");
		System.out.println(npe);
		
		
		
	}
}

例题二

package Advance.exception;

public class ExceptionTest02 {
	public static void main(String[] args) {
		System.out.println(100/0);
		/**
		 * 程序执行到此发生了ArithmeticException异常
		 * 底层new ArithmeticException异常对象
		 * 然后抛出ArithmeticException给main方法
		 * main方法没有处理,将这个异常自动抛给JVM
		 * jvm最终终止程序执行 所不会输出hello world
		 * 
		 * ArithmeticException属于运行时异常
		 */
		System.out.println("hello world !");
	}
}

例题三

package Advance.exception;

/**
 * @author 衣鱼
 *	doSome()方法调用报错的原因是什么?
 */
public class ExceptionTest03 {
	
	//第一种处理:在方法声明上继续使用throws ,来完成异常的继续上抛 ,抛给调用者
	//上抛类似推卸责任 ,将异常抛给调用者
	//public static void main(String[] args) throws ClassNotFoundException {
		/**
		 * main方法调用doSome()方法
		 * 因为doSome()方法声明位置上有throws ClassNotFoundException
		 * 所以在调用doSome()方法时,必须对异常进行预先处理
		 * 如果不处理,编译器会报错
		 */
	//	doSome();    //编译器报错 :Unhandled exception type ClassNotFoundException
//	}
	
	//第二种方式 try ......catch 进行捕捉
	//捕捉相当于把异常拦下来,上层不知道
	public static void main(String[] args) {
		try {
			doSome();
		}catch(ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * doSome方法在方法声明的位置使用了throws ClassNotFoundException
	 * 这个代码表示doSome()方法在执行过程中,可能出现ClassNotFoundException异常
	 *  ClassNotFoundException的父类属于Exception,所以 ClassNotFoundException属于编译时异常
	 * @return 
	 * @throws ClassNotFoundException
	 */
	public static  void doSome() throws ClassNotFoundException{
		//System.out.println("dosome !");
	}
	
}

例题四

package Advance.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

/**
 * @author 衣鱼
 *
 */
public class ExceptionTest04 {
	public static void main(String[] args) {
		System.out.println("main begin");
		m1();
		System.out.println("main over");
	}

	private static void m1() {
		System.out.println("m1begin");
		m2();
		System.out.println("m1over");
	}

	private static void m2() {
		System.out.println("m2begin");
		m3();
		System.out.println("m2over");
	}

	private static void m3() {
		//调用sun jdk的构造方法   
		/**
		 * 运行报错
		 * 		该处调用了一个构造方法: FileInputStream();
		 * 		该方法的源代码声明位置上有:throws FileNotFoundException
		 * 		通过类的继承结构看到:FileNotFoundException 父类是IOException 
		 * 		IOException的父类Exception,所以,FileNotFoundException是编译时异常
		 * 
		 * 		编译时异常要求程序员编写程序对该程序进行处理,不处理就会报错。
		 */
		//new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx");		//创建一个输入流对象,该流指向一个文件
		try {
		new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx");		//创建一个输入流对象,该流指向一个文件
		}catch(FileNotFoundException ffe) {		//往上写父类没有问题
			System.out.println("文件未找到");
		}
	}
}

在这里插入图片描述

例题五

package Advance.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author 衣鱼
 * 异常捕捉的情况下,方法的后续代码照样执行。
 * 异常上抛的情况下,方法的后续代码不再执行。
 * 
 * try catch	
 * 		1、catch后的小括号中的类型可以是具体的异常类型,也可以是该异常类型的父类型
 * 		2、catch可以写多个,建议精确到一个个处理,有利于程序调试
 * 		3、catch多个情况处理时,从上到下必须遵从从小到大的原则。先子类再父类。
 */
public class ExceptionTest04 {
	public static void main(String[] args) {
		System.out.println("main begin");
		m1();
		System.out.println("main over");
	}

	private static void m1() {
		System.out.println("m1begin");
		m2();
		System.out.println("m1over");
	}

	private static void m2() {
		System.out.println("m2begin");
		m3();
		System.out.println("m2over");
	}

	private static void m3() {
		//调用sun jdk的构造方法
		/**
		 * 运行报错
		 * 		该处调用了一个构造方法: FileInputStream();
		 * 		该方法的源代码声明位置上有:throws FileNotFoundException
		 * 		通过类的继承结构看到:FileNotFoundException 父类是IOException 
		 * 		IOException的父类Exception,所以,FileNotFoundException是编译时异常
		 * 
		 * 		编译时异常要求程序员编写程序对该程序进行处理,不处理就会报错。
		 */
		//new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx");		//创建一个输入流对象,该流指向一个文件
	 	
		try {
		new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx");		//创建一个输入流对象,该流指向一个文件
		}catch(FileNotFoundException ffe) {
			System.out.println("文件未找到");
		}
		
		try {
			new FileInputStream("C:\\Users\\衣鱼\\Desktop\\随机算法.docx");		//创建一个输入流对象,该流指向一个文件
			}catch(FileNotFoundException ffe) {
				System.out.println("文件未找到");
			}catch(IOException ie) {
				System.out.println("读文件报错");
			}
		
	}
}

例题六

package Advance.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

/**
 * @author 衣鱼
 *		异常对象的重要方法
 *			String msg = exception.getMessage();		//获取异常简单的描述信息
 *			exception.printStackTrace();		//打印异常追踪的堆栈信息
 */
public class ExceptionTest05 {
	public static void main(String[] args) {
		NullPointerException e = new NullPointerException("空指针异常dfhhediue");		//new异常对象,但没有抛出 不会中断程序
		//获取异常信息,构造方法的String参数
		String msg = e.getMessage();	  //空指针异常dfhhediue
		System.out.println(msg);
		
		//打印异常堆栈信息   
		e.printStackTrace();		//后台打印信息的时候,采用了异步线程的方式
		
		System.out.println("hello world ");
		
		m1();
	}

	private static void m1() {
		m2();
	}

	private static void m2() {
		m3();	
	}

	private static void m3() {
		//自动生成try catch
		try {
			new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx");
		} catch (FileNotFoundException e) {
			//System.out.println("文件未找到");
			e.printStackTrace();		//异常追踪信息
			System.out.println("=======================================");
			String msg = e.getMessage();	  
			System.out.println(msg);
			
		}
	}
}

例题七

package Advance.exception;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * @author 衣鱼
 *	关于try  catch中的finally子句:
 *		1、在finally子句中的代码最后执行,并且一定会执行,即使try语句块代码出现异常
 *		2、finally语句必须和try一起出现,不能单独编写
 *		3、finally子句的适用情况:通常在finally语句块完成资源的释放/关闭。
 */
public class ExceptionTest06 {
	public static void main(String[] args) {
		FileInputStream fs = null; //声明位置放在try的外面,这样在finally中才能使用
		try {
			 fs = new FileInputStream("C:\\Users\\衣鱼\\Desktop\\课后题.docx");
			
			//空指针异常
			String s = null;
			s.toString();
			
			System.out.println("+++++======+++++++");		//不会在控制台输出,因为空指针异常;所以try中以后的代码也不会执行
			//关闭流 流不关闭还是需要占用资源的
			//目标:即使上面的程序出现异常,流仍然需要关闭
			//fs.close();
			
		}catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {		//关闭流
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//finally的代码一定会执行,即使try出现异常
			//将关闭流的代码放入finally更适合
			if(fs!=null){
				//fs.close();			//IO异常,进行捕捉
				try {
					fs.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}	
			}
			System.out.println(".................................................................");  //输出,finally语句中都会执行
		}
	}
}

package Advance.exception;
/**
 * @author 衣鱼
 *	finally的深层次理解	
 *		try中的return和fianlly执行顺序
 */
public class ExceptionTest07 {
	public static void main(String[] args) {
		//try finally 没有catch 是可以的
		/*
		//代码的执行顺序:
				//先执行try
				//再执行finally
				//最后执行return  [return执行,方法必然结束]
		try {
			System.out.println("try......");
			return;			//finally内的代码块依旧会执行
		}finally {
			System.out.println("finally......");
		}
		//System.out.println("===============");   //代码不会执行
	*/
		try {
			System.out.println("try......");
			//退出jvm
			System.exit(0);   	//退出jvm finally不会执行
		}finally {
			System.out.println("finally......");
		}
		
	}
}

finally面试题

package Advance.exception;
/**
 * @author 衣鱼
 *	面试题:
 *		输出结果是什么?——100
 *		
 *java语法规则:
 *		方法体中的代码必须遵循自上而下的顺序依次执行
 *		return语句一旦执行,整个方法必须结束
 */
public class ExceptionTest08 {
	public static void main(String[] args) {
		int result = m();
		System.out.println(result);
	}
	public static int m() {
		int i =100;		//流程①
		try {
			//这行代码出现在int i= 100 后面 所以最终返回必须是100
			//return一定是最后执行的,一旦执行,整个方法结束
			return i;					//流程③
		}finally {
			i++;					//流程②
		}
	}
	
	/*
	  m()反编译之后的效果
	  public static int m() {
	  		int i =100;
	  		int j = i;
	  		i++;
	  		return j;
	  }
	 */

}

final finally finalize 区别

package Advance.exception;
/**
 * @author 衣鱼
 *	
 */
public class ExceptionTest09 {
	public static void main(String[] args) {
		//final 是一个关键字 表示最终的不变的
		final int i =100;
		
		//finally 是一个关键字 和try联合使用
		
		//finalize 是Object类中的一个方法  作为一个方法名存在
		//标识符 该方法由垃圾回收器调用
		
	}
}

见Object文章
在这里插入图片描述

自定义异常

  • SUN提供的JDK内置的异常是不够用的,且具体的业务具有自己独特的问题,出现的异常在JDK中是不存在的。
  • java中自定义异常
    • ①编写一个类继承Exception或者RuntimeException
    • ②提供两个构造方法,一个无参,一个有参。
package Advance.exception;
/**
 * @author 衣鱼
 *		自定义异常
 *			异常类型:MyException
 *			父类: Exception
 */
public class MyException extends Exception {
	public MyException() {		
	}
	public MyException(String s) {			
		}
}


package Advance.exception;
/**
 * @author 衣鱼
 *	测试自定义的异常类
 */
public class MyExceptionTest {
	public static void main(String[] args) {
		MyException me = new MyException("用户名不能为空");	//调用自定义的异常测试程序的时候需要throw出去
		//throw me;			//如果自定义异常是编译时异常,需要进行预处理,此时我们刚抛出去异常,不能在使用catch捕捉,在方法上继续throws
		me.printStackTrace();
	}
}

模拟用户注册

package homework;
/**
 * @author 衣鱼
 *	编写程序模拟用户注册
 *		1、程序执行,需要用户输入”用户名“、”密码“
 *		2、输入信息后。后台java程序模拟用户注册
 *		3、注册用户名要求长度【3-10】之间。其他为异常
 *	
 */
public class Register {
	public static void main(String[] args) {
		UserServise us = new UserServise();
		try {
			us.register(args[0],args[1]);
		} catch (MyUserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
/**
 * 
 * @author 衣鱼
 *	username 用户名
 *	password 密码
 *	当用户名为空、用户名小于3位、用户名大于10位 出现MyUserException 异常
 */
class UserServise{
	public void register(String username ,String password) throws MyUserException {
		//引用等于null判断最好放在最前面
		//username == null  不如写成 null==username  考虑到程序员失误,把双等于写成一个赋值等于
		if(null ==username||username.length()<3||username.length()>10) {
			//MyUserException mue =new MyUserException("注册用户名要求长度【3-10】之间");
			//throw mue;
			throw new MyUserException("注册用户名要求长度【3-10】之间");
		}else {
			System.out.println("注册成功");
		}
	}
}

//自定义异常类
class MyUserException extends Exception{
	public MyUserException() {
		
	}
	public MyUserException(String s) {
		super(s);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值