Java基础day15——枚举、异常

1.枚举与版本

枚举自JDK1.5版本后开始有

1.5以前则用private final String 定义属性

和private来私有化构造器

public static final 来创建对象

并用Get方法获取

  枚举类:类的对象的个数是可数多个(有限)的 这样的类我们叫作枚举类。

    JDK1.5开始有枚举类


 */
/*
    JDK1.5之前的枚举类如何实现
 */
class Season{
    //属性 - 每个对象各自拥有一份。
    private final String NAME;
    private final String INFO;

    //私有化构造器-不能在类的外面创建该类的对象
    private Season(String name,String info){
        this.NAME = name;
        this.INFO = info;
    }

    //创建对象
    public static final Season SPRING = new Season("春天","春暖花开"); //常量
    public static final Season SUMMER = new Season("夏天","夏天蚊子咬");
    public static final Season AUTUMN = new Season("秋天","秋天有落叶");
    public static final Season WINTER = new Season("冬天","冬天穿棉袄");

    public String getNAME() {
        return NAME;
    }

    public String getINFO() {
        return INFO;
    }
}
public class EnumTest {

    public static void main(String[] args) {
        //获取Season对象
        Season spring = Season.SPRING;
        System.out.println(spring.getNAME() + " " + spring.getINFO());
    }
}

1.5版本后

格式  : 权限修饰符 enum 枚举类的名字{

}

权限修饰符:只能用public 和缺省的     和类的修饰符相同

枚举类默认继承了java.lang.Enum类

枚举类的构造器只能用private 修饰 默认用private 修饰

枚举中自定义用final 修饰 因为对象都是常量 所以不需要用static过度修饰

switch -case中变量类型可以是枚举类型

switch中可用类型  byte int short char 字符串 枚举

/*
    JDK1.5之后的枚举类如何实现
        格式 : 权限修饰符 enum 枚举类的名字{
               }

               权限修饰符 :只能是public和缺省的。

    说明:
        1.枚举类不能再继承其它类。因为默认继承了java.lang.Enum类
        2.创建对象 - 枚举类中声明的对象必须放在类中的首行。多个对象之间用","分隔开最后用“;”结尾
        3.枚举类的构造器默认是private修饰也只能是private修饰
        4.如果我们要在枚举类中自定义属性 那么建议该属性用final修饰(因为对象都是常量 所以对象中的属性也要常量但不要被static修饰)。
        5.switch-case中 switch中的变量的类型可以是枚举类型。
 */

enum Season3{
    SPRING,SUMMER,AUTUMN,WINTER;
}

class A{
    public void test(){
        //switch (byte,short,int,字符串,char,枚举)
        switch (Season3.SPRING){
            case AUTUMN:
                break;
            case SPRING:
                break;
        }
    }
}

//枚举类不能再继承其它类。因为默认继承了java.lang.Enum类
enum Season2{

    //创建对象 - 枚举类中声明的对象必须放在类中的首行。多个对象之间用","分隔开最后用“;”结尾
    SPRING("春天"),SUMMER("夏天"), AUTUMN("秋天"), WINTER("冬天");

    private final String name; //final修饰的变量必须赋值
    //枚举类的构造器 -只能是private
    //private Season2(){}//默认是private

    private Season2(String name){ //自定义了一个有参的构造器
        this.name = name;
    } //默认是private


    public String getName() {
        return name;
    }
}


public class EnumTest2 {

    public static void main(String[] args) {

    }
}

2.枚举类使用场景

1.类比较少

2.形参限定 只能使用枚举,避免范围为的随意传参

class State{
    public static final int OPEN = 0;
    public static final int CLOSE = 1;
}

/*
    在类的设计中 如果是关于某些状态一般用枚举类(比较少)

    在类的设计中 如果是关于某些参数(比较多)(比如: ip地址 端口号 线程数量 ....... 等后面Kafka就知道了)
 */
enum ComputerState{
    OPEN,CLOSE;//对象
}

public class EnumTest3 {

    public static void main(String[] args) {
        //setComputerState(-5);
        setComputerState(ComputerState.OPEN);
    }

    /*
        用枚举类作为方法的形参的好处就是只能传枚举类中的某一个对象。
     */
    public static void setComputerState(ComputerState state){
        if (state == ComputerState.CLOSE){

        }else{

        }
    }
    //设置电脑的状态
//    public static void setComputerState(int state){
//
//    }

}

3.枚举类中的API

了解即可

/*
    枚举类中的方法
 */

import java.util.Arrays;

public class EnumAPITest {
    /*
    下面了解即可
    1.String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法!
    2.String name():返回的是常量名(对象名)
    3.int ordinal():返回常量的次序号,默认从0开始
    4.枚举类型[] values():返回该枚举类的所有的常量对象,返回类型是当前枚举的数组类型,是一个静态方法
    5.枚举类型 valueOf(String name):根据枚举常量对象名称获取枚举对象
     */
    public static void main(String[] args) {
        //枚举类型[] values():返回该枚举类的所有的常量对象,返回类型是当前枚举的数组类型,是一个静态方法
        Season2[] values = Season2.values();
        System.out.println(Arrays.toString(values));

        //枚举类型 valueOf(String name):根据枚举常量对象名称获取枚举对象
        Season2 spring = Season2.valueOf("SPRING");//实参是个字符串 - 严格区分大小写
        System.out.println(spring.getName());

        //String toString(): 默认返回的是常量名(对象名),可以继续手动重写该方法!
        String string = Season2.SPRING.toString();
        System.out.println(string);

        //String name():返回的是常量名(对象名)
        System.out.println(Season2.SPRING.getName());

        //int ordinal():返回常量的次序号,默认从0开始
        System.out.println(Season2.SPRING.ordinal());
    }
}

4.异常概述及异常演示

异常的结构  throwable 总表异常

Error 表示严重错误 无法用catch进行处理修复

Exception :可以catch到进行处理的普通异常 分为编译时异常和运行时异常

编译时异常:在程序编译时发生的异常,不一定会发生 但有发生的风险

运行时异常:程序运行时的代码错误导致(空指针 下角标越界等错误)

/*
    异常 : 指的是在程序运行的过程中,出现非正常的情况导致程序终止
        注意:异常不是指的语法错误或逻辑代码错误

    JVM(系统)是如何处理异常的
        Java中把不同的异常用不同的类表示。一旦发生某种异常。系统就会创建对应异常类的对象并抛出。
        该异常是可以被catch到如果catch到后可以做相应的处理。如果没有catch动作程序终止运行。

    异常体系结构:
        |------Throwable
            |-------Error: 表示严重错误。无法catch只能程序挂掉。
            |-------Exception :表示普通异常是可以被catch到的。catch到后可以做相应的处理程序不会挂掉。没有catch到程序一样终止运行。
                |------编译时异常(受检异常):在程序编译的时候发生的异常-不一定会真正的发生异常只是有可能会发生异常
                        例:有一个程序该程序需要读取配置文件,但该配置文件有可能找不到不是说一定找不到。
                            那这个读取文件的操作(方法)就会在编译时发生异常-所以需要处理该异常-万一找不到了怎么办。
                |------运行时异常(非受检异常)(RuntimeException及子类):在程序运行的时候发生的异常。
                            这类异常是由程序员的代码编写错误导致(比如:空指针  下角标越界 类型转换异常)
 */
public class ExceptionTest {
    public static void main(String[] args) {
        //error演示
        //error();

        runtimeException();
    }

    /*
        非受检异常:运行时异常
     */
    public static void runtimeException(){
        //System.out.println(1 / 0);//ArithmeticException

        //NullPointerException
//        String s = null;
//        System.out.println(s.length());

        //ClassCastException
//        Object o = new Integer("1");//多态
//        String s = (String) o;

        //ArrayIndexOutOfBoundsException
//        int[] ns = new int[2];
//        ns[3] = 10;
    }

    /*
        编译时异常
     */
    public static void exception(){
        //受检异常-编译时异常
        //FileNotFoundException
        //new FileInputStream("a.txt");

        //InterruptedException
        //Thread.sleep(10000);
    }

    public static void error(){
          /*
            演示 error : OutOfMemoryError
         */
        //int[] n = new int[Integer.MAX_VALUE];//Integer.MAX_VALUE int的最大值

        //StackOverflowError
        error();
    }


}

5.try —— catch ——finally 结构

格式

try{

可能发生错误的代码

}catch(异常类型1){

}...

finally{

一定要执行的代码

}

无论什么情况finally中代码一定会执行 除了还没执行就结束

/*
    我们提到的异常指的是Exception

    处理异常:
        方式一 :try-catch-finally
        方式二 :throws

    处理异常方式一:try-catch-finally
       格式:
            try{
                可能会发生异常的代码
                代码1
                代码2 --> 发生异常。代码3就不再执行了
                代码3
            }catch(异常类型1){
                异常类型1的处理
            }catch(异常类型2){
                异常类型2的处理
            }
            .......
            finally{
                一定要执行的代码
            }
       说明:
         1.如果try中的代码没有发生异常 那么会执行完try中所有的代码后跳到finally中执行finally中的代码。
            然后跳出try-catch-finally结果继续向下执行其它代码

         2.如果try中的代码发生了异常 那么在try中发生异常的代码后面的try中代码不再执行。
            系统会根据相应的异常创建异常类的对象并抛出。因为我们会catch异常所以会和catch后面的异常类型匹配。
            如果和第一个catch后面的异常类型匹配失败继承向下匹配直到匹配成功并执行相应catch中的代码执行完后
            跳到finally中并执行finally中的代码执行完后跳出try-catch-finally并继续向下执行其它代码。
            如果向下匹配失败那么会进入finally中执行finally中的代码然后终止程序的运行(因为没抓到异常-没有匹配成功)。

        3.注意:finally可以省略不写 ,如果有finally无论什么情况finally中的代码一定会执行。
 */
public class ExceptionTest2 {
    public static void main(String[] args) {

       demo4();
    }

    /*
        没有finally
     */
    public static void demo4(){
        try{
            System.out.println("开始执行代码");
            System.out.println(1 / 0);
            System.out.println("执行完代码");
        }catch (ClassCastException e){
            System.out.println("类型转化异常");
        }catch (NullPointerException e){
            System.out.println("空指针异常");
        }

        System.out.println("over");
        System.out.println("over");
    }

    /*
        有异常但没有catch到
     */
    public static void demo3(){
        try{
            System.out.println("开始执行代码");
            System.out.println(1 / 0);
            System.out.println("执行完代码");
        }catch (ClassCastException e){
            System.out.println("类型转化异常");
        }catch (NullPointerException e){
            System.out.println("空指针异常");
        }finally {
            System.out.println("劳资一定要执行");
        }

        System.out.println("over");
        System.out.println("over");
    }

    //没有异常
    public static void demo2(){
        try{
            System.out.println("开始执行代码");
            //System.out.println(1 / 0);
            System.out.println("执行完代码");
        }catch (ClassCastException e){
            System.out.println("类型转化异常");
        }catch (NullPointerException e){
            System.out.println("空指针异常");
        }catch (ArithmeticException e){
            System.out.println("算术运算异常");
        }finally {
            System.out.println("劳资一定要执行");
        }

        System.out.println("over");
        System.out.println("over");
    }

    public static void demo1(){
        try{
            System.out.println("开始执行代码");
            System.out.println(1 / 0);
            System.out.println("执行完代码");
        }catch (ClassCastException e){
            System.out.println("类型转化异常");
        }catch (NullPointerException e){
            System.out.println("空指针异常");
        }catch (ArithmeticException e){
            System.out.println("算术运算异常");
        }finally {
            System.out.println("劳资一定要执行");
        }

        System.out.println("over");
        System.out.println("over");
    }

}

6.try —— catch ——finally再说明

catch作用时收集异常信息

异常写父类 : tongyichul

异常类型写具体类型 : 不同类型不同处理最后写父类

catch可以省略

finally 作用:关闭资源 保存某些数据 保存某些状态

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

        demo3();
    }

    public static void demo3(){

        try {
            new FileInputStream("a.txt");//编译时异常 - 必须处理。不处理没办法运行。
        } catch (FileNotFoundException e) {
            //实际生产中-要收集异常信息
            System.out.println(e.getMessage());//getMessage() : 获取异常信息 -- 将异常信息写到日志文件
            e.printStackTrace();//将异常信息打印到控制台
        }
        System.out.println("over");
        System.out.println("over");

    }

    /*
        异常的类型写父类还是具体的类型呢?
            场景1(异常类型写父类) : 无论什么异常全部是统一处理方式
            场景2(异常类型要写具体的类型 最后用父类兜底) :不同的异常不同的处理方法
        注意:如果要匹配多种异常类型 小的(异常的子类)在前面大的(异常的父类)在后面。
     */
    public static void demo2(){
        try{
            System.out.println("开始执行代码");
            //System.out.println(1 / 0); //运行时异常

            String s = null;
            System.out.println(s.length());//运行时异常
            System.out.println("执行完代码");
        }catch (ArithmeticException e){ // 写父类
            System.out.println("处理方式1");
        }catch (NullPointerException e){ // 写父类
            System.out.println("处理方式2");
        }catch (Exception e){ // 写父类
            System.out.println("统一处理");
        }
        System.out.println("over");
        System.out.println("over");
    }
    /*
        如何catch到所有异常
     */
    public static void demo1(){
        try{
            System.out.println("开始执行代码");
            //System.out.println(1 / 0);

            String s = null;
            System.out.println(s.length());
            System.out.println("执行完代码");
        }catch (Exception e){ // 写父类
            System.out.println("发生异常了");
        }
        System.out.println("over");
        System.out.println("over");
    }
}
/*
    catch可以省略 :try-finally结构
 */
public class ExceptionTest4 {
    public static void main(String[] args) {
        demo1();
    }

    public static void demo1(){

        /*
            try-catch : 有异常要处理 没有一定要执行的代码
            try-catch-finally : 有异常要处理 而且有一定要执行的代码(比如 ①关闭资源 ②保存某些数据 ③保存某些状态)
            try-finally : 有异常不处理  有一定要执行的代码(比如 ①关闭资源 ②保存某些数据 ③保存某些状态)
         */
        try {
            System.out.println(1 / 0);
        }finally {
            //finally中放的是一定要执行的代码
            //场景 :比如 ①关闭资源 ②保存某些数据 ③保存某些状态
            System.out.println("我一定要执行");
        }

        System.out.println("over");
    }
}

7.jdk1.7的结构再变化

/*
    在jdk1.7的时候 catch中的写法可以这么写 :catch(异常的类型 | 异常的类型2 e)
 */
public class ExceptionTest5 {
    public static void main(String[] args) {
        try{
            System.out.println(1 / 0);
        }catch (NullPointerException | ArithmeticException e){
            System.out.println("发生异常了");
        }
    }
}

9.finally不执行的情况


/*
    finally : finally中的代码一定会执行(除非System.exit(0) 关闭JVM).

    1.就算在try-catch中有return finally中的代码也一定要执行
    2.如果finally中出现return那么try-catch中的return就失效了 -- (其实发生覆盖)
 */
public class FinallyTest {

    public static void main(String[] args) {
//        System.out.println(demo1());
//        System.out.println(demo2());

        demo3();
    }

    /*
        finally不会执行的情况
     */
    public static void demo3(){
        try{
            System.exit(0); //关闭JVM --- System.exit(0) :0是JVM退出的状态码。0是正常退出
        }catch (Exception e){
            System.out.println("发生了异常");
        }finally {
            System.out.println("finally一定会执行");
        }
    }

    /*
        就算在try-catch中发生了return,那么finally中的return仍然会执行。
     */
    public static int demo2(){
        try{
            return 1;
        }catch (Exception e){
            return 2;
        }finally {
            return 3; //如果finally中出现return那么try-catch中的return就失效了 -- (其实发生覆盖)
        }
    }

    /*
        就算在try-catch中有return finally中的代码也一定要执行
     */
    public static int demo1(){
        try{
            return 1;
        }catch (Exception e){
            return 2;
        }finally {
            System.out.println("finally中的代码一定要执行");
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值