【Java25】异常练习


1.try catch finally

package com.atguigu.test01.review;
// 编写代码演示栈内存溢出 StackOverflowError(递归导致内存溢出)
public class TestError1 {
    
    
	public static void main(String[] args) {
    
    
		Son s = new Son();
		s.test(); //自己调用自己,不调用父类test()方法。java.lang.StackOverflowError
	}
}
class Father{
    
    
	public void test(){
    
    
		System.out.println("父类的");
	}
}
class Son extends Father{
    
    
	public void test(){
    
     
		//调用父类的test();要用super.test()
		test();
		System.out.println("子类的");
	}
}
package com.atguigu.test01.review;
import java.util.ArrayList;
// 请编写代码演示OOM:OutOfMemoryError
public class TestError2 {
    
    
	public static void main(String[] args) {
    
    
		//1、答案一:创建一个超级大数组,
		//数组的长度的类型是int,Integer是int类型的一个包装类,Integer.MAX_VALUE是2的31次方-1
//		int[] arr = new int[Integer.MAX_VALUE];		

		//2、答案二:不断的创建对象
		ArrayList list = new ArrayList();//容器,用来装对象
		while(true){
    
    
			list.add(new Object());
		}
	}
}
package com.atguigu.test02.review;
/*
 *记住return后代码不执行除了finallly,try中return记住值
 * (1)因为finally有return,最终一定从finally的语句 回去
 * (2)但是try中的return也会走,只是执行它的第一个动作,把返回值放到“操作数栈”
 * 例如:把i=1先放到操作数栈中
 * (3)因为finally有return,这个时候,我们这里的return也有两个动作
 * ①再把它的返回值也放到操作数栈中,i=2,②结束当前方法
 */
public class Test04 {
    
    
	static int i = 0;
	public static void main(String[] args) {
    
    
		System.out.println(test()); //2
	}
	public static int test(){
    
    
		try{
    
    
			return ++i;
		}finally{
    
    
			return ++i;
		}
	}
}
package com.atguigu.test02.review;
/*
 * (1)因为finally中没有return,最后结束是从try或catch中回去
 * (2)我们try或catch中的return 返回值;语句拆开来执行
 * ①先把返回值放到“操作数栈”,8的值放到操作数栈中
 * ②再去走finally
 * 此时虽然finally对result做了修改,但是没有影响操作数栈中值
 * ③回去执行return后半个动作,结束当前方法
 */
public class Test01 {
    
    
	public static void main(String[] args) {
    
    
		int test = test(3,5);
		System.out.println(test); //8
	}
	public static int test(int x, int y){
    
    
		int result = x;
		try{
    
    
			if(x<0 || y<0){
    
    
				return 0;
			}
			result = x + y;
			return result;
		}finally{
    
    
			result = x - y;
		}
	}
}
public class TestFinallyNoReturn {
    
    
	public static void main(String[] args) {
    
    
		String str = getNum(1);
		System.out.println(str);
	}	
		
	public static String getNum(int a){
    
    
		try{
    
    
			System.out.println(a/0);
			if(a > 0){
    
    
				return "正数";
			}else if(a < 0){
    
    
				return "负数";
			}else{
    
    
				return "零";
			}
		}catch(Exception e){
    
    
			System.out.println("exception");
			return "异常"; //最后走
		}finally{
    
     //里面没return
			System.out.println("finally");
		}
	}
}

在这里插入图片描述

public class TestFinallyNoReturn2 {
    
    
	public static void main(String[] args) {
    
    
		int num = getNum(4);
		System.out.println(num);//0,不是30
	}
	
	public static int getNum(int a){
    
    
		int result = 10;
		try{
    
    
			System.out.println(a/0); //直接跳到catch
			if(a > 0){
    
    
				result = 20;
				return result;
			}else if(a < 0){
    
    
				result = -20;
				return result;
			}else{
    
    
				return result;
			}
		}catch(Exception e){
    
    
			System.out.println("exception");
			result = 0;
			return result;
		}finally{
    
    
			result = 30;
			System.out.println("finally");
//			return result;//如果有这句,最后一行结果就变成30
		}
	}
}

在这里插入图片描述

package com.atguigu.test05;

import java.util.InputMismatchException;
import java.util.Scanner;
//从键盘输入两个整数a,b,求两个数的和、差、积、商。并且尝试使用try...catch处理可能发生的异常
public class TestExer {
    
    
	public static void main(String[] args) {
    
    
		Scanner input = new Scanner(System.in);
		try {
    
    
			System.out.print("请输入一个整数:");
			int a = input.nextInt();			
			System.out.print("请输入另一个整数:");
			int b = input.nextInt();			
			System.out.println("和:" + (a+b));
			System.out.println("差:" + (a-b));
			System.out.println("积:" + (a*b));
			System.out.println("商:" + (a/b));
		} catch (InputMismatchException e) {
    
    
			System.err.println("输入错误,应该输入整数");
		} catch (ArithmeticException e) {
    
    
			System.err.println("除数不能为0");
		} catch (Exception e) {
    
    
			e.printStackTrace();
		} finally{
    
    
			input.close();//资源关闭
		}
	}
}
package com.atguigu.test05;
import java.util.InputMismatchException;
import java.util.Scanner;
//增加要求:如果输入有问题,提示错误信息后重新输入,如果没问题,就不重新输入
public class TestExer2 {
    
    
	public static void main(String[] args) {
    
    
		Scanner input = new Scanner(System.in);
		while(true){
    
    
			try {
    
    
				System.out.print("请输入一个整数:");
				int a = input.nextInt();//"a"不被int接收,一直在通道中,要读出来丢掉				
				System.out.print("请输入另一个整数:");
				int b = input.nextInt();				
				System.out.println("和:" + (a+b));
				System.out.println("差:" + (a-b));
				System.out.println("积:" + (a*b));
				System.out.println("商:" + (a/b));
				break; //一切正常,走一次就行
			} catch (InputMismatchException e) {
    
    
				System.err.println("输入错误,应该输入整数");
				String str = input.nextLine();//读取当前行所有内容,我没有接受,就表示丢弃了
				System.out.println(str);
			} catch (ArithmeticException e) {
    
    
				System.err.println("除数不能为0");
			} catch (Exception e) {
    
    
				e.printStackTrace();
			} 
		}		
		input.close();
	}
}

在这里插入图片描述
在这里插入图片描述

package com.atguigu.test05;
/*
 * (1)finally里面有return,就从finally的return回去了
 * (2)类初始化:main所在的类要先初始化,才能执行main方法
 * 由①静态变量的显示赋值(这里没有)②静态代码块
 *(3)实例初始化:必须要new对象才会有,这里没有创建TestExer4的对象,所以不走
 */
public class TestExer4 {
    
    
	{
    
    
		System.out.println("b");
	}
	static{
    
    
		System.out.println("a");
	}
	TestExer4(){
    
    
		System.out.println("c");
	}
	
	public static String getOut(){
    
    
		try{
    
    
			return "1";
		}catch(Exception e){
    
    
			return "2";
		}finally{
    
    
			return "3";
		}
	}
	
	public static void main(String[] args) {
    
    
		System.out.println(getOut());//3
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.atguigu.test07;
/*
 * 面试题:throw和throws什么区别?
 * (1)throw用于手动抛出异常对象,是个可执行的语句
 * (2)throws,在方法签名中,声明方法可能抛出什么异常,让调用者来处理这些异常。
 */
public class TestThrow {
    
    
	public static void main(String[] args) {
    
    
		Account a = new Account(100);
		try {
    
    
			boolean flag = a.withdraw(500);			
			System.out.println("取款成功" + flag); //如果没有异常,取款成功
		} catch (IllegalArgumentException e) {
    
    
//			System.out.println(e.getMessage());
			e.printStackTrace();
		} catch (RuntimeException e) {
    
    
//			System.out.println(e.getMessage());
			e.printStackTrace();
		}
	}
}

//111111111111111111111111111111111111111111111111111111111111111111111111111111
class Account{
    
    
	private double balance;	
	public Account(double balance) {
    
    
		super();
		this.balance = balance;
	}
	public boolean withdraw(double money)throws IllegalArgumentException,RuntimeException{
    
    
		if(money < 0){
    
    
			//System.out.println("取款金额不能小于0");
			throw new IllegalArgumentException("取款金额" +money + "有问题,取款金额不能小于0");
		}
		if(money > balance){
    
    
			throw new RuntimeException("余额不足");
		}		
		balance -= money;
		return true;
	}
}

在这里插入图片描述

2.自定义异常

/*
 * 1、自定义异常的要求:
 * (1)必须继承Throwable或它的子类
 * 但是实际开发中,一般继承RuntimeException和Exception
 * (2)建议大家保留两种构造器的形式
 * ①无参构造
 * ②带给父类的message属性赋值的构造器
 * 
 * 2、如何使用自定义异常
 * 只能使用throw语句进行手动抛出。它不能由JVM自动抛出。
 */

在这里插入图片描述

package com.atguigu.test09;

public class Account {
    
    
	private String id;
	protected double balance;
	private double annualInterestRate;
	public Account(String id, double balance, double annualInterestRate) {
    
    
		super();
		this.id = id;
		this.balance = balance;
		this.annualInterestRate = annualInterestRate;
	}
	public Account() {
    
    
		super();
	}
	public String getId() {
    
    
		return id;
	}
	public void setId(String id) {
    
    
		this.id = id;
	}
	public double getBalance() {
    
    
		return balance;
	}
	public void setBalance(double balance) {
    
    
		this.balance = balance;
	}
	public double getAnnualInterestRate() {
    
    
		return annualInterestRate;
	}
	public void setAnnualInterestRate(double annualInterestRate) {
    
    
		this.annualInterestRate = annualInterestRate;
	}
	
	public double getMonthlyInterestRate(){
    
    
		return annualInterestRate / 12;
	}
	public double getMonthlyInterest(){
    
    
		return balance * getMonthlyInterestRate();
	}

//11111111111111111111111111111111111111111111111111111111111111111111111111111111
	public void withdraw(double money) throws AccountException{
    
    
		if(money < 0){
    
    
			throw new AccountException("取款金额有误,不能小于0");
		}
		if(money > balance){
    
    
			throw new AccountException("余额不足");
		}
		balance -= money;
	}
	public void deposit(double money) throws AccountException{
    
    
		if(money < 0){
    
    
			throw new AccountException("存款金额有误,不能小于0");
		}
		balance += money;
	}
}
package com.atguigu.test09;

public class AccountException extends Exception{
    
    
	public AccountException() {
    
    
		super();
	}
	public AccountException(String message) {
    
    
		super(message);
	}
}

在这里插入图片描述

package com.atguigu.test09;

public class TestAccount {
    
    
	public static void main(String[] args) {
    
    
		Account a = new Account("1122", 20000, 4.5/100);		
		try {
    
    
			a.withdraw(30000);
			System.out.println("取款成功:余额," + a.getBalance());
		} catch (AccountException e) {
    
     
			System.out.println("取款失败,原因:" + e.getMessage());
		}		
		try {
    
    
			a.withdraw(2500);
			System.out.println("取款成功:余额," + a.getBalance());
		} catch (AccountException e) {
    
    
			System.out.println("取款失败,原因:" + e.getMessage());
		}		
		try {
    
    
			a.deposit(3000);
			System.out.println("存款成功,余额:" + a.getBalance());
			System.out.println("月利率:" + a.getMonthlyInterestRate() * 100 + "%");
			System.out.println("年利息:" + a.getBalance() * a.getAnnualInterestRate());
		} catch (AccountException e) {
    
    
			System.out.println("存款失败,原因:" + e.getMessage());
		}
	}
}

在这里插入图片描述
在这里插入图片描述

package com.atguigu.test09;

public class CheckAccount extends Account{
    
    
	private double overdraft;
	public CheckAccount(String id, double balance, double annualInterestRate, double overdraft) {
    
    
		super(id, balance, annualInterestRate);
		this.overdraft = overdraft;
	}
	public CheckAccount() {
    
    
		super();
	}
	public double getOverdraft() {
    
    
		return overdraft;
	}
	public void setOverdraft(double overdraft) {
    
    
		this.overdraft = overdraft;
	}
	@Override
	public void withdraw(double money) throws AccountException {
    
    
		if(money <= balance){
    
    
			balance -= money;
		}else if(money > balance + overdraft){
    
    
			throw new OutOfOverdraftException("超过可透支额度");
		}else{
    
    
			overdraft -= money - balance;//超过余额部分
			balance = 0;
		}
	}	
}
package com.atguigu.test09;

public class OutOfOverdraftException extends AccountException{
    
    
	public OutOfOverdraftException() {
    
    
		super();
	}
	public OutOfOverdraftException(String message) {
    
    
		super(message);
	}
}
package com.atguigu.test09;

public class TestCheckAccount {
    
    
	public static void main(String[] args) {
    
    
		CheckAccount c = new CheckAccount("1122", 20000, 4.5/100, 5000);		
		try {
    
    
			c.withdraw(5000);
			System.out.println("取款成功,余额:" + c.getBalance() + ",可透支额度:" + c.getOverdraft());
		} catch (AccountException e) {
    
    
			System.out.println("取款失败,原因:" + e.getMessage());
		}		
		try {
    
    
			c.withdraw(18000);
			System.out.println("取款成功,余额:" + c.getBalance() + ",可透支额度:" + c.getOverdraft());
		} catch (AccountException e) {
    
    
			System.out.println("取款失败,原因:" + e.getMessage());
		}		
		try {
    
    
			c.withdraw(3000);
			System.out.println("取款成功,余额:" + c.getBalance() + ",可透支额度:" + c.getOverdraft());
		} catch (AccountException e) {
    
    
			System.out.println("取款失败,原因:" + e.getMessage());
		}
	}
}

在这里插入图片描述
B站/知乎/微信公众号:码农编程录
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43435675/article/details/112680624