异常
1.Throwable
可以抛出的。Throwable类是所有异常的顶级父类,所有的异常都具有可抛性。在Java中,able结尾的,一般表示某种能力:
- Serializable:可序列化的。
- Comparable:可比较的。
- Iterable:可迭代的。
- Runnable:可运行的(线程相关)。
- Throwable有两个直接子类:
- Error:一般指虚拟机等出现的问题,一般我们的程序无法处理。如StackOverflowError:堆栈溢出错误
- Exception:异常。包含两大类:
1)、RuntimeException(运行时异常)
2)、CheckedException(编译时异常)
2.RuntimeException
运行时异常
- 1.程序运行的时候报的异常
- 2.可以使用try-catch-finally处理,也可以不处理。
- 3.大部分时候,我们都不会去处理运行时异常。
- try-catch会让可读性变差
- try-catch会让效率变低
- 程序的很多运行时异常是我们程序猿本身的问题
- 运行时异常一般采用if判断条件,增强程序的健壮性
- 4.常见的运行时异常:
- ArithmeticException:算术运算异常
- NullPointerException:空指针异常
- StringIndexOutOfBoundsException:字符串下标越界异常
- ArrayIndexOutOfBoundsException:数组下标越界异常
- ClassCastException:类型转换异常
- NumberFormatException:数字格式化异常
3.CheckedException
检测时异常 编译时异常 非运行时异常
- 1.程序编译的时候报的异常(编译通不过)
- 2.必须使用try-catch-finally来处理(或throws)
异常处理机制
1.throws
抛出异常,扔给调用者来处理。throws并没有真正处理异常,只是把异常往外抛出了,知识骗过了编译器。(消极的异常处理方式)main方法不建议throws。
2.try-catch-finally
捕获异常。
public class TestCatch {
public static void main(String[] args) {
int a= 2;
int b= 0;
try{// 捕获可能有异常的语句
System.out.println(a/b);
}catch(ArithmeticException e){
System.out.println("ArithmeticException
}
}
}
- 当一个语句块可能含有多个异常时,需要catch所有可能异常,就要用到多个catch语句。当要捕获的异常类不存在父子关系时可以任意先后位置;如果有父子关系,子类放上面,父类放下面。
public class TestCatch {
public static void main(String[] args) {
int a= 2;
int b= 0;
String str = new String("av");
String s = "abc";
try{
System.out.println(a/b);
System.out.println(str.charAt(0));
int ni = Integer.parseInt(s);
// RuntimeException是父类,所以将拦截所有异常,下面的两个就执行不到
}catch(RuntimeException e){
System.out.println("ArithmeticException ");
}catch(NullPointerException e){
System.out.println("NullPointerException");
}catch(NumberFormatException e){
System.out.println("NumberFormatException");
}
}
}
- finally
无论如何都会执行的代码,一般用于关闭资源或处理临时文件。
public class TestFinally {
public static void main(String[] args) {
System.out.println("return:"+m1());// return:3
}
public static int m1(){
int a = 2;
int b = 1;
// finally无论如何都会执行,程序流程为:1>5>6 如果将b改为0:1>3>5>6
try {
System.out.println(a/b);// 1
return 1;// 2
} catch(Exception e){
System.out.println(e.toString());// 3
return 2;// 4
} finally{
System.out.println("finally");// 5
return 3;// 6
}
}
}
自定义异常
- 如何自定义异常
- 1.继承自Exception(编译时异常)或RuntimeException(运行时异常),继承不同的异常父类就产生不同的自定义异常。
- 2.提供String做参数的构造,并且调用super(String msg);
- 在要使用自定义异常的地方使用
throw+异常对象
将该异常手动抛出。
public class DrinkNotFoundException extends Exception{// 自定义饮品没有找到异常
public DrinkNotFoundException(String msg){
super(msg);
}
}
// 使用自定义异常
public abstract class Drink {
public final int COFFEE = 1;// 饮品编号
public final int BEER = 2;
public final int MILK = 3;
public abstract void taste();
public static Drink getDrink(int flag)throws DrinkNotFoundException{// 静态工厂返回饮品实例,编译时异常所以要抛出
switch(flag){
case 1:
return new Coffee();
case 2:
return new Beer();
case 3:
return new Milk();
default:
// 抛出饮品没有找到异常
throw new DrinkNotFoundException("对不起,没有您输入的饮品类型!");
}
}
}
// 调用getDrink()方法
public class Test {
public static void main(String[] args) {
try{
Drink a = Drink.getDrink(4);// 4是没有的饮品编号,将抛出异常
a.taste();// 打印饮品口味
}catch(DrinkNotFoundException e){
e.printStackTrace();// 打印异常堆栈跟踪信息
}
System.out.println("else");
}
}
- 异常的常用方法
- e.getMessage():取得异常的描述信息
【/ by zero】 - e.toString():异常类信息和异常描述信息
【java.lang.ArithmeticException: / by zero】 - e.printStackTrace():打印异常堆栈跟踪信息
【java.lang.ArithmeticException: / by zero
at cn.ucai.day16.TestTryCatch.main(TestTryCatch.java:9)】
- e.getMessage():取得异常的描述信息
String常用方法
- split():根据给定[正则表达式]的匹配拆分此字符串.
String msg = "1001,张三,man";
String[] strArr = msg.split(",");
System.out.println(strArr[0]);// 1001
System.out.println(strArr[1]);// 张三
System.out.println(strArr[2]);// man
String ip = "192.168.3.18";
// split:按照正则表达式
// 如果拆分不出来,考虑转义
String[] ipArr = ip.split("\\.");
System.out.println(Arrays.toString(ipArr));
- replace():替换字符串
String s1 = "abcabcabc";
String s2 = s1.replace("a", "中");
System.out.println(s2);// 中bc中bc中bc
// replaceAll支持正则表达式
String s3 = s1.replaceAll("a", "中");
System.out.println(s3);// 中bc中bc中bc
- contains():是否包含某字符
System.out.println("abc".contains("a"));// true
- toCharArray():返回该字符串对应的字符数组
String s4 = "abcd";
char[] chArr = s4.toCharArray();
System.out.println(Arrays.toString(chArr));//[a, b, c, d]
- toLowerCase()/toUpperCase():转换大小写
System.out.println("AbCd".toLowerCase());// abcd
System.out.println("abcd".toUpperCase());// ABCD
可变的字符串
StringBuilder
& StringBuffer
:用法相同
- StringBuilder:1.5后出现,速度快,单线程执行。目前优先使用。
- StringBuffer: 1.0后出现,速度相对较慢,支持多线程
StringBuilder builder = new StringBuilder();
builder.append("abc");
builder.append(1.0);
builder.append(true);
builder.append(20).append("def").append("123");
System.out.println(builder);// abc1.0true20def123
// StringBuilder 转为String
String result = builder.toString();
System.out.println(result);// abc1.0true20def123
BigDecimal
- 用于小数的精确计算
- 用于大数的计算
BigDecimal bd1 = new BigDecimal("2.6");
BigDecimal bd2 = new BigDecimal("2.0");
double d = bd1.subtract(bd2).doubleValue();
System.out.println(d);// 0.6 如果使用double类型则是0.600...01
System.out.println(Double.MAX_VALUE);// double型最大值
BigDecimal bd3 = new BigDecimal(Double.MAX_VALUE);
BigDecimal bd4 = new BigDecimal(Double.MAX_VALUE);
System.out.println(bd3.add(bd4));// 相加