枚举和注解、异常

一、 枚举和注解

1.  枚举的概述

        枚举 (enumeration),是一组常量的集合

        枚举属于一种特殊的类,里面只包含一组有限的特定对象

        枚举的两种实现方式:自定义类实现枚举enum关键字实现枚举

(1) 自定义类实现枚举

        ① 不需要提供 setXxx 方法,因为枚举对象值通常为只读

        ② 对枚举对象/属性使用 final + static 共同修饰,实现底层优化

        ③ 枚举对象名通常使用全部大写,常量的命名规范

        ④ 枚举对象根据需要,也可以有多个属性

特点:     ① 构造器私有化

                ② 本类内部创建一组对象 [四个 春夏秋冬] 

                ③ 对外暴露对象 (通过为对象添加 public final static 修饰符)

                ④ 可以提供 get 方法,但不要提供 set        

(2) enum关键字实现枚举

        ① 当我们使用 enum 关键字开发一个枚举类时,默认会继承 Enum 类

             而且是一个 final

        ② 传统的 public static final Season SPRING = new Season("春天","温暖")

             简化成 SPRING("春天","温暖"),这里必须知道它调用的是哪个构造器

             常量名(实参列表)

        ③ 如果使用无参构造器创建枚举对象,则实参列表小括号都可以省略

        ④ 当有多个枚举对象时,使用逗号间隔,最后有一个分号结尾

        ⑤ 枚举对象必须放在枚举类的行首

package com.hhh.enum_; 
public class Enumeration { 
    public static void main(String[] args) { 
        System.out.println(Season.AUTUMN); 
        System.out.println(Season.SUMMER); 
    } 
}

enum Season2 {
    //定义了四个对象, 固定. 
    // 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("夏天", "炎热"); 
    //如果使用了 enum 来实现枚举类 
    //1. 使用关键字 enum 替代 class 
    //2. public static final Season SPRING = new Season("春天", "温暖") 
    //   直接使用SPRING("春天", "温暖") 
    //3. 如果有多个常量(对象), 使用 ,号间隔即可 
    //4. 如果使用 enum 来实现枚举,要求将定义常量对象,写在前面 
    //5. 如果我们使用的是无参构造器,创建常量对象,则可以省略 () 
    SPRING("春天", "温暖"), WINTER("冬天", "寒冷"), AUTUMN("秋天", "凉爽"), 
    SUMMER("夏天", "炎热")/*, What()*/; 

    private String name; 
    private String desc;//描述
    private Season2() {
    //无参构造器 
    }
    private Season(String name, String desc) { 
        this.name = name; 
        this.desc = desc; 
    }
    public String getName() { 
        return name; 
    }
    public String getDesc() { 
        return desc; 
    }
    @Override 
    public String toString() { 
        return "Season{" + "name='" + name + '\'' + 
                        ", desc='" + desc + '\'' + 
                      '}'; 
    } 
}

         2) enum 常用方法应用实例

                ① toString:Enum 类已经重写过了,返回的是当前对象名,子类可以

                                     重写该方法,用于返回对象的属性信息

                                        Season autumn = Season.AUTUMN;

                                        System.out.println(autumn);

                ② name:返回当前对象名(常量名)子类中不能重写

                                        System.out.println(autumn.name());

                ③ ordinal:返回当前对象的位置号,默认从0开始

                                        System.out.println(autumn.ordinal());

                ④ values:返回当前枚举类中所有的常量

                                        Season[] values = Season.values();

                                        for(Season season:Season.values){

                                                System.out.println(season);

                                        }

                ⑤ valueOf:将字符串转换成枚举对象,要求字符串必须为已有的常量名

                                     否则报异常!

                                        Season value = Season.valueOf("SPRING");

                                        System.out.println(value);

                ⑥ compareTo:比较两个枚举常量,比较的就是位置号

                                        System.out.println(autumn.compareTo(value));

        3) enum 实现接口

                ① 使用 enum 关键字后,就不能再继承其他类了,因为 enum 会隐式继承 Enum,

                     而 Java 是单继承机制

                ② 枚举类和普通类一样,可以实现接口

                        enum 类名 implement 接口1,接口2{}

2.  注解的理解

        ① 注解 (Annotation) 也被称为元数据 (Metadata),用于修饰解释 包、类、方法、

             属性、构造器、局部变量等数据信息

        ② 和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入

             在代码中的补充信息

        ③ 在 JavaSE 中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。

             在 JavaEE 中注解占据了更重要的角色,例如用来配置应用程序的任何切面,

             代替 Java EE 旧版中所遗留的繁冗代码和 XML 配置等

        (2) 基本的 Annotation 介绍

                 使用 Annotation 时要在其前面增加 @ 符号,并把该 Annotation 当成一个

        修饰符使用,用于修饰它支持的程序元素。

                三个基本的 Annotation:

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

                    //@interface 不是 interface,是注解类

                ② @Deprecated:用于表示某个程序元素(类,方法等)已过时

                ③ @SuppressWarnings:抑制编译器警告 

        1) @Override 使用说明

                ① @Override 表示指定重写父类的方法 (从编译层面验证),如果父类

                    没有 fly 方法,则会报错 

                ② 如果不写 @Override 注解,而父类仍有 public void fly(){},仍然构成重写

                ③ @Override 只能修饰方法,不能修饰其他类,包,属性等等

                ④ 查看 @Override 注解源码@Target(ElementType.METHOD)

                    说明只能修饰方法

                ⑤ @Target 是修饰注解的注解,称为元注解

        2) @Deprecated 使用说明

                ① 用于表示某个程度元素(类,方法等)已过时 

                ② 可以修饰方法,类,字段,包,参数等

                ③ @Target(value={CONSTRUCTOR,FIELD,LOCAL_VARIABLE,

                    METHOD,PACKAGE,PARAMETER,TYPE})

                ④ @Deprecated 的作用可以做到新旧版本的兼容和过渡

        3) @SuppressWarnings 使用说明

                ① unchecked 是忽略没有检查的警告

                     例如:@SuppressWarnings(“unchecked”);

                ② rawtypes 是忽略没有指定泛型的警告(传参时没有指定泛型的警告错误)

                ③ unused 是忽略没有使用某个变量的警告错误

                ④ @SuppressWarnings 可以修饰的程序元素为,查看@Target

                ⑤ 生成 @SuppressWarnings 时,直接点击左侧的黄色提示,就可以选择

                     (注意可以指定生成的位置)

3. JDK内置的元 Annotation (元注解)

    JDK 的元 Annotation 用于修饰其他 Annotation 

(2) 元注解的种类

        ① Retention         //指定注解的作用范围,三种 SOURCE,CLASS,RUNTIME

        ② Target              //指定注解可以在哪些地方使用

        ③ Documented   //指定该注解是否会在 javadoc 体现

        ④ Inherited         //子类会继承父类注解

        1) @Retention 注解

                    只能用于修饰一个 Annotation 定义,用于指定该 Annotation 可以保留多长时间

            @Retention 包含一个 RetentionPolicy 类型的成员变量,使用 @Retention 时必须为

            该 value 成员变量指定值

                @Retention 的三种值:

                ① RetentionPolicy.SOURCE 编译器使用后,直接丢弃这种策略的注释

                ② RetentionPolicy.CLASS 编译器将把注解记录在 class 文件中,当运行

                    Java 程序时,JVM 不会保留注释。这是默认值

                ③ RetentionPolicy.RUNTIME 编译器将把注解记录在 class 文件中,当运行

                     Java 程序时,JVM 会保留注释,程序可以通过反射获取该注解

        2) @Target 注解

               用于修饰 Annotation 定义,用于指定被修饰的 Annotation 能用于修饰哪些

               程序元素。@Target 也包含一个名为 value 的成员变量。

        3) @Documented 注解

                用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档,

                即在生成文档时,看到该注解

                说明:定义为 Documented 的注解必须设置 Retention 值为 RUNTIME

        4) @Inherited 注解

                被它修饰的 Annotation 将具有继承性,如果某个类使用了被 @Inherited 修饰

                的 Annotation ,则其子类将自动具有该注解

二、 Exception(异常)

        代码出现异常/问题,可以使用 try-catch 异常处理机制来解决,从而保证程序的健壮性

 解决方法:选择该代码块,alt + shift +z (idea是 ctrl+alt+t ),选中 try-catch,既可以继续执行

        

         

         1.异常的概念

                Java 语言中,将程序执行中发生的不正常情况成为 "异常"。

                 (开发过程中的语法错误和逻辑错误不是异常)

             (2) 执行过程中所发生的的异常事件可分为两大类

        ① Error (错误):Java 虚拟机无法解决的严重问题

                    例如:JVM 系统内部错误、资源耗尽等严重情况;

                              StackOverflowError [栈溢出] OOM (out of memory),

                              Error 是严重错误,程序会崩溃

        ② Exception:其他因编程错误偶然的外在因素导致的一般性问题

                                可以使用针对性的代码进行处理。

                     例如:空指针访问试图读取不存在的文件,网络连接中断等等

             

         Exception 分为两大类:

                        运行时异常 [程序运行时,发生的异常] 

                        编译时异常 [编程时,编译器检查出的异常]

        2. 异常体系图

                体现了继承实现关系 

        ① 异常分为两大类,运行时异常编译时异常

        ② 运行时异常,编译器不要求强制处置的异常 (编译器检查不出来)。

             一般是编程时的逻辑错误,是程序员应该避免其出现的异常

            java.lang.RuntimeException 类及它的子类都是运行时异常

        ③ 对于运行时异常,可以不作处理,因为这类异常很普遍,若全处理可能会

            对程序的可读性和运行效率产生影响

        ④ 编译时异常,是编译器要求必须处置的异常

         3. 常见的运行时异常

        ① NullPointerException 空指针异常

        ② ArithmeticException 数学运算异常

        ③ ArrayIndexOutOfBoundsException 数组下标越界异常

        ④ ClassCastException 类型转换异常

        ⑤ NumberFormatException 数字格式不正确异常[]

         4. 常见的编译异常

                编译异常是指在编译期间,就必须处理的异常,否则代码不能通过编译

        ① SQLException 操作数据库时,查询表可能发生异常

        ② IQException 操作文件时,发生的异常

        ③ FileNotFoundException 当操作一个不存在的文件时,发生异常

        ④ ClassNotFoundException 加载类,而该类不存在时,异常

        ⑤ EOFException 操作文件,到文件末尾,发生异常

        ⑥ IllegalArguementException 参数异常

        5. 异常处理的方式

                异常处理就是当异常发生时,对异常处理的方式

        ① try-catch-finally

             程序员在代码中捕获发生的异常,自行处理

                try {

                        代码/可能有异常

                } catch (Exception e) {

                        // 捕获到异常

                        // 当异常发生时,系统将异常封装成 Exception 对象 e,

                        // 传递给 catch,得到异常对象后,程序员自己处理

                        // 注:如果没有发生异常,catch 代码块不执行

                        // try-catch 块可以有多个

                } finally{

                        // 不管 try 代码块是否有异常发生,始终要执行 finally

                        // 所以,通常将释放资源的代码,放在 finally

                        // 如果没有finally,语法也可以通过

                }

   

        ② throws

             将发生的异常抛出(甩锅),交给调用者 (方法) 来处理,最顶级的处理者就是JVM 

                

         (2) try-catch 注意事项

         ① 如果异常发生了,则异常发生后面的代码不会执行直接进入到 catch 块

         ② 如果异常没有发生,则顺序执行 try 的代码块,不会进入到 catch

         ③ 如果希望不管是否发生异常,都执行某段代码(比如关闭链接,释放资源等)

              则执行-finally{}

         ④ 可以有多个 catch 语句,捕获不同的异常(进行不同的业务处理),

              要求父类异常在后,子类异常在前,

                      比如(Exception 在后,NullPointerException 在前),

              如果发生异常,只会匹配一个 catch

          ⑤ 可以进行 try-finally 配合使用,这种用法相当于没有捕获异常,

               因此程序会直接崩掉/退出

               应用场景,就是执行一段代码,不管是否发生异常,都必须执行

               某个业务逻辑

public class Exception{
    public static int method(){
        int i = 1;
            try{
                i++;    //i=2
                String[] names = new String[3];
                if (names[1].equals("tom")){//空指针
                    System.out.println(name[1]);
                } else {
                    name[3] = "hahah";
                }
                return 1;
            } catch (ArrayIndexOutOfBoundsException e){
                return 2;
            } catch (NullPointerException e){
                return ++i;    //i=3,保存临时变量 temp=3;
            } finally {
                ++i;    //i=4
                System.out.println("i=" + i);    //i=4
            }
    }
    public static void main(String[] args){
    System.out.println(method());    //3
}    //i=4,3

        (3) throws 异常处理

        ① 如果一个方法中的语句执行时,可能生成某种异常,但是并不能确定如何

             处理这种异常,则此方法应显示地声明抛出异常,声明该方法将不对这些

             异常进行处理,而由该方法的调用者负责处理

        ② 在方法声明中用 throws 语句可以申明抛出异常的列表,throws 后面的异常

             类型可以是方法中产生的异常类型,也可以是它的父类 

        ③ throws 关键字后面也可以是 异常列表,即可以抛出多个异常

                注意事项:

        ① 对于编译异常,程序中必须处理,比如 try-catch throws

        ② 对于运行时异常,程序中如果没有处理,默认就是 throws 的方式处理

        ③ 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的

             异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型

        ④ 在 throws 过程中,如果有方法 try-catch,就相当于处理异常,就可以不必 throws 

        6. 自定义异常

        当程序中出现了某些 "错误" ,但该错误信息并没有在 Throwable 子类中描述处理,

        这个可以可以自己设计异常类,用于描述该错误信息

    自定义异常的步骤:

            ① 定义类:自定义异常类名(程序员自己写) 继承 Exception 或 RuntimeException

            ② 如果继承 Exception ,属于编译异常

            ③ 如果继承 RuntimeException ,属于运行异常 (一般继承 RuntimeException)

public class CustomException { 
    public static void main(String[] args) { 
        int age = 180; 
        //要求范围在 18 – 120 之间,否则抛出一个自定义异常 
        if(!(age >= 18 && age <= 120)) { 
            //这里我们可以通过构造器,设置信息 
            throw new AgeException("年龄需要在 18~120 之间"); 
        }
        System.out.println("你的年龄范围正确."); 
    } 
}

class AgeException extends RuntimeException { 
    public AgeException(String message) {//构造器 
        super(message); 
    } 
}

        7. throwthrows 的区别

意义  位置   后面跟的东西
  throws异常处理的一种方式  方法申明处   异常类型
  throw手动生成异常对象的关键字  方法体中   异常对象

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值