【Java基础】学习笔记4 - 枚举类、注解与异常

枚举类

枚举类的定义比较复杂

依据下方代码做出解释

  1. 枚举常量必须位于枚举类最顶端,他表示我们需要使用的常量
  2. 定义私有属性,这些属性将成为枚举常量中的参数
  3. 定义构造函数,构造函数的格式对应枚举常量的格式,一一赋值给私有属性
  4. 定义私有属性的 getter,这样外界才可以获取枚举常量中的参数值
package chapter3;

public class EnumClass {
    
    
    public static void main(String[] args) {
    
    
        Persons[] persons = Persons.values();
        for (Persons person : persons) {
    
    
            StringBuilder sb = new StringBuilder();
            sb.append(person.getAge());
            sb.append(person.getName());
            sb.append(person.name());
            System.out.println(sb.toString());
        }
    }
}

enum Persons {
    
    
    JACK("jack", 12),  // 枚举常量 JACK,名称为 "jack",年龄为 12
    TOM("tom", 13),   // 枚举常量 TOM,名称为 "tom",年龄为 13
    WHITE("white", 41),  // 枚举常量 WHITE,名称为 "white",年龄为 41
    ALIEN("undefined");  // 枚举常量 ALIEN,名称为 "undefined",使用默认年龄 999

    private final String name;  // 枚举常量的名称
    private final int age;  // 枚举常量的年龄

    // 枚举常量的构造方法,接受名称和年龄
    Persons(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    // 枚举常量的构造方法,只接受名称,年龄使用默认值 999
    Persons(String name) {
    
    
        this.name = name;
        this.age = 999;
    }

    // 获取枚举常量的名称
    public String getName() {
    
    
        return name;
    }

    // 获取枚举常量的年龄
    public int getAge() {
    
    
        return age;
    }
}

或者,直接使用最简单的办法,所有枚举常量本身就是一个字符串常量
他们不需要任何参数,只需要再被用到时取出 name() 即可

public class EnumClass {
    
    
    public static void main(String[] args) {
    
    
        GENDER boy = GENDER.BOY;
        GENDER girl = GENDER.GIRL;
        System.out.println(boy.name());
    }
}

enum GENDER {
    
    
    BOY, GIRL;
}

因为枚举类 enum 默认隐式继承了 Enum,所以你没法再用 extends 了,但是还是可以实现接口的!

枚举类挂载多个接口然后实现他们,就可以直接被外界调用

package chapter3;

public class EnumInterfaceClass {
    
    
    public static void main(String[] args) {
    
    
        // 直接通过枚举常量调用对应接口方法
        BB.ASD.say();
    }
}

// 接口
interface B {
    
    
    void say();
}

enum BB implements B {
    
    

    ASD("asd"), QWE("qwe");

    private final String msg;

    BB(String msg) {
    
    
        this.msg = msg;
    }

    // 实现对应的方法
    @Override
    public void say() {
    
    
        System.out.println(msg);
    }
}

注解

三个常见的注解:

  • @Override 重写注解
  • @Deprecated 表示方法已被废弃
  • @SuppressWarnings 抑制编译器警告

@Override

只能修饰方法

只能指定为重写父类的方法,如果父类没有该方法,就会报错

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


@Deprecated

可以标注所有类型成员

表示该类型已经过时,用于新旧版本切换过度


@SuppressWarnings

抑制编译器警告

抑制的范围根据你放置该注解的位置有关

你可以通过指定抑制哪一个方面的注解,对应抑制名称可以上网查

@SuppressWarnings({
    
    "unchecked"})
public void asd(){
    
    }

四种元注解

@Retention:用于指定被注解的注解的保留策略。注解的保留策略决定了注解在编译时、类加载时或运行时可见。
他接受一个参数,可选取值为:

  • RetentionPolicy.SOURCE:注解仅保留在源代码中,在编译后不会包含在编译好的文件中。
  • RetentionPolicy.CLASS:注解保留在编译后的字节码文件中,但不会被加载到虚拟机中,在运行时不可见。
  • RetentionPolicy.RUNTIME:注解保留在编译后的字节码文件中,并被加载到虚拟机中,在运行时可通过反射机制获取。

@Target:用于指定被注解的注解可以应用于哪些元素上。注解可以应用于类、方法、字段等不同的元素上,@Target 用于限制注解的使用范围。
@Target 接受一个参数 ElementType[],表示注解可以应用于的元素类型。

@Documented:用于指定被注解的注解是否包含在 Java 文档中。如果一个注解被标注了该注解 d,则在生成 Java 文档时,该注解会包含在文档中。

@Inherited:用于指定被注解的注解是否可以被继承。当一个类被继承时,是否继承父类上的注解。


异常

异常可以划分为两类:

  1. Error:JVM 无法解决的严重问题,如系统内部错误或者资源耗尽等情况
  2. Exception:一般性错误,如空指针异常;他又可以分为两大类:
    • 运行时异常:不要求强制处理的异常,一般都是编程时的逻辑错误
    • 编译时异常:编译器要求必须处理的异常

运行时异常

常见的运行时异常:

  1. NullPointerException(空指针异常):当代码尝试使用一个空对象的方法或访问空对象的属性时抛出。
  2. ArrayIndexOutOfBoundsException(数组越界异常):当尝试访问数组中不存在的索引时抛出。
  3. ClassCastException(类转换异常):当尝试将一个对象强制转换为不兼容的类型时抛出。
  4. NumberFormatException(数字格式异常):当字符串无法转换为数字类型时抛出,例如使用 Integer.parseInt 时传入的字符串不是合法的数字格式。
  5. ArithmeticException(算术异常):当进行算术运算时出现错误,例如除以零或模运算时除数为零。
  6. IllegalArgumentException(非法参数异常):当传递给方法的参数不合法或无效时抛出,例如传递了空对象或不允许的参数值。
  7. IllegalStateException(非法状态异常):当对象处于不允许的状态时抛出,例如在不正确的时间调用方法或操作。
  8. IndexOutOfBoundsException(索引越界异常):当访问集合(如列表或字符串)中不存在的索引时抛出。
  9. ConcurrentModificationException(并发修改异常):当在迭代集合的同时,使用不允许的方式(如修改集合)进行修改时抛出。
  10. UnsupportedOperationException(不支持的操作异常):当调用不支持的方法或操作时抛出,通常是因为对象不支持特定的操作。

捕获异常

最简单的 try catch 代码块来捕获异常

子类异常写在前面,父类异常写在后面

finally 表示无论如何都会执行的代码

package chapter4;

public class Exp1 {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            String str = "123";
            int num = Integer.parseInt(str);
            System.out.println(num);
        } catch (NumberFormatException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            System.out.println("我一直会被执行");
        }
    }
}

抛出异常

我们可以直接摆烂,不去主动处理异常,而是由子类去处理

此时可以使用 throw 抛出异常,抛出的异常可以是当前异常的父类;
如果你为了省事,可以直接 throw Exception

package chapter4;

public class Exp2 {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            int num = new Exp2().getNum("asd");
            System.out.println(num);
        } catch (NumberFormatException e) {
    
    
            e.printStackTrace();
        }
    }

    public int getNum(String str) throws NumberFormatException {
    
    
        return Integer.parseInt(str);
    }
}

编译时异常一定要处理或者抛出;运行时异常一般直接抛出;

如果你已经处理异常,就没必要抛出异常了


自定义异常

package chapter4;

import java.util.Scanner;

public class Exp3 {
    
    
    public static void main(String[] args) {
    
    
        int age = 100;
        if (age < 100) throw new CustomException("你的数字不对");
    }
}

class CustomException extends RuntimeException {
    
    
    public CustomException(String message) {
    
    
        super(message);
    }
}

猜你喜欢

转载自blog.csdn.net/delete_you/article/details/132698142