文章目录
异常处理 - Exception 继承 Throwable
泛型类不能继承Throwable —— 即不能继承所有异常类
java唯一正式的的 错误报告机制 —— 使得构建能够与客户端代码可靠地进行沟通 (包构建者告诉客户端程序员使用包的细节错在哪里,什么原因导致的错误)重要方面: 一旦发生(抛出异常),程序不会沿着正常路径继续跑下去-直接catch里面的语句
原则、初衷: ① 方便程序员处理异常 ② 只有知道如何处理异常情况下才捕获异常
运行时异常:ConcurrentModificationException:多个进程同时修改某个对象、容器
异常情形: 阻止当前的方法或作用域继续执行的问题 - 当前环境无法获得足够信息解决问题
普通问题: 当前环境下能获得足够的信息,总能 解决发生的错误
抛出异常后的顺序: 创建异常对象 → 当前的执行路径被终止 → 弹出异常对象的引用 → 异常处理机制接管程序 → 寻找下一个 合适的地方(异常处理程序) 继续执行 (换一方式运行 或者 继续运行)
异常处理:
- 终止模型: 错误很关键,无法返回异常发生前的位置,一旦抛出异常,就不能继续执行
- 恢复模型: 处理被修正,重新调用方法,不能抛出异常 → 很少使用,会增加程序耦合度
1 public static void main(String[] args) {
2 try {
3 try {
4 throw OneException();
5 }catch(Exception e) { //接受OneException的异常
6 println(e);
7 }finally {
8 throw TwoException();
9 }
10 }catch(Exception e) { //接收TwoException的异常
11 println(e);
12 } //解决异常覆盖问题最好是内部有接收将被覆盖异常的catch语句,先catch在finallypa抛出新的异常。 - 如果不处理内部抛出的异常则会被 ”吞咽异常“
13 }
- try: 一个try语句最多只能抛出一个异常,即使里面有多个异常抛出来,也会被最迟调用的所覆盖。(丢失异常) —— catch时如没有定义Exception 则须定义try里面所有未处理的异常,也可以索性用try(Exception)一次性接收
- throw: 简单的看成函数的 return返回引用 → 返回一个异常对象 通常异常对象的类型(class名) 是仅有的有意义的信息
- throws(检查异常): 可以声明方法会抛出异常,不过方法本身可以不发出异常 ——特殊:可以直接抛出RuntimeException及其子类的异常而无需声明更无需try-catch
- 方法异常(throws)声明的是父类Exception: 必须catch要有Exception选项,catch(Exception)的话会全部接受继承与它的子类,需放置最后
- finally(最后执行): 先执行内部的finally,在执行更高一级的finally
class SimpleException extends Exception{}
public class Test {
public static int cout() throws SimpleException { //这里声明了有错误抛出就必须抛出错误 —— 异常说明“throws"
System.out.println("我抛出了一个错误");
throw new SimpleException(); //抛出一个声明的错误
}
public static void main(String[] args) {
try { //运行有声明错误的方法
cout()
}catch(SimpleException se) { //捕获错误 中括号内可以抛出一个自身异常,不过得到StackTrace抛出点不会更新,需手动更新即se对象本身
System.out.println("我捕获到了这个错误");
}finally { //只要try 一般情况都会最后运行finally语句 -先执行内部的finally在执行更高一级外部的finally
System.out.println("ending");
}
}
]
方法的使用
-
printStackTrace() 、 getStackTrace() : 得到的是抛出异常点的信息(数组栈,最后一个元素为第一个方法的调用点)
-
fillInStackTrace() : 更新堆栈的信息
-
Throwable(Throw cause) - 异常链,保准cause的信息: 这里的构造器中的cause传递的只是 cause.toString():cause.getClass() + cause.getMessage()
-
initCause(异常a): 在异常里面保存a异常的信息 —— 异常链
- Exception、Error、RuntimeException有构造器可以异常链
-
getCause(): 得到当前异常之前接收到的之前那个异常
public static void main() {
ArrayIndexOutOfBoundsException aid = new ArrayIndexOutOfBoundsException("超出范围");
Exception e = new Exception(aid);
Exception arrayException = (Exception))e.getCause(); //注意这里的arrayException 与 aid是一模一样的
异常方法的重写(继承方法重写、接口实现的方法)
- 子类的构造函数 声明需与父类相同,想增加也可以 子类构造函数异常声明 = 父类声明异常 + 自定义声明异常
- 父类普通方法无声明异常,则子类的普通方法也绝对不可以声明异常
- 父类普通方法有声明异常,则子列可以声明异常为其父类异常的子集 子类普通函数异常声明 = 父类声明异常的子集(可为空)
- 子类即继承了父类也实现了接口的同名同参方法,则重写的子类同名方法异常以父类为准,不过实现的子类方法必须满足父类与接口的异常声明
class Father {
Father() throws FourException {}
void cout one() throws OneException {}
void cout two{}
}
interface Elder {
void cout one() throws TwoException;
void cout three() throws ThreeException;
}
public class Son extends Father implements Elder {
Son() throws FourException,FiveException {}
public void one() {} //满足接口与父类的要求,访问权限public, 异常声明可为空,也可为 throws TwoException不过要在父类先添加这个声明。
void two() {} //父类无声明,子类也必须无
public void three() throws ThreeException {} //普通子类成员函数异常声明只能少或跟父类一样,但就是不能多。
构造器异常以及清理销毁对象
public static void main(String[] args) {
try {
InputFile in = new InputFile("文件地址");
try {
获取文件信息的操作 // 对于文件的操作
}catch(Exception e) {
不能获取信息后的警告,处理 //不能获取信息的操作
}finally {
in.dispose(); //对文件的操作结束就必须关闭文件,以免浪费资源
}
}catch(Exception e) {
println("构造失败");
}
字符串String
String对象: 具有 只读 的特性 —— 意味任何引用都不可能改变它的值
StringBuilder对象: 可变的序列 —— 不保证同步,一般优于StringBuffer
StringBuffer对象: 可变的序列 —— 线程安全,可同步,故开销大
String的循环等复杂操作: 最好自己构建StringBuilder,减少系统申请太多次的空间。
① String a = "abc";
② String b = new String("abc");
③ String c = "abc" + a;
④ final String d = ""; String e = "abc" + d; //与a相等
①字面量:保存在字符串常量池中,,多个字符串共用这个字符串,返回的是常量池的地址
②new String:在堆中创建新空间,池中创建新空间(如果没有),返回的是堆地址
③字符串变量不能在编译期确定a引用值,故只会分配堆空间创建
④final型的String:编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中
格式化输出
输出有三种: “ \n换行符 ”
- java的 System.out.print/println
- C形式 System.out.printf() —— 需编程员自己加换行
- 仿C形式 System.out.format()
类型转换字符:dxhscbfe
d → decimal(十进制)、 x → hexadecimal(十六进制)、h → hashCode(散列码十六进制)、s → string(字符串)、c → char(字符)、b → boolean(布尔数值)、f → float,double(浮点数十进制)、e → 浮点数科学计数法、
布尔类(Boolean):只要构造函数传实际参数不为null都为 true
format()方法
Formatter(格式化器,翻译器): 把指定的字符串按要求输出
- 构造器参数值: 是格式化字符串的去向,目的地
- format(String, Object…args): 返回格式化后的formatter,然后StirngBuilder.toString回目的地(file、err、out等)
Formatter fm = new Formatter(System.out); // format() 之后直接输出字符串在控制台上
fm.format("%-15.5s","wrqwte"); //直接输出字符了,无须System.out.println(), 不过Formatter() 构造器为空时才需要手动标定目的地
格式化修饰符: String format = “%对齐标志(默认右,“-”左对齐)+ width(占据的空间)+.precision(字符串为长度,浮点数为小数位几数)”
若没有限制字符串长度话, 即使 width < 实际字符串长度, 最后也是显示 实际字符串
System.out.format("%-15.5s","wrqwte");
//输出为:wrqwt //左对齐,一定占据15个字符长度,实际只能输出5个字符
System.out.format("%15.5s","wrqwte");
//输出为: wrqwt // 右对齐一共占据15个字符长度
方法: → *Matcher类
- reset(String) 重设需正则的字符串
- boolean matches() 正则表达式是否能对应全部匹配字符串
- boolean lookingAt() 正则表达式能否匹配字符串的始部分(第一个字符需对应匹配)
- boolean find() 正则表达式是否有字符串的子字符串匹配
- boolean find(int start) 从字符串start位置开始检索字符串的子字符串
- String group() 输出groups[0]正则表达式所匹配的子字符串
- String group(int i) 输出正则表达式匹配的子字符串 groups[[i] 匹配的内容
- Matcher appendReplacement(StringBuffer sb, String) 将匹配的整个字符串复制到sb中
- StringBuffer appendTail(sb) 将Matcher字符串的最后未匹配的加到sb中
String str = "f S ds ftg";
StringBuffer sb = new StringBuffer();
Matcher m = Pattern.compile("(?i)s").matcher(str);
while(m.find())
m.appendReplacement(sb, "匹配")
System.out.println(sb); // output: f 匹配 d匹配
m.appendTail(sb);
System.out.println(sb); // output: f 匹配 d匹配 ftg
正则表达式
字符类与ASCII字符码表
java中用 “\\” 进行转义
?: 前面字符或者括号内的匹配次数 [0,1] 例如:do(es)? → 匹配do,does dos? → 匹配dos,do
+ : 前面字符或者括号内的匹配次数 [1,+∞] 例如:do(es)+ → 匹配does、doeses、doeseses等
✳: 前面字符或者括号内的匹配次数 [0, +∞] → 不包括1次
{ m , n }: 前面字符或者括号内的匹配次数 [m, n] 注:n不写时匹配次数无穷即{m ,},只剩m时为固定匹配次数{m}
\d: 0 - 9数字即十进制数 注:java中须写成:\\d
\w: 匹配数字、字母、下划线中的一个 注:\W 则与之相反
\s: 匹配空白字符
. : 匹配除换行符\n的任何字符
|: ”或“的意思
[a-z && [h,i,j] ] : 实质 [ h,i,j ] 交集 的意思
行的开始(有否定的意思),结束,词(非词)的边界、前一个匹配结束: ^ 、 $ 、\b → \B 、\G
量词
扫描输入
- StringReader、BufferedReader、Scanner(用处很大)、StringTokenizer(基本可以废弃使用)