异常处理和String类
1、异常处理
1.1 Exception 的两种处理方式概述
这两种方式就是Java中处理异常的方式
【捕获】 有能力处理你就捕获,自己的问题你就捕获
【抛出】 没有办法处理,或者不是自己的问题,和自己无关,因别人导致的错误,抛出
1.2 捕捉异常
1.2.1 基本格式
格式:
try {
// 有可能出现问题的代码,存在一定隐患的代码
} catch (异常类型) {
// 对应当前异常类型的处理方式
// 【因为技术所限,我们只能sout 或者 printStackTrace 后期我们会使用
日志log】
}
package com.qfedu.a_exception;
public class Demo1 {
public static void main(String[] args) {
int num1 = 0;
int num2 = 20;
int ret = 0;
/*
* num2 / num1 是存在一定的隐患的,如果num1保存的数据是0,
* 这里会出现一个算术异常
*/
try {
// 有可能出现异常的代码
ret = num2 / num1;
} catch (ArithmeticException e) {
/*
* ArithmeticException 算术异常,catch块中捕获对应异常
* catch大括号内是对应的处理方式,现在只能展示效果
*/
e.printStackTrace();
}
System.out.println(ret);
/*
* java.lang.ArithmeticException: / by zero
* at com.qfedu.a_exception.Demo1.main(Demo1.java:16)
* 0
*/
}
}
1.2.2 细节问题和注意事项
1. 代码中出现异常,JVM会终止代码运行,如果使用try catch捕获处理异常,JVM会认为当前代码中不存在异常,可以继续运行。
2. 在try大括号内或者catch大括号内都是局部变量,处理操作数据时小心谨慎。
3. try - catch捕获处理异常,可以处理多种异常情况!!!而且建议异常处理分门别类,对症下药
4. 代码中存在多种隐患,存在多个异常情况,try - catch捕获有且只能处理第一个出现异常的代码,因为JVM从异常代码开始直接进入异常捕获阶段
5. Exception作为Java中所有异常的超类,在捕获异常处理时如果直接使用Exception进行捕获处理,无法做到异常对症下药操作。
6. Exception可以作为try - catch 最后一个,用于处理其他异常捕获之后没有对症方式遗留问题。[不多见]
1.3 跳出异常
1.3.1 基本格式
关键字:
throw
在方法内特定条件下抛出指定异常
throws
在【方法声明】位置,告知调用者,当前方法有哪些异常抛出
用于处理非当前方法操作问题,导致出现的异常,一般情况下是用于处理方法运行过程中因为参数传入,参数处理,运算结果导致的问题,抛出异常。
throw是一个高级的参数合法性判断!!!
/*
* throws 关键字在方法声明位置告知当前方法的调用者,这里存在异常信息
*/
/**
* 测试方法
*
* @param num1 int类型参数
* @param num2 int类型参数
* @throws ArithmeticException 如果除数为0,当前方法抛出算术异常
*/
public static void test(int num1, int num2) throws ArithmeticException {
/*
参数合法性判断 之前的方式 low
if (0 == num2) {
System.out.println("你个瘪犊子...坑我");
System.exit(0);
}
*/
// 参数合法性判断,如果num2 为0, 这里存在隐患
if (0 == num2) {
/*
* 存在异常,这里创建一个异常对象抛出,这里构造方法中
* 存在无参数构造方法和有参数构造方法
* 无参数构造方法异常信息为null
* 有参数构造方法可以传入一个String类型数据,异常信息为指定字符串内容
*/
throw new ArithmeticException("除数不能为0");
}
// 如果num2的值为0,num1 / num2 操作是存在隐患的,有问题的
int ret = num1 / num2;
System.out.println(ret);
}
1.3.2 细节问题和注意事项
1. 代码如果运行到throw抛出异常,之后的代码不再运行,之后的代码是成为无参触及代码
2. 代码中存在多种隐患,按照隐含的情况,分门别类处理,不能在同一个条件内抛出两个异常。并且在方法的声明位置,throws之后,不同的异常,使用逗号隔开
3. 当调用带有异常抛出的方法时,对于方法抛出的异常,有两种处理方式,可以捕获处理,也可以抛出处理。
1.4 抛出处理和捕获处理选择
情况分析:
询指定路径指定名字的文件,存在的异常处理分析过程。
1.5 异常分类
运行时异常:
RuntimeException 代码运行过程中出现的异常,没有强制处理的必要性
ArrayIndexOutOfBoundsException 数组下标越界异常
NullPointerException 空指针异常
ArithmeticException 算术异常
运行时异常不强制要求捕获和抛出!!!
JVM会处理RuntimeException,也就是告知异常的前因后果!!!
其他异常:
强制要求处理,不管是捕获处理,还是抛出处理,都需要进行操作。
如果未处理!!!直接报错!!!
IDE工具的快速修复
Eclipse Ctrl + 1
IDEA Alt + Enter
1.6 自定义异常
自定义单身狗异常
PFSP
private final static Person
我比较习惯这个顺序 代码中常见的也是这个顺序
自定义异常格式:
class MyException extends Exception {
// 无参数构造方法
public MyException() {}
// 有参数构造方法,且参数数据类型为String类型
public MyException(String message) {
super(message);
}
}
【注意】
Eclipse会提示要求完成一个ID号,可以忽略,存在一个警告,不用管。
package com.qfedu.a_exception;
/*
* 忽略黄色警告!!!
*/
/**
* 自定义异常,单身狗异常
*
* @author Anonymous
*
*/
public class SingleDogException extends Exception {
/**
* 无参数构造方法
*/
public SingleDogException() {}
/**
* 带有参数的构造方法,需要的参数类型是String类型
*
* @param message 异常信息内容
*/
public SingleDogException(String message) {
/*
* 通过super关键字调用父类的参数为String类型构造方法
*/
super(message);
}
}
package com.qfedu.a_exception;
public class Demo4 {
public static void main(String[] args) throws SingleDogException {
try {
buyOneFreeOne(false);
} catch (SingleDogException e) {
// TODO Auto-generated catch block
System.out.println("两只黄鹂鸣翠柳,你还是个单身狗");
}
buyOneFreeOne(true);
}
/**
* 买一送一方法,如果有女朋友满足要求,如果没有不满足要求
*
* @param hasGirlFriend boolean类型数据,判断是否有女朋友
* @throws SingleDogException SingleDog 单身狗异常
*/
public static void buyOneFreeOne(boolean hasGirlFriend) throws SingleDogException {
if (false == hasGirlFriend) { // !hasGirlFriend
// throw 抛出一个异常对象 SingleDogException 自定义异常类
throw new SingleDogException("路见不平一声吼,你还没有女朋友");
}
System.out.println("3RMB 甜筒 买一送一");
}
}
1.7 异常处理总结
1. 异常存在的必要性,代码中使用的数据,大多数来源于用户,用户传入数据是一个非常不可靠的情况!!!存在一定错误意识,反馈机制和处理机制。
2. 异常处理方式
捕获
抛出
要根据使用情况,操作方式,反馈形式来选择对应的处理方式。
3. 自定义异常,了解异常的构造,基本上在开发中用到自定义异常的情况不多见。但是要了解关于异常信息保存的方式。
2、String类
2.1 字符串类型概述
又爱又恨!!!
爱:
字符串基本上就是数据的保存,传输,处理非常重要的一种手段。
恨:
解析过程非常烦人,需要掌握熟记很多方法,同时需要有一定的技巧和灵性
String字符串类型是Java中引用数据类型,并且String类型是使用final修饰,没有自己的子类。
字符串的存储也是非常个性的一件事情,分两种情况,
一种是在内存的数据区
一种是在内存的堆区
字符串是一个常量!!!
字符串确定之后无法修改!!!
2.2 字符串内存分析和equals方法
package com.qfedu.b_string;
/*
* 字符串常量分析
*/
public class Demo1 {
public static void main(String[] args) {
String str1 = "烤羊排";
String str2 = "烤羊排";
String str3 = new String("烤羊排");
String str4 = new String(str1);
/*
* tfff
* == 等于判断是比较两个变量中保存的数据是否一致
* String str1 str2 str3 str4 都是引用数据类型的变量,也就是==判断比较的是
* str1 ~ str4 中保存的空间首地址
*/
System.out.println("str1 == str2 : " + (str1 == str2)); // true
System.out.println("str2 == str3 : " + (str2 == str3)); // false
System.out.println("str3 == str4 : " + (str3 == str4)); // false
System.out.println("str4 == str1 : " + (str4 == str1)); // false
System.out.println("----------------------------------------");
/*
* 字符串如何比较是否一致???
*
* Java中规定,字符串比较要求采用equals方法来完成,并且使用的equals方法是String类
* 重写Object类内的方法,比较方式是比较字符串内容。
*/
System.out.println("str1.equals(str2) : " + str1.equals(str2)); // true
System.out.println("str2.equals(str3) : " + str2.equals(str3)); // true
System.out.println("str3.equals(str4) : " + str3.equals(str4)); // true
System.out.println("str4.equals(str1) : " + str4.equals(str1)); // true
}
}
2.3 获取方法
int length();
获取字符串的长度
char charAt(int index);
从字符串中获取对应下标位置的字符,(存在下标越界问题)
int indexOf(char ch);
找出指定字符在当前字符串中的下标位置
"ABCDEFGABCDEFG"
查询 'E' ==> result 4
int indexOf(String str);
找出指定字符串在当前字符串中的下标位置
"ABCDEFGABCDEFG"
查询 "DE" ==> result 3
int lastIndexOf(char ch);
找出指定字符最后一次出现的下标位置
"ABCDABCD";
查询 'B' ==> result 5
int lastIndexOf(String str);
找出指定字符串最后一次出现的下标位置
"ABCDABCD";
查询 "CD" ==> result 6
package com.qfedu.b_string;
/*
* 获取方法
*/
public class Demo2 {
public static void main(String[] args) {
String str = "ABCDEFGABCDEFG";
// length方法
System.out.println("str.length() : " + str.length());
// charAt方法
System.out.println("str.charAt(5) : " + str.charAt(5));
System.out.println("str.charAt(0) : " + str.charAt(0));
// StringIndexOutOfBoundsException 字符串下标操作越界异常 字符串长度为14
// 有效下标为0 ~ 13
// ArrayIndexOutOfBoundsException
// System.out.println("str.charAt(14) : " + str.charAt(14));
// indexOf方法
System.out.println("str.indexOf(\"CD\") : " + str.indexOf("CD"));
System.out.println("str.indexOf('C') : " + str.indexOf('C'));
// lastIndexOf方法
System.out.println("str.lastIndexOf(\"CD\") : " + str.lastIndexOf("CD"));
System.out.println("str.lastIndexOf('C') : " + str.lastIndexOf('C'));
}
}
2.4 判断方法
boolean endsWith(String str);
判断当前字符串是不是指定字符串结尾,如果是返回true,不是返回false
boolean startsWith(String str);
判断当前字符串是不是指定字符串开始,如果是返回true,不是返回false
boolean isEmpty();
判断当前字符串是否为空,空字符串是指 "" 双引号什么都没有
boolean contains(String str) 是否包含指定序列 应用:搜索
判断该指定字符串是否是当前字符串的子字符串。
当前字符串:
"ABCDEFG";
参数字符串:
"CDE"; ==> result true;
参数字符串:
"CE"; ==> result false
原码是调用String类的indexOf方法,找出指定字符串的下标位置,indexOf方法下标为大于等于0,返回 true,否则返回 false
boolean equals(Object anObject);
重写 Override Object类内方法,判断两个字符串是否一致。
boolean equalsIgnoreCase(String anotherString);
忽略大小写是否相等,不考虑英文大小写方式比较两个字符串是否一致。
package com.qfedu.b_string;
/*
* 判断方法
*/
public class Demo3 {
public static void main(String[] args) {
String str = "ABCDEFGABCDEFG";
// endsWith方法
System.out.println("str.endsWith(\"FG\") : " + str.endsWith("FG"));
System.out.println("str.endsWith(\"FG\") : " + str.endsWith("GF"));
// startsWith方法
System.out.println("str.startsWith(\"AB\") : " + str.startsWith("AB"));
System.out.println("str.startsWith(\"BA\") : " + str.startsWith("BA"));
// isEmpty方法
System.out.println("str.isEmpty() : " + str.isEmpty());
System.out.println("\"\".isEmpty() : " + "".isEmpty());
// contains方法
System.out.println("str.contains(\"ABCD\") : " + str.contains("ABCD"));
System.out.println("str.contains(\"ACBD\") : " + str.contains("ACBD"));
// equalsIgnoreCase方法
System.out.println("ABCDEFG".equalsIgnoreCase("AbcdEfg"));
}
}
2.5 转换方法
String(char[] value);
将字符数组转换为字符串
String(char[] value, int offset, int count);
将字符数组转换为字符串,从指定offset位置开始,计数count
offset是开始位置
count是截取个数
例如:
char[] arr = {'A', 'B', 'C', 'D', 'E'};
调用方法参数:
new String(arr, 2, 3); ==> result "CDE"
static String valueOf(char[] data);
同理String(char[] value);
tips: 底层代码是 return new String(data);
static String valueOf(char[] data, int offset, int count);
同理String(char[] value, int offset, int count);
tips: 底层代码是 return new String(data, offset, count);
char[] toCharArray();
将字符串转换为字符数组
例如:
"ABCDE";
返回值:
{'A', 'B', 'C', 'D', 'E'};
package com.qfedu.b_string;
/*
* 转换方法
*/
public class Demo4 {
public static void main(String[] args) {
char[] arr = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
String str = new String(arr);
System.out.println(str);
String str2 = new String(arr, 3, 3);
System.out.println(str2);
String str3 = String.valueOf(arr);
System.out.println(str3);
String str4 = String.valueOf(arr, 3, 3);
System.out.println(str4);
char[] charArray = "你好,这里是骚磊电台".toCharArray();
for (int i = 0; i < charArray.length; i++) {
System.out.println(charArray[i]);
}
}
}
2.6 其他方法
String replace(char oldChar, char newChar);
替换使用newChar字符类型,替换当前字符串内的所有指定字符oldChar
例如:
"ABCDEABCDE";
调用方法:
"ABCDEABCDE".replace('A', '你');
返回值结果:
"你BCDE你BCDE"; 【注】原字符串不变
String[] split(String regex); 【重点】
【重点】切割,将当前字符串按照指定字符串切割成String类型数组
例如:
String str = "你好!他好!大家好!广州好迪";
调用方法:
str.split("!");
返回值结果:
String[] arr = {"你好", "他好", "大家好", "广州好迪"};
调用方法:
str.split("好");
返回值结果:
String[] arr = {"你", "!他", "!大家","!广州", "迪"};
String substring(int beginIndex); 【重点】
从指定beginIndex开始,到字符串结尾截取字符串
例如:
String str = "ABCDEFG";
调用方法:
str.substring(3);
返回值结果:
"DEFG"
String substring(int beginIndex, int endIndex); 【重点】
从指定beginIndex开始,到endIndex结束,截取字符串
要头不要尾 beginIndex <= 结果范围 < endIndex [3,5)
例如:
String str = "ABCDEFG";
调用方法:
str.substring(3, 5);
返回值结果:
"DE"
String toUpperCase();
字符串中所有的英文字母转大写,返回新字符串
String toLowerCase();
字符串中所有的英文字母转小写,返回新字符串
String trim();
去除字符串两边的空格
package com.qfedu.b_string;
import java.util.Arrays;
/*
* 其他方法
*/
public class Demo5 {
public static void main(String[] args) {
String str = "ABCDEFGABCDEFG";
String replace = str.replace('A', '你');
System.out.println(str);
System.out.println(replace);
String str1 = "你好,他好,大家好,广州好迪";
String[] split = str1.split(",");
// Arrays数据工具类的toString方法,数组中的元素会使用, 分割
System.out.println(Arrays.toString(split));
for (int i = 0; i < split.length; i++) {
System.out.println(split[i]);
}
String substring = str.substring(5);
System.out.println(substring);
String substring2 = str.substring(5, 9);
System.out.println(substring2);
System.out.println("abc,,,d浩爷EFG".toUpperCase());
System.out.println("AB!!!!C浩爷Defg".toLowerCase());
System.out.println();
String str2 = " fdafdsaf fedadfs ";
System.out.println(str2);
System.out.println(str2.trim());
}
}