JavaSE学习笔记-异常、枚举、注解(5)

目录

一、异常

1.什么是异常

2.异常的体系结构

3.捕获和抛出异常

二、枚举

1.自定义实现枚举

2.enum关键字实现枚举类

3.默认继承Enum父类中常用的方法

三、注解

1.注解的理解

2.JDK内置的基本注解类型

3. 元注解


一、异常

1.什么是异常

1.异常是指程序运行中出现的不期而至的各种状况如:文件找不到、网络连接失败、非法参数、内存或硬盘满了、数据为空等等.

2.简单分类

检查型异常(CheckedException)
       在Java中所有不是RuntimeException派生的Exception(此处不包含error)都是检查型异常。当函数中存在抛出检查型异常的操作时(即有代码可能会导致抛出检查型异常时),该函数的函数声明中必须包含throws语句。调用改函数的函数也必须对该异常进行处理,如不进行处理则必须在调用函数上声明throws语句。

       检查型异常是JAVA首创的,在编译期对异常的处理有强制性的要求。在JDK代码中大量的异常属于检查型异常,包括IOException,SQLException等等。

非检查型异常(UncheckedException)
        在Java中所有RuntimeException的派生类都是非检查型异常,与检查型异常对比,非检查型异常可以不在函数声明中添加throws语句,调用函数上也不需要强制处理。
        常见的NullPointException,ClassCastException是常见的非检查型异常。非检查型异常可以不使用try...catch进行处理,但是如果有异常产生,则异常将由JVM进行处理。

对于RuntimeException的子类最好也使用异常处理机制。虽然RuntimeException的异常可以不使用try...catch进行处理,但是如果一旦发生异常,则肯定会导致程序中断执行,所以,为了保证程序再出错后依然可以执行,在开发代码时最好使用try...catch的异常处理机制进行处理。

 摘自:https://www.cnblogs.com/xh_chiang/p/6850847.html

2.异常的体系结构

图可不清楚去这里看(java异常体系结构详解_Lily的专栏-CSDN博客_java异常体系结构图

3.捕获和抛出异常

关键字: try、catch 、finally、throw、throws

package com.yves.oop;

public class ExceptionTest {
    public static void main(String[] args) {
        int a = 1;
        int b = 0;
        try{//监控区域
            System.out.println(a/b);
        }catch(ArithmeticException e){
            //捕获分析异常部分
            System.out.println("算术运算异常");
        }finally {
            System.out.println("无论是否发生异常都会执行部分");
        }
    }
}

结果:
算术运算异常
无论是否发生异常都会执行部分

还可以多级捕获异常(多个catch).,多级捕获时应该注意catch覆盖范围应该从小到大递增(最大程度便于分析异常)。

package com.yves.oop;

import java.io.IOException;

public class ExceptionTest {

    public static void main(String[] args) {

        try{//监控区域
            new ExceptionTest().a(); //这里为栈溢出异常 Throwable->Error->StackOverflowError
        }catch(RuntimeException e){
            //捕获分析异常部分
            System.out.println("运行时异常");
        }catch (Exception e){
            System.out.println("Exception异常");
        }catch (Error e){
            System.out.println("Error异常");    //应该在这里捕获
        }catch (Throwable e){
            System.out.println("Throwable异常");
        }finally {
            System.out.println("无论是否发生异常都会执行部分");
        }
    }

    public void a(){
        b();
    }
    public void b(){
        a();
    }
}

结果:
Error异常
无论是否发生异常都会执行部分

主动抛出异常:throw,throws

package com.yves.oop;

import java.io.IOException;

public class ExceptionTest {

    //假设方法中处理不了这个异常,在方法上抛出异常 用throws
    public void test(int a , int b) throws ArithmeticException{
//        if(b==0){
//            throw new ArithmeticException();//主动抛出异常  用throw
//        }
        //若有异常 且在方法内主动抛出异常后 抛出异常位置后的代码不会执行 返回方法调用方
        //若有异常 且在方法上主动抛出异常后 会执行到抛出异常的那一行代码 返回方法调用方
        System.out.println(a/b);
    }

    public static void main(String[] args) {
        try{
            new ExceptionTest().test(1,0);
        }catch (Exception e){
            System.out.println("算术错误");
            //利用try catch捕获到异常后 若不结束 程序会继续向下执行 开发中这样不便于我们发现错误
            //所以可以使用System.exit(1);结束程序 
            System.exit(1);
        }
        
        System.out.println("剩余代码部分");
    }
}

二、枚举

枚举创建的两种方式:

        自定义实现枚举;

        使用enum关键字实现枚举;

1.自定义实现枚举

        1.不提供set方法,因为枚举通常是只读的;

        2.对枚举属性使用final+static共同修饰,实现底层优化(static final 属性在被调用的时候不会加载类)

        3.枚举对象名通常全部大写

        4.属性、构造器私有化;通过为对象添加 public static final 对外暴漏对象

        5.通过enum实现枚举默认继承Enum父类 不可继承其他类,但是可以实现接口(实现方法中的接口即可)

代码验证: static + final 属性在被调用的时候不会加载类

package com.yves.enumPackage;

public class Season {
    //利用 static final 修饰的属性被 类名.属性名 调用时不会加载类(静态代码块未执行,静态代码块在类加载时执行且仅执行一次)
    public static final int AAA = 123;
    
    static{
        System.out.println("loading...");
    }
}

package com.yves.enumPackage;

public class Application {
    public static void main(String[] args) {

        System.out.println(Season.AAA);

    }
}

结果:
123

自定义枚举类实例:

package com.yves.enumPackage;

public class Season {
    private String name;
    private String desc;
    
    public static final Season SPRING = new Season("春天","温暖");
    public static final Season WINTER = new Season("冬天","寒冷");
    public static final Season AUTUMN = new Season("秋天","凉爽");
    public static final Season SUMMER = new Season("夏天","炎热");
    
    //构造器私有化 (创建了有参构造器,那么默认的无参构造器想要使用必须显式定义)
    private Season(String name,String desc){
        this.name = name;
        this.desc =desc;
    }
    //2.只保留get方法,保证属性不被修改
    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

package com.yves.enumPackage;

public class Application {
    public static void main(String[] args) {
        System.out.println(Season.SPRING);
        Season season = Season.AUTUMN;
        System.out.println(season);
        System.out.println(season.getName());

    }
}

结果:
Season{name='春天', desc='温暖'}
Season{name='秋天', desc='凉爽'}
秋天


2.enum关键字实现枚举类

1.使用 enum替代了class
2.SPRING("春天","温暖") 取代了 public static final Season SPRING = new Season("春天","温暖");
    因为 enum替代了class 所以无法new, 使用 常量名(参数列表) 方式即可。
    注意:使用 常量名(参数列表) 方式,也会走构造器,本质上等价于 public static final           Season SPRING = new Season("春天","温暖");
3.如果定义多个常量(对象) 使用,隔开即可
4.如果使用enum实现枚举,要求将定义的常量(对象)写在最前面
5.如果使用无参构造器则可以省略() eg: SPRING

enum枚举类实例:

package com.yves.enumPackage;

enum Season {
    //如果使用了枚举类
    /*
    1.使用 enum替代了class
    2.SPRING("春天","温暖") 取代了 public static final Season SPRING = new Season("春天","温暖");
        因为 enum替代了class 所以无法new, 使用 常量名(参数列表) 方式即可。
        注意:使用 常量名(参数列表) 方式,也会走构造器,本质上等价于 public static final Season SPRING = new Season("春天","温暖");
    3.如果定义多个常量(对象) 使用,隔开即可
    4.如果使用enum实现枚举,要求将定义的常量(对象)写在最前面
     */
    SPRING("春天","温暖"),
    SUMMER("夏天","炎热"),
    AUTUMN("秋天","凉爽"),
    WINTER("冬天","寒冷");

    private String name;
    private String desc;

    //构造器私有化 (创建了有参构造器,那么默认的无参构造器想要使用必须显式定义)
    private Season(String name,String desc){
        this.name = name;
        this.desc =desc;
    }
    //2.只保留get方法
    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

package com.yves.enumPackage;

public class Application {
    public static void main(String[] args) {
        System.out.println(Season.SPRING);
        Season season = Season.AUTUMN;
        System.out.println(season);
        System.out.println(season.getName());
    }
}

结果:
Season{name='春天', desc='温暖'}
Season{name='秋天', desc='凉爽'}
秋天


解释第五条:如果使用无参构造器则可以省略()。     

package com.yves.enumPackage;

public class Application {

    enum Gender{

        //这个BOY是一个对象 默认调用了Gender的无参构造器
        //这里的BOY实际上等价于  自定义枚举类的 public static final BOY = new Gender()
        BOY,GIRL;
      
    }

    public static void main(String[] args) {

        Gender boy = Gender.BOY;   //boy={name:BOY}
        Gender boy2 = Gender.BOY;

        //Gender 没有写toString方法,所以会去调父类的toString方法(枚举类默认继承Enum类)
        /*
            Enum 的toString方法
                public String toString() {
                return name;
            }
            因为 boy={name:BOY} 所以 System.out.println(boy); 会输出BOY
          
        */
        System.out.println(boy);    
        
        //BOY和BOY2都指向Gender.BOY
        System.out.println(boy2 == boy);  //ture

    }
}
结果:
BOY
true

3.默认继承Enum父类中常用的方法

package com.yves.enumPackage;

enum Season {

    SPRING("春天","温暖"),
    SUMMER("夏天","炎热"),
    AUTUMN("秋天","凉爽"),
    WINTER("冬天","寒冷");

    private String name;
    private String desc;

    private Season(String name,String desc){
        this.name = name;
        this.desc =desc;
    }

    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

}




package com.yves.enumPackage;

public class Application {
    public static void main(String[] args) {

        Season season1 = Season.SPRING;
        Season season2 = Season.SUMMER;

        System.out.println("=====name() 输出枚举对象的名字====");
        // .name()方法; 输出枚举对象的名字
        System.out.println(season1.name());  //SPRING

        System.out.println("=====ordinal() 输出枚举对象所在的次序====");
        //ordinal() 输出枚举对象所在的次序
        System.out.println(season1.ordinal()); //SPRING:0 SUMMER:1 所以这里为0

        System.out.println("=====values() 返回定义的所有枚举对象====");
        //values() 返回定义的所有枚举对象
        Season valus[] = Season.values();
        for (Season s  : valus) {
            System.out.println(s);
        }

        System.out.println("=====compareTo() 比较两个枚举对象,比较的是编号====");
        //compareTo() 比较两个枚举对象,比较的是编号 返回值为 int 前面的编号-后面的编号
        System.out.println(Season.SPRING.compareTo(Season.SUMMER));  //0-1 = -1

        System.out.println("valueOf(name) 根据name 查找该枚举对象是否存在====");
        //valueOf(name)根据你输入的 “参数名称” 去查找Season的枚举对象
        //如果找到则返回 如果没有则报错;
        Season sea1 = Season.valueOf("WINTER");  //存在 返回该对象
        System.out.println(sea1);
        Season sea2 = Season.valueOf("SPRING1"); //不存在SPRING1 报错
        System.out.println(sea2);
    }
}
结果:
=====name() 输出枚举对象的名字====
SPRING
=====ordinal() 输出枚举对象所在的次序====
0
=====values() 返回定义的所有枚举对象====
SPRING
SUMMER
AUTUMN
WINTER
=====compareTo() 比较两个枚举对象,比较的是编号====
-1
valueOf(name) 根据name 查找该枚举对象是否存在====
WINTER
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant com.yves.enumPackage.Season.SPRING1
	at java.lang.Enum.valueOf(Enum.java:238)
	at com.yves.enumPackage.Season.valueOf(Season.java:3)
	at com.yves.enumPackage.Application.main(Application.java:43)

Process finished with exit code 1

三、注解

1.注解的理解

    1. 注解也被 者运行,相当于代码中的补充信息

2.JDK内置的基本注解类型

         @override 、@deprecated 、@suppresswarnings

        1. @override:限定某个方法,是重写父类方法,该注解只能用于方法

        2. @deprecated:用于表示某个程序元素(类、方法)过时

        3. @suppresswarnings:抑制编译器警告

3. 元注解

        元注解:用于修饰注解的注解叫元注解

        1.Retention:指定注解的作用范围

                source:源码                   class: 类                  runtime : 运行时

        2.Target :指定注解可以在那些地方使用(类、方法、构造器、变量。。。。。)

        3.Documented:指定该注解是否会在javadoc中体现

        4.Inherited:子类会继承父类的注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值