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