Java-异常-异常处理5种典型应用

Java-异常-5种典型应用


目录




内容

1、可能抛异常的静态方法给静态变量赋值

  • 代码

      package exception.exception;
    
      public class TestException2 {
      	public static void main(String[] args) {
      		System.out.println(LuckNumber.a);
      	}
      }
    
      // 幸运数字
      class LuckNumber {
      	static int a = getA(); // 此处报错,未处理异常
    
      	//随机0-9(排除2和4,4不吉利,2骂人)
      	static int getA() throws Exception {
      		int x = (int)Math.random();
      		if( x == 2 || x == 4) 
      			throw new Exception("数字不吉利");
      		return x;
      	}
      }
    
  • 问题:如上代码所示,在static int a = getA()处又错误,未处理异常,怎么办呢?

    • throws 只能用在方法签名后
    • try…catch 不能用在类体中
  • 解决方案

  把静态变量声明和赋值分离开,赋值操作在静态代码块中完成,代码如下所示:

package exception.exception;

public class TestException2 {
	public static void main(String[] args) {
		System.out.println(LuckNumber.a);
	}
}

// 幸运数字
class LuckNumber {
	static int a;
	static {
		try {
			a = getA();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	//随机0-9(排除2和4,4不吉利,2骂人)
	static int getA() throws Exception {
		int x = (int)(Math.random() * 10);
		if( x == 2 || x == 4) 
			throw new Exception("数字不吉利");
		return x;
	}
}
  • 测试结果:
    • 正常

        7
      
    • 异常

        java.lang.Exception: 数字不吉利
        	at exception.exception.LuckNumber.getA(TestException2.java:23)
        	at exception.exception.LuckNumber.<clinit>(TestException2.java:14)
        	at exception.exception.TestException2.main(TestException2.java:5)
        0
      

2、继承中的方法异常抛出问题

  • 代码

      package exception.exception;
    
      public class TestException3 {
      	public static void main(String[] args) {
      		Father f = new Father();
      		Son s = new Son();
      		f.test();
      		s.test();
      	}
      }
    
      class Father {
      	public void test() {
      		System.out.println("父类test方法");
      	}
      }
    
      class Son extends Father {
    
      	@Override
      	public void test() throws ArithmeticException, NullPointerException{
      		System.out.println("子类test方法");
      	}
      }
    
  • 问题:上述代码能正常运行吗?(不出异常)

    • 之前学习继承的时候,我们知道其中方法继承,子类继承自父类的方法,抛出的方法类型必须和父类相同或者是父类异常的子类
    • 这样想难道它不应该报错吗?
  • 解析

  事实上,自JDK7.0开始,所有方法签名之后默认抛出RuntimeException运行时异常,不需要显示指定。我们上面子类方法抛出的都是RuntimeException的子类,所以和我们之前学习并不违背。

3、finally中try…catch嵌套问题

  • 现实需求:上小学的时候,我们喝热水。统一都是水房内大锅炉烧开,水房外一排水龙头,凭水票打水。那么冬天的时候呢,一般会提前把水管内凉水放一放。问题来了,现在水龙头开着,需要关闭,但是因为各种原因,某些水龙头可能关不上了(比如,水龙头滑丝了等等),出异常了,那么我们应该试着关闭其他的水龙头。

  • 代码

      package exception.exception;
    
      public class TestException4 {
      	public static void main(String[] args) {
      		// 假设有3个水龙头
      		Switch s1 = new Switch();
      		Switch s2 = new Switch();
      		Switch s3 = new Switch();
    
      		// 怎么实现不管其中任意一个能不能关闭,都要尝试去关闭其他水龙头呢
      	}
      }
    
      // 开关类
      class Switch {
      	// 模拟关闭水龙头
      	public void close() throws Exception{
      		int x = (int)(Math.random() * 10);
      		if( x == 2 || x == 4) 
      			throw new Exception("水龙头关不上了");
      	}
      }
    
  • 解决方案

  这里我们就要用到finally代码块,并且嵌套try…catch,代码如下:

package exception.exception;

public class TestException4 {
	public static void main(String[] args) {
		// 假设有3个水龙头
		Switch s1 = new Switch();
		Switch s2 = new Switch();
		Switch s3 = new Switch();

		// 怎么实现不管其中任意一个能不能关闭,都要尝试去关闭其他水龙头呢
		try {
			s1.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				s2.close();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					s3.close();
				} catch (Exception e) {
					e.printStackTrace();
				} 
			}
		}
	}
}

// 开关类
class Switch {
	// 模拟关闭水龙头
	public void close() throws Exception{
		int x = (int)(Math.random() * 10);
		if( x == 2 || x == 4) 
			throw new Exception("水龙头关不上了");
		System.out.println("水龙头关上了");
	}
}
  • 测试结果
    • 正常

        水龙头关上了
        水龙头关上了
        水龙头关上了
      
    • 异常

        java.lang.Exception: 水龙头关不上了
        at exception.exception.Switch.close(TestException4.java:37)
        at exception.exception.TestException4.main(TestException4.java:12)
        水龙头关上了
        水龙头关上了
      

4、变量需要在try…catch代码块和代码块之后使用问题

  • 文件复制:把E:\a.txt复制为F:\b.txt

  • 代码

      package exception.exception;
    
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.io.IOException;
    
      public class TestExeception6 {
      	public static void main(String[] args) {
    
      		try {
      			FileInputStream fis = new FileInputStream("e:\\a.txt");
      			FileOutputStream fos = new FileOutputStream("f:\\b.txt");
    
      			byte[] b = new byte[1024];
      			int len;
      			while((len = fis.read(b)) != -1) {
      				fos.write(b, 0, len);
      			}
      		} catch(Exception e) {
      			e.printStackTrace();
      		} finally {
      			try {
      				fos.close();
      			} catch (IOException e) {
      				e.printStackTrace();
      			} finally {
      				try {
      					fis.close();
      				} catch (IOException e) {
      					e.printStackTrace();
      				}
      			}
      		}
      		System.out.println("文件复制完成!");
      	}
      }
    
  • 问题:上面代码在finally代码块中,fis,fos未声明错误

  • 解决

      package exception.exception;
    
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.io.IOException;
    
      public class TestExeception6 {
      	public static void main(String[] args) {
      		FileInputStream fis = null;
      		FileOutputStream fos = null;
      		try {
      			fis = new FileInputStream("e:\\a.txt");
      			fos = new FileOutputStream("f:\\b.txt");
    
      			byte[] b = new byte[1024];
      			int len;
      			while((len = fis.read(b)) != -1) {
      				fos.write(b, 0, len);
      			}
      		} catch(Exception e) {
      			e.printStackTrace();
      		} finally {
      			try {
      				fos.close();
      			} catch (IOException e) {
      				e.printStackTrace();
      			} finally {
      				try {
      					fis.close();
      				} catch (IOException e) {
      					e.printStackTrace();
      				}
      			}
      		}
      		System.out.println("文件复制完成!");
      	}
      }
    

  把声明和赋值分离开,声明部分放在try…catch 之前,扩大变量的作用域。

5、try…catch灵活运用

  • 问题:判断一个字符串中是否为纯数字
  • 解决
    • 传统

        public class TestException5 {
        	public static void main(String[] args) {
        		String str = "3222323x";
        		System.out.println(isDigit1(str));
        	}
      
        	public static boolean isDigit1(String str) {
        		char[] chars = str.toCharArray();
        		for(char x: chars) {
        			if(!Character.isDigit(x))
        				return false;
        		}
        		return true;
        	}
        }
      

      测试结果:

        “2342423" ---- > true
        "23232x" --------> false
      
    • try…catch

        	public class TestException5 {
        	public static void main(String[] args) {
        		String str = "3222323x";
        		System.out.println(isDigit2(str));
        	}
      
        	public static boolean isDigit2(String str) {
        		try {
        			Integer.parseInt(str);
        			return true;
        		}catch(Exception e) {
        			e.printStackTrace();
        			return false;
        		}
        	}
        }
      

后记

本项目为参考某马视频开发,相关视频及配套资料可自行度娘或者联系本人。上面为自己编写的开发文档,持续更新。欢迎交流,本人QQ:806797785

前端项目源代码地址:https://gitee.com/gaogzhen/vue-leyou
    后端JAVA源代码地址:https://gitee.com/gaogzhen/JAVA

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章