JAVA中的异常
一.简介
- Throwable,Error,和Exception。
- Java异常结构中定义有Throwable类,Exception和Error是其派生类的两个子类,其中Exception表示网络故障,文件损坏,设备错误,用户输入非法等情况导致的异常。
二.TryCatch捕获异常
1.TryCatch使用
try{
代码片段
}catch(XXException e){
捕获try代码片段出现的XXException
}
public class TryCatchDemo {
public static void main(String[] args) {
try {
String s="afaf";
int p=Integer.parseInt(s);
System.out.println(p);
} catch (NullPointerException e) {
System.out.println("空指针异常");
}catch(StringIndexOutOfBoundsException e2){
System.out.println("下标越界异常");
}catch(ArithmeticException e3){
System.out.println("数学异常");
/*
* 养成好习惯,最后一个catch捕获Exception防止因为没有捕获到
* 的异常,捕获异常时从小到大也就是异常的子类到异常的父类逐渐抛出
*/
}catch(NumberFormatException e4){
System.out.println("转换异常");
e4.printStackTrace();//日志跟踪
}
}
}
2. 常见的RuntimeException异常
- 1.制造空指针异常:NullPointerException
- 2.制造数学异常:ArithmeticException
- 3.制造数组越界异常:ArrayIndexoutofBoundsException
- 4.制造数值格式异常:NumberFormatException
- 5.制造强制类型转换异常:ClassCastException
public class TryCatchDemo2 {
public static void main(String[] args) {
//1.空指针异常
// String str=null;
// System.out.println(str.length());
//2.数学异常
// int a=5/0;
// System.out.println(a);
//3.数组越界异常
// int[] arr=new int[2];
// System.out.println(arr[3]);
//4.数值格式异常
// String s="afaf";
// int p=Integer.parseInt(s);
// System.out.println(p);
//5.强制转换异常
Object obj="牛逼的Java";
int y=(Integer)obj;
}
}
3.各种异常之间的关系
三.Finally
1.Finally块
1.他只能定义在异常处理机制的最后,可以直接在try后面或者最后一个catch之后(一般都在catch后面);
2.finally可以保证程序运行到try中,那麽无论try中的代码是否出现异常,finally里面的代码都要执行.
3.在这里通常释放资源等操作方在finally中,比如关闭流,释放资源等。
public class Finallydemo {
public static void main(String[] args) {
try {
int a=5/0;
System.out.println(a);
//finally在return之前执行
return;
} catch (Exception e) {
e.printStackTrace();
System.out.println("出错了!");
}finally{
System.out.println("执行了finally");
}
System.out.println("程序结束了");
}
}
2.对IO流的操作捕获异常
public class Finallydemo2 {
public static void main(String[] args) {
FileInputStream fis=null;
try {
fis=new FileInputStream("demo.txt");
byte[] bs=new byte[100];
fis.read(bs);
String str=new String(bs,"UTF-8");
System.out.println(str);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(fis!=null){
fis.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
3.自动关闭流
在JDK1.7版本后推出了一个新的特性那就是自动关闭流.自动关闭语法是编译器认可的,编译后还是在finally中进行.
public class Finallydemo3 {
public static void main(String[] args) {
try (FileInputStream fis=new FileInputStream("fos.txt");){//(;)分号可加可不加
byte[] bs=new byte[100];
fis.read(bs);
String str=new String(bs,"UTF-8");
System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
}
}
}
四.throw和throws
1.throw与throw的简介与关系
1.一个方法内部使用throw抛出一个异常,就要在方法上使用throws, 声明该异常的抛出告知调用方法处理这个异常,只有RuntimeException, 或者他的子类异常在方法中抛出是不需要在方法上声明该异常的抛出, 其他异常类则必须在后面使用throws抛出异常,否则编译不通过。
异常的抛出:
throw关键字,用于将一个异常抛出通常两种情况会主动抛出异常
1.程序遇到一个满足语法要求,但是不满足业务要求的是时候抛出一个异常给调用者。
2.程序出现异常,在当前代码中处理,该异常可以抛给调用者。
throws:当我们调用了一个含有throws声明异常抛出的方法时, 编译器要求我们必须处理这个异常,
处理方式有两种:
1.try-catch自己捕获异常并处理。
2.在当前方法上继续使用throws声明该异常抛出,调用者
需要来处理这个异常。
2.throw抛出RuntimeException
可将RuntimeException异常抛给客户端,前提是需要我们异类捕获runtimeException抛出的异常信息.
public class ThrowDemo {
public static void main(String[] args) {
try {
String str="";
System.out.println(str.charAt(2));
} catch (Exception e) {
//e.printStackTrace();//日志跟踪
//一旦执行throw,后面的程序将不再执行
throw new RuntimeException("下表越界了");
}
System.out.println("结束");
}
}
3.利用getMessage()方法捕获方法中抛出的异常
public class Person {
private int age;
public int getAge() {
return age;
}
public void setAge(int age) throws Exception {
if(age>200||age<0){
throw new Exception("年龄不合法");
}else{
System.out.println("合法");
}
this.age = age;
}
public static void main(String[] args) {
try {
Person p=new Person();
p.setAge(600);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
4.throws在方法上抛出异常
1.throws:在方法上抛出异常,要求调用方法来解决异常,这里要注意throws不要在主程序main方法上抛出。
2.调用抛出的异常要大于或者等于被调用的方法所抛出的异常。
public class ThrowsDemo {
public static void test() throws FileNotFoundException{//如果改为Exception,则发生错误
int a=5/0;
System.out.println(a);
}
public static void test1() throws FileNotFoundException{
test();
}
public static void test2() throws FileNotFoundException{
test1();
}
public static void main(String[] args){
try {
test2();
} catch (Exception e) {
System.out.println("错了");
e.printStackTrace();
}
}
}
3.子类重写父类含有throws声明抛出的方法对throws重写原则。
public class ThrowsDemo2 {
public void test()throws IOException,AWTError,RuntimeException{
}
}
class Aoo extends ThrowsDemo2{
//1.可以不抛出异常
public void test(){
}
//2.可以抛出部分异常
public void test1() throws IOException{
}
//3.不准抛出父类额外异常
public void test2() throws SQLException{
}
//4.可以抛出父类方法中抛出异常的子类异常类型
public void test3() throws FileNotFoundException{
}
//5.不可以抛出父类方法抛出异常的父类异常类型
public void test4() throws Exception{
}
}
五.自定义异常
1.自定义异常:必须要继承runtimeException()
自定义异常类:NameAlreadException
public class NameAlreadException extends RuntimeException {
public NameAlreadException() {
super();
// TODO Auto-generated constructor stub
}
public NameAlreadException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public NameAlreadException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public NameAlreadException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public NameAlreadException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}
因为NameAlreadException继承了RuntimeException异常,所以方法可以直接抛出该异常。
public class RuntimeExceptionDemo2 {
//用户注册,假如用户名被占用
public static void register(){
String userName="刘永超";
Scanner scanner=new Scanner(System.in);
System.out.println("请输入用户名:");
String str=scanner.next();
if(userName.equals(str)){
throw new NameAlreadException("用户名被占用");
}else{
System.out.println("可以注册");
}
}
public static void main(String[] args) {
try {
register();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
``