震惊,java异常竟可以这样做!!!

本文详细介绍了冒泡排序的不同优化版本及其实现,并探讨了二分查找算法的工作原理。此外,还深入讲解了Java异常处理机制,包括try-catch-finally语句的执行流程和异常处理的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

day12

在这里插入图片描述

数组排序

冒泡排序:

相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处

public static void bubbleSort01(int[] arrs) {
		System.out.println("原数组:"+toString(arrs));
		for(int i=0;i<arrs.length-1;i++) {//控制趟数
			System.out.println("第"+(i+1)+"趟");
			for(int j=0;j<arrs.length-1;j++) {//次数
				if(arrs[j]>arrs[j+1]) {
					int temp = arrs[j];
					arrs[j] = arrs[j+1];
					arrs[j+1] = temp;
				}
				System.out.println("第"+(j+1)+"次:"+toString(arrs));
			}
		}
		
	}
第一次优化

如果这一趟没有交换,下一趟就不执行。

public static void bubbleSort03(int[] arrs) {
		System.out.println("原数组:"+toString(arrs));
		for(int i=0;i<arrs.length-1;i++) {//控制趟数
			//声明一个是否排好序
			boolean isSorted = true;
			System.out.println("第"+(i+1)+"趟");
			for(int j=0;j<arrs.length-1-i;j++) {//次数
				if(arrs[j]>arrs[j+1]) {
					isSorted = false;
					int temp = arrs[j];
					arrs[j] = arrs[j+1];
					arrs[j+1] = temp;
				}
				System.out.println("第"+(j+1)+"次:"+toString(arrs));
			}
			
			//判定
			if(isSorted) {
				break;
			}
			
		}
		
	}
第二次优化

这一趟交换完后,基准点从末尾移动到已经排好序的位置

​ 如果这一趟没有交换,下一趟就不执行。

public static void bubbleSort04(int[] arrs) {
		System.out.println("原数组:"+toString(arrs));
		//基准点
		int index = arrs.length-1;
		for(int i=0;i<arrs.length-1;i++) {//控制趟数
			//声明一个是否排好序
			boolean isSorted = true;
			
			int tmp = 0; 
			System.out.println("第"+(i+1)+"趟");
			for(int j=0;j<index;j++) {//次数
				if(arrs[j]>arrs[j+1]) {
					isSorted = false;
					int temp = arrs[j];
					arrs[j] = arrs[j+1];
					arrs[j+1] = temp;
					tmp = j;
				}
				
				System.out.println("第"+(j+1)+"次:"+toString(arrs));
			}
			index = tmp;
			//判定
			if(isSorted) {
				break;
			}
			
		}
		
	}

二分查找:

  将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
public static int bSearch(int[] arrs,int value) {
		//声明索引
		int max = arrs.length-1;
		int min = 0;
		int mid = 0;
		//循环判定
		while(min<=max) {
			mid = (max+min)/2;
			if(arrs[mid]>value) {
				max = mid-1;
			}else if(arrs[mid]<value) {
				min = mid+1;
			}else {
				return mid;
			}
		}
		return -1;
	}
	

面试题:

public static void info(int ... arr) {
		int sum = 0;
		for(int ar:arr) {
			sum+=ar;
		}
		System.out.println(sum);
	}
	
	//可变参 1.5
	public static void info(String str,int ... arr) {
		int sum = 0;
		for(int ar:arr) {
			sum+=ar;
		}
		System.out.println(sum);
	}

可变参数:

  • 提高代码的复用性

  • 简化了开发

  • 降低入参的复杂度

  • 可变参数作为形式参数 一定是在当前形参的最后

  • 可变参数作为形式参数 一定只有一个

  • 可变参数在一定长度上可以代替相同类型 不同个数的 方法重载

tips:

其实.class文件底层还是数组存储。

对于重载方法而言:

  •    1:可变参数最后调
    
  •    2:基本类型 最近最优(byte short int long float double)
    
  •    3:引用类型 最近最优(多个从在方法参数列表中的形式参数存在继承关系,一定调用子类的重载方法) null
    
public class Test05 {
    public static void main(String[] args) {
        //调用该方法会出现什么问题
        //fun("",null);
    	invoke(null,1);//会调用哪个方法呢? 
    }

    public static void fun(String str,String ... strs){
        System.out.println("str = [" + str + "], strs = [" + strs + "]");
    }
    public static void fun(String str,Integer ... ins){
        System.out.println("str = [" + str + "], ins = [" + ins + "]");
    }
    
    static void invoke(Object obj,Object ... args ){
        System.out.println("obj = [" + obj + "], args = [" + args + "]");
    }
    static void invoke(String str,Object obj,Object ... args){
        System.out.println("str = [" + str + "], obj = [" + obj + "], args = [" + args + "]");
    }
    
}

异常

定义及处理过程:

不正常就是异常 ,

1:jvm会处理程序中未处理的异常:
a:暂停程序

​ b:报错(异常内容【什么异常 原因描述】 异常行数 )

2:不要让jvm去处理异常

public class Test02 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		System.out.println("请输入第一个数》》》》》");
		
		if(input.hasNextInt()) {
			int num1 = input.nextInt();
			System.out.println("请输入第二个数》》》》》");
			if(input.hasNextInt()) {
				int num2 = input.nextInt();
				if(num2!=0) {
					int result = num1/num2;
					System.out.println(num1+"/"+num2+"="+result);
				}else {
					System.out.println("您输入除数为0 》》》");
				}
			}else {
				System.out.println("您输入的数据有误》》》");
			}
		}else {
			
			System.out.println("您输入的数据有误》》》");
			}
		
	}
}

tips:

处理异常

  •     通过大量的if判定来确保程序没有异常,但是用户是万恶之源,
    
  •     永远无法知晓他到底会做什么。
    
  •     编写的判定逻辑不可能将所有情况都囊括进去,程序在执行过程中如果出现问题,出现异常
    
  •     此时由于没有异常处理方案,导致交由jvm处理,jvm处理方式就是 暂停程序 报错。-》不能忍受的。
    
  •     通过if判定完成异常校验: 代码臃肿、不利于阅读以及维护
    

处理方案:

java提供了完整的异常处理方案,可以帮助我们在编写代码过程中,处理程序中的异常信息。

  •    try catch finally throws throw
    
try-catch:

java中的异常机制:

语法结构:

  • try{
  • //有可能出现异常的代码块
  • }catch(声明异常){
  • 异常解决办法
  • }
public static void main(String[] args) {
		
		
		try {
			System.out.println(1/0);//new ArithmeticException(); 出异常ArithmeticException
		}catch(Exception e) {//Exception e =  new ArithmeticException();
			//记录异常信息
			System.out.println("输入的数据有误。。。。。");
			//错误信息记录下来
		}
		System.out.println("我是try-catch外的代码");
		}
}		
tips:

执行顺序:

  • 1:执行try块中的内容

  • 2:如果try块中内容出现异常,执行catch块

  • 3:匹配catch中声明的异常信息 ,如果匹配上,则执行catch中的代码

  • 4:继续执行后续代码

  • 5:如果catch中的异常信息没有匹配到 那么此时交由jvm处理该异常

    ​ catch:中的类型一定要注意 要能够捕获到try快中实际出现的异常信息

    ​ 如果忘记了具体的异常信息可以通过使用

  • Exception去捕获异常信息

  • 不要再catch块中做业务逻辑判定

try-多重catch

语法结构:

  •  try{
    
  •  //可能出现异常的代码段
    
  •  }catch(异常1){
    
  •  //异常 的解决办法
    
  •  }catch(异常2){
    
  •  //异常 的解决办法
    
  •  }.......{
    
  •  }
    
常见对象的常见方法:

异常对象的常见方法:

  •    toString: 当前异常类型以及原因描述
    
  •    printStackTrace: 打印堆栈信息 异常类型以及原因描述 异常位置
    
  •    getMessage:异常原因
    
public class Test04 {
	public static void main(String[] args) {
		
		Scanner input = new Scanner(System.in);
		System.out.println("请输入第一个数》》》》》");
		
		
		try {
			int num1 = input.nextInt();//InputMismatch
			
			System.out.println("请输入第二个数》》》》》");
			int num2 = input.nextInt();
			
			int result = num1/num2;
			
			System.out.println(num1+"/"+num2+"="+result);
			
		}catch(ArithmeticException e) {
			System.out.println("除数不能为0");
			//System.out.println(e.toString());
			//e.printStackTrace();
			System.out.println(e.getMessage());
		}catch(InputMismatchException e) {
			System.out.println("用户输入有误");
		}catch(Exception e) {
			System.out.println("网络加载问题。。。。");
		}
			
		System.out.println("后续代码。。。");
		
		
	}
}

tips:

try多层catch执行顺序:

  • 1:执行try块 如果出现异常 new出当前异常对象

  • 2:逐一匹配catch中的异常内容

  • 3:如果匹配上 执行对应的catch中的代码 整个try-catch执行结束

  • 4:如果匹配上 jvm去解决当前异常信息

    ​ 注意事项:

  • 1:在多重catch中一般情况下会在最后一个catch语句中编写exception

    ​ 用来捕获可能未被识别的异常信息

  • 2:不要再第一个catch中编写父类异常 屏蔽所有子类异常

try-catch-finally

语法结构:

  • 			try{
    
  • 			//可能出现异常的代码
    
  • 			}catch(异常1){
    
  • 			//处理办法
    
  • 			}.....{
    
  • 			}finally{
    
  • 			//代码块
    
  • 			关闭资源的代码  
    
  • 			}
    
public class Test05 {
	
	public static void main(String[] args) {
		
		Scanner input = new Scanner(System.in);
		System.out.println("请输入第一个数》》》》》");
		try {
			int num1 = input.nextInt();
			
			System.out.println("请输入第二个数》》》》》");
			//input.close();
			int num2 = input.nextInt();////new IllegalStateException 
		    int result = num1/num2;
			
			System.out.println(num1+"/"+num2+"="+result);
			input.close();
			
		}catch(InputMismatchException e) {
			System.out.println("输入有误");
		}catch(ArithmeticException e) {
			System.out.println("除数不能为0");
		}catch(Exception e) {//Exception e = new IllegalStateException 
			System.out.println("网络加载有误。。");
		}finally {
			// 一定会被执行
			System.out.println("我是finally块中的代码");
			input.close();
		}
		System.out.println("后续代码。。。。");
	}
}
测试如何让finally不执行
public class Test06 {
	public static void main(String[] args) {
		System.out.println(test());
	}
	public  static  int  test() {
		Scanner input = new Scanner(System.in);
		System.out.println("请输入第一个数》》》》》");
		try {
			int num1 = input.nextInt();
			System.out.println("请输入第二个数》》》》》");
			int num2 = input.nextInt();////new IllegalStateException 
			int result = num1/num2;
			System.out.println(num1+"/"+num2+"="+result);
			System.exit(0);
			return 1;
		}catch(InputMismatchException e) {
			System.out.println("输入有误");
		}catch(ArithmeticException e) {
			System.out.println("除数不能为0");
		}catch(Exception e) {
			System.out.println("网络加载有误。。");
		}finally {
			System.out.println("我是finally");
			input.close();
		}
		return 2;
	}
}
tips:

retrun 语句不会让finally不执行

  • finally先于return语句执行

  • 代码中存在System.exit() 可以让finally不执行 但是一般不这么干

    ​ 执行顺序:

  • 1:执行try块 如果出现异常 new出当前异常对象

  • 2:逐一匹配catch中的异常内容

  • 3:如果匹配上 执行对应的catch中的代码

  • 4:如果未匹配上 jvm去解决当前异常信息

  • 5:不论是否匹配成功 都会执行finally中内容

    ​ finally中一般情况下编写关闭资源的操作

jdk1.7之后对于try-catch-finally的改变

可以通过对于流、网络连接对象的创建声明在try的()中,后续无序通过使用finally显式的关闭资源

  • 	try(资源1;资源2.。。。){
    
  • 	//可能出现的异常信息
    
  • 	}catch(异常1){
    
  • 	//解决办法
    
  • 	}。。。。。{
    
  • 	}
    
public class Test07 {
	public static void main(String[] args) {
		try (Scanner input = new Scanner(System.in);
				InputStream is = new FileInputStream(new File(""))){
			System.out.println("请输入第一个数》》》》》");
			int num1 = input.nextInt();
			System.out.println("请输入第二个数》》》》》");
			//input.close();
			int num2 = input.nextInt();////new IllegalStateException 
			int result = num1/num2;
			
			System.out.println(num1+"/"+num2+"="+result);
			input.close();
			
		}catch(InputMismatchException e) {
			System.out.println("输入有误");
		}catch(ArithmeticException e) {
			System.out.println("除数不能为0");
		}catch(Exception e) {//Exception e = new IllegalStateException 
			System.out.println("网络加载有误。。");
		}
		System.out.println("后续代码。。。。");
		
	}
}

异常的机制

throw

​ 1:throw 声明当前代码块中可能存在的异常信息 并且将当前异常信息抛出给调用者。

  • 对于调用者而言 通过try-catch捕获异常

  • 不管当前异常交由jvm解决

    ​ 2:throw会导致当前程序中断掉 后续代码不执行

public class Test09 {
	public static void main(String[] args)  throws FileNotFoundException{
		//创建student对象
		Student stu1 = new Student();
		stu1.setName("张三");
		/*
		 * try { stu1.setAge(-1); }catch(RuntimeException e) {
		 * System.out.println("参数有误"); }
		 */	
		System.out.println(stu1);
		
		info();
		
	}	
	public static void info() throws FileNotFoundException,ArithmeticException{
		//try {
			new FileInputStream(new File(""));
		/*}catch(FileNotFoundException e) {
			System.out.println(e);
		}*/
	}
}

class Student{
	
	private String name;
	private int age;
	
	public Student() {
		// TODO Auto-generated constructor stub
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}
	
	/**
	 * 
	 * @param age
	 * @throws RuntimeException 当前方法对外会抛出异常 如果参数有误
	 */
	public void setAge(int age)  throws FileNotFoundException{
		if(age<0||age>150) {
			throw new FileNotFoundException();//异常中断
		}
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}
throws

throws 在方法外对外抛出某个异常,调用者解决当前异常。

​ main方法中对外抛出的异常全部都交由jvm做。

  • throws抛出异常 是异常解决的一种办法定义在方法的外部 形式参数后 可以抛出多个异常通过","分割
  • throw 定义在方法内部,声明当前方法可能出现的异常信息 可以导致当前程序中断。
  • 一般会将throws和throw在一起使用,throw 声明的异常是检查时异常需要和throws一起使用
  • 但是throws可以单独使用
自定义异常:

1:jdk中提供的异常信息不满足目前的使用

​ 2:如何自定义异常:

  • a:声明一个自定义异常类
  • b:继承Exception
  • c:编写两个构造器 一个空 一个带字符串的构造器
public class Test10 {
	public static void main(String[] args) /* throws AgeException */{
		
		
		User u = new User();
		try {
			u.setAge(-1);
			
		}catch(AgeException e) {
			//System.out.println("年龄有误。。。");
			System.out.println(e.getMessage());
		}
		System.out.println(u);
		
	}
}
class User{
	private int age;
	public User() {
		// TODO Auto-generated constructor stub
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) throws AgeException{
		if(age<0||age>150) {
			throw new AgeException("年龄输入有误");
		}
		this.age = age;
	}
	@Override
	public String toString() {
		return "User [age=" + age + "]";
	}
}

static void main(String[] args) /* throws AgeException */{

	User u = new User();
	try {
		u.setAge(-1);
		
	}catch(AgeException e) {
		//System.out.println("年龄有误。。。");
		System.out.println(e.getMessage());
	}
	System.out.println(u);
	
}

}
class User{
private int age;
public User() {
// TODO Auto-generated constructor stub
}
public int getAge() {
return age;
}
public void setAge(int age) throws AgeException{
if(age<0||age>150) {
throw new AgeException(“年龄输入有误”);
}
this.age = age;
}
@Override
public String toString() {
return “User [age=” + age + “]”;
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值