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站/知乎/微信公众号:码农编程录