6.1.2 异常发生后的反应
1.对象创建保留,可能资源信息泄露
2.程序意外终止,导致其他模块无法运行
6.1.3 异常捕获机制
try-catch-finally
语法规则:
try{
//监视器,有可能发生异常的代码
}catch(异常类型 变量){
//捕获器 捕try中代码的对应异常
}catch(异常类型 变量){
}....
finally{
//资源清理块 无条件
注意:
try块不可以单独存在,配合catch,配合finally
一个try可以对应catch,分别处理不同的异常,Exception类型作为最后的扑火的,只能选择一个catch执行
finally可以有也可以没有,只要有finally,语句无条件运行【不管是否发生异常】,即使return,正常运行,除非退出虚拟机。
实例:
public class tewst {
public static void main(String[] args) {
System.out.println("我的代码");
int b=0;
//System.out.println(10/b);
try {
System.out.println(10/b);
int []a = new int[3];
System.out.println(a[2]);
}catch(ArithmeticException e) {
System.err.println("数学问题");
//return;
System.exit(0);
}catch(ArrayIndexOutOfBoundsException e) {
System.err.println("发生了越界问题");
}catch(Exception e) {
System.out.println("执行异常");
}finally {
System.out.println("无条件运行");
}
System.out.println("另一个人的代码");
}
}
执行顺须:
6.1.5 异常抛出
异常抛出,不手动捕获异常,方法将异常抛出。
throws 方法向外抛出异常,抛给别人解决 抛出的是异常类型
throw 手动构(创)造异常,引起注意(警示) 抛出的是对象
throws:
控制权限 【修饰符】 返回值类型 方法名(参数) throws 异常类型1,异常类型2,.....{
}
注意:
1.方法向外抛出异常,抛给方法的调用位置
2.调用者不解决,可以继续向外抛出,最终抛给虚拟机(不建议)
3.编译异常问题居多
4.子类在覆盖父类的方法时,不能抛出比父类更大的异常类型
public class A {
public void test() throws ArrayIndexOutOfBoundsException{
}
}
class B extends A{
//错误 Exception > ArrayIndexOutOfBoundsException
public void test() throws Exception{
}
}
throw :
手动创建一个异常,扔出去,用于某些Java中没有对应异常类型,如年龄问题、金额.....
语法规则:
//1.创建一个异常对象
Exception e = new Exception();
Exception e = new Exception("异常信息提示");
//2.抛出
throw e;
例子:
public class Test3 {
//检测年龄合法
public static void checkAge(int age) throws Exception{
if(age<0) {
Exception e = new Exception("年龄非法使用");
AgeException e1 =new AgeException("年龄非法使用,无法继续");
throw e1;
}
if(age >= 18) {
System.out.println("成年");
}else {
System.out.println("未成年");
}
}
public static void main(String[] args) {
try {
checkAge(-7);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace(); //是打印异常的堆栈信息,指明错误原因
}
System.out.println("检测完毕");
}
}
class AgeException extends Exception{
public AgeException() {
super();
// TODO Auto-generated constructor stub
}
public AgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public AgeException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
}
练习:
父类 River 河流
属性:
当前水位 waterLine
警戒水位 warnningLine
测试水位方法 flow() : 当前水位超出警戒水位10米 抛出异常【手动抛出】 , 内部不解决 ,水位正常,打印 河水静静流
子类:
长江 覆盖方法 5米 否则 : 孤帆远影碧空尽 未见长江天际流
黄河 覆盖方法 9米 否则: 白日依山尽 黄河入海流
gc类
行为 : 监视河流
watch(River r){
//捕获 try-catch-finally
}
public class River {
private double waterLine;
private double warnningLine;
public double getWaterLine() {
return waterLine;
}
public void setWaterLine(double waterLine) {
this.waterLine = waterLine;
}
public double getWarnningLine() {
return warnningLine;
}
public void setWarnningLine(double warnningLine) {
this.warnningLine = warnningLine;
}
public River() {
super();
}
public River(double waterLine, double warnningLine) {
super();
this.waterLine = waterLine;
this.warnningLine = warnningLine;
}
public void flow() throws Exception {
if(waterLine-warnningLine>=10) {
Exception e = new Exception("当前水位超出警戒水位10米");
throw e;
}else {
System.out.println("河水静静流");
}
}
}
public class LongRiver extends River {
public LongRiver(double waterLine, double warnningLine){
super(waterLine, warnningLine);
// TODO Auto-generated constructor stub
}
public LongRiver() {
super();
// TODO Auto-generated constructor stub
}
public void flow() throws Exception{
if(getWaterLine()-getWarnningLine()>=5) {
Exception e = new Exception("当前水位超出警戒水位5米");
throw e;
}else {
System.out.println(" 孤帆远影碧空尽 未见长江天际流");
}
}
}
class YellowRiver extends River{
public YellowRiver() {
super();
// TODO Auto-generated constructor stub
}
public YellowRiver(double waterLine, double warnningLine){
super(waterLine, warnningLine);
// TODO Auto-generated constructor stub
}
public void flow() throws Exception{
if(getWaterLine()-getWarnningLine()>=9) {
Exception e = new Exception("当前水位超出警戒水位9米");
throw e;
}else {
System.out.println(" 白日依山尽 黄河入海流");
}
}
}
//Gc类
public class Gc {
public void watch(River r) {
try {
r.flow();
}catch(Exception e) {
e.printStackTrace();
}finally {
System.out.println("结束");
}
}
}
public class Test {
public static void main(String[] args) {
/* Gc gc =new Gc();
River r1 = new YellowRiver();
r1.setWarnningLine(20);
r1.setWaterLine(5);
gc.watch(r1);
River r2 = new LongRiver();
gc.watch(r2);
River r3 = new River();
gc.watch(r3);
*/
new Gc().watch(new LongRiver(20,10));
}
}
6.1.6 自定义异常
public class AgeException extends Exception {
//自定义年龄异常,引起注意
}
填空:
1.异常是指发生在(编译/运行性)时的错误
2.所有异常类的根父类是( Exception )
3.处理异常需要使用的关键字包括(try ),( catch ),( finally ),( throws ),( throw ),其中,会出现异常的代码放置在(try )块中,
处理异常的代码放置在(catch )块中,该块需要一个(异常类)作为参数,而无论是否发生了异常,都会执行的代码放置在( finally )块中。
4.用来指明该方法可能会抛出异常时,需要在定义方法时,在方法说明的后边使用( throws )关键字,该关键字后边跟(异常类型);
用来手动抛出一个异常时,使用( throw )关键字,该关键字后边跟( 异常对象 )
5.自定义的异常类需要继承(Throwable/Exception)类或其子类
6.2 String 【java.lang】
public final class String extends Object implements Serializable, Comparable<String>, CharSequence{
}
6.2.1 String 类型的特点
String 引用数据类型,特殊的。 字符串定长的,长度固定。
字符串变量对象:
栈 字符串引用
堆 实例化
字符串常量对象:
字符串常量池
//2个对象
String s = "abc";
String s2 = "abcd";
//一共创建对象个数 2个
String s = "abc";
String s3 = new String("abc");
//一共创建对象个数 3个
String s = "abcd";
String s3 = new String("abc");
6.2.2 字符串的创建
String str = "abc";
new String();
new String(String str);
new String(char[]);
new String(StringBuilder builder);
public class TestString2 {
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = new String(new char[] {'a','b','c'});
String s3 = "abc";
String s4 = "abc";
System.out.println(s1 == s2);//f
System.out.println(s1 == s3);//f
System.out.println(s3 == s4);//t
}
}
6.2.3 String的方法
字符串由下标,从0开始,下标取值范围【0-s.length-1】
方法名 | 用途 | 参数 | 返回值 |
char charAt(int) | 获取字符串中某个字符 | 下标 | 对应位置的字符 |
int length() | 字符串长度 | 无 | 字符串长度 |
char[] toCharArray() | 字符串转化数组 | 无 | 字符数组 |
int IndexOf(String) | 查找字符串 | 返回第一次参 出现的下标,没有返回-1 | |
int lastIndexOf(String) | 查找字符串 | 返回最后一次参 出现的下标,没有返回-1 | |
String substring(int begin) | 截取新串 | 起始位置 | 从起始位置截取到最后 |
String substring(int begin,int end) | 截取新串 | 起始位置--终止位置 | 从起始位置截取到终止为止-1 |
String replace(old,new) | 替换 | old替换成new | 替换后新串 |
charAt()的练习:
查找字符,传入字符,判断是否存在,返回下标
public class StrTest {
public static void main(String[] args) {
String str = "abcdef";
System.out.println(find(str, 'b'));
}
public static int find(String str,char c) {
for(int i=0;i<str.length();i++) {
if(str.charAt(i)== c) {
return i;
}
}
return -1 ;
}
}
方法:传入字符串的返回逆置串 abcde edcba
public class StrTest {
public static void main(String[] args) {
String str = "abcdef";
//System.out.println(find(str, 'b'));
System.out.println(reverse(str));
}
public static String reverse (String str) {
String s="";
for(int i=str.length()-1;i>=0;i--) {
s+=str.charAt(i);
}
return s;
}
//第二种方法
public static String reverse2 (String str) {
//排序方法
char []c =str.toCharArray();
for(int i=0;i<c.length/2;i++) {
char a = c[i];
c[i] = c[c.length-1-i]; //最后一位
c[c.length-1-i] = a;
}
return new String(c);
}
}
字符串常用的几种方法
1. 截取
2. 查找
3. 比较
4. 替换
5. 分割
IndexOf(String)的例子:
String[] pills = {"去痛片","阿莫西林","阿斯匹林"};
Scanner sc = new Scanner(System.in);
System.out.println("请输入关键字");
String key = sc.next();
//打印所有包含关键词的
for (int i = 0; i < pills.length; i++) {
if(pills[i].indexOf(key) != -1) {
System.out.println(pills[i]);
}
}
substring(int begin,int end)的练习:
public class strdd {
public static void main(String[] args) {
String str = "abcdef";
System.out.println(str.substring(2));
System.out.println(str.substring(2, 4));
System.out.println(str);
}
}
String replace(old,new)的练习:
public class t {
//定义一个字符串,返回后三位
public static void main(String[] args) {
String str = "abcdefg";
if(str.length()<=3)
System.out.println(str);
else
System.out.println(str.substring(str.length()-3));
//替换
System.out.println(str.replace("a", "*"));
getMax(str);
}
//替换实现实现字符个数
public static void getMax(String str) {
int l1 =str.length();
for(int i=0;i<str.length();i++) {
int l2=str.replace(str.charAt(i)+"","").length();
int count =l1-l2;
System.out.println(str.charAt(i)+","+count);
}
}
}