八、可变参数、stream流、异常

可变参数

介绍

  • 定义方法参数的一种方式,方法的参数类型已经确定,个数不确定,我们可以使用可变参数

格式

修饰符 返回值类型 方法名(数据类型… 变量名) {  }

注意事项

  • 可变参数的变量其实是一个数组
  • 如果一个方法有多个参数,包含可变参数,可变参数要放在最后

基本使用

    public static void main(String[] args) {
        //int[] arr = new int[]{4, 56, 6, 2, 2, 4, 5, 6, 7, 3};
        //sum(arr);

        sum(4, 56, 6, 2, 2, 4, 5, 6, 7, 3);
        sum();
        sum(10, 20);
        sum(10, 20, 30);

    }

    //计算数组中所有的数据的和 打印
    //int...是可变参数  表示可以接受任意数量的int类型数据 ,可变参数的本质是一个数组
    public static void sum(int... arr) {
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        System.out.println(sum);
    }

    //public static void sum(int[] arr) {
    //    int sum = 0;
    //    for (int i = 0; i < arr.length; i++) {
    //        sum += arr[i];
    //    }
    //    System.out.println(sum);
    //}

可变参数放到参数的最后面

在这里插入图片描述

创建不可变集合(理解)

  • static <E> List<E> of(E…elements) 创建一个具有指定元素的List集合对象
  • static <E> Set<E> of(E…elements) 创建一个具有指定元素的Set集合对象
  • static <K , V> Map<K,V> of(E…elements) 创建一个具有指定元素的Map集合对象
  • 常用来作为创建集合的构造参数

代码

  • method1是List.of练习
  • method2是 Set.of练习 ,注意不要传入重复数据 ,会报错
  • method3是 Map.of练习 ,传入多个键和值
  • method4是 Map.ofEntries练习 ,传入多个Entry对象
    private static void method1() {
        List<String> list = List.of("a", "b", "c", "d");
        System.out.println(list);
        //list.add("Q");报错
        //list.remove("a");报错
        //list.set(0,"A");报错

        //集合的批量添加。
        //首先是通过调用List.of方法来创建一个不可变的集合,of方法的形参就是一个可变参数。
        //再创建一个ArrayList集合,并把这个不可变的集合中所有的数据,都添加到ArrayList中。
        ArrayList<String> list3 = new ArrayList<>(List.of("a", "b", "c", "d"));
        System.out.println(list3);
    }

    private static void method2() {
        //传递的参数当中,不能存在重复的元素。下面的a重复 会报异常 IllegalArgumentException: duplicate element: a
        Set<String> set = Set.of("a", "b", "c", "d", "a");
        System.out.println(set);
    }

    private static void method3() {
        //传入多个键值
        Map<String, String> map = Map.of("zhangsan", "江苏", "lisi", "北京", "wangwu", "天津");
        System.out.println(map);
    }

    private static void method4() {
        //传入一个个Entry对象
        Map<String, String> map = Map.ofEntries(
                Map.entry("zhangsan", "江苏"),
                Map.entry("lisi", "北京")
        );
        System.out.println(map);
    }

Collections.addAll 添加数据

ArrayList<String> list = new ArrayList<>();

//利用Collections的addAll方法添加数据
Collections.addAll(list, "aaa", "bbb", "ccc", "ddd");

System.out.println(list);

Stream流(理解,掌握常用的中间操作)

案例需求

按照下面的要求完成集合的创建和遍历

  • 创建一个集合,存储多个字符串元素
  • 把集合中所有以"张"开头的元素存储到一个新的集合
  • 把"张"开头的集合中的长度为3的元素存储到一个新的集合
  • 遍历上一步得到的集合

原始方式示例代码

ArrayList<String> list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"));

//遍历list1把以张开头的元素添加到list2中。
ArrayList<String> list2 = new ArrayList<>();
for (String s : list1) {
    if(s.startsWith("张")){
        list2.add(s);
    }
}
//遍历list2集合,把其中长度为3的元素,再添加到list3中。
ArrayList<String> list3 = new ArrayList<>();
for (String s : list2) {
    if(s.length() == 3){
        list3.add(s);
    }
}
for (String s : list3) {
    System.out.println(s);
}     

流的实现方式

        ArrayList<String> list1 = new ArrayList<>(List.of("张三丰", "张无忌", "张翠山", "王二麻子", "张良", "谢广坤"));

        //1 获取流  list1.stream()

        //2 过滤 姓张的数据   filter(s -> s.startsWith("张"))
        //3 过滤 长度为3的数据  filter(s -> s.length() == 3)

        //4 打印  终结操作   forEach(s -> System.out.println(s))

        list1.stream().filter(s -> s.startsWith("张")).
                filter(s -> s.length() == 3).
                forEach(s -> System.out.println(s));

Stream流的思想

  • 类似流水线,在过程中可以多次处理流数据

Stream流的三类方法

  • 获取Stream流
    • 创建一条流水线,并把数据放到流水线上准备进行操作
  • 中间方法
    • 流水线上的操作
    • 一次操作完毕之后,还可以继续进行其他操作
  • 终结方法
    • 一个Stream流只能有一个终结方法
    • 是流水线上的最后一个操作

生成Stream流的方式

  • 1 Collection体系集合
    • 使用默认方法stream()生成流
  • 2 Map体系集合
    • 把Map转成Set集合(keySet,entrySet),间接的生成流
    • keySet().stream() 或者 entrySet().stream()
  • 3 数组
    • 通过Arrays中的静态方法stream生成流 Arrays.stream(arr)
  • 4 同种数据类型的多个数据
    • 通过Stream接口的静态方法of(T… values)生成流 , 原理还是数组变流

代码演示

// - 1  Collection体系集合
//  - 使用默认方法stream()生成流
List<String> list = new ArrayList<>();
Stream<String> listStream = list.stream();

Set<String> set = new HashSet<>();
Stream<String> setStream = set.stream();


//- 2  Map体系集合
//  - 把Map转成Set集合(keySet,entrySet),间接的生成流
Map<String, String> map = new HashMap<>();
//先获取key的集合 再获取流
Stream<String> mapKeyStream = map.keySet().stream();
//先获取Entry对象的集合 再获取流
Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();


//- 3  数组
//  - 通过Arrays中的静态方法stream生成流
int[] arr = new int[]{4,56,7,8,4,3};
IntStream intStream = Arrays.stream(arr);

//4 通过of方法 把同一类型的多个数据 转为流对象
Stream<Integer> is = Stream.of(3, 4, 6, 7, 8);
Stream<String> ss = Stream.of("z", "l", "x");

Stream流中间操作方法【熟练应用】

概念

  • 中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作

常见方法

方法名说明
Stream filter(Predicate predicate)用于对流中的数据进行过滤
Stream limit(long maxSize)返回流中最前面 指定参数个数的数据组成的流
Stream skip(long n)跳过指定参数个数的数据,返回由该流的剩余元素组成的流
static Stream concat(Stream a, Stream b)合并a和b两个流为一个流
Stream distinct()返回 去掉流数据中 重复的元素后剩余数据组成的流

filter代码

  • 流的操作不影响原集合的数据
        ArrayList<String> al = new ArrayList<String>(List.of("周润发", "成龙", "小明", "刘德华", "吴京", "周星驰", "李连杰"));

         //流的操作不影响原集合的数据
        al.stream().filter(s -> s.length() >= 3).forEach(s -> System.out.println(s));

        //会把流数据里的每一条数据 传到test方法中 获取返回值,返回为true的数据留下,为false的删除
        al.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() == 3;
            }
        });

limit skip代码

 ArrayList<String> al = new ArrayList<String>(List.of("周润发", "成龙", "小明", "刘德华", "吴京", "周星驰", "李连杰"));
 
System.out.println("--------------------------------------------------------------");
//  Stream<T> limit(long maxSize)           	返回流中最前面指定参数个数的数据组成的流
al.stream().limit(4).forEach(s -> System.out.println(s));

System.out.println("--------------------------------------------------------------");

//  Stream<T> skip(long n)                  	跳过指定参数个数的数据,返回由该流的剩余元素组成的流
al.stream().skip(2).forEach(s -> System.out.println(s));

concat 和distinct

//  static <T> Stream<T> concat(Stream a, Stream b)	合并a和b两个流为一个流
ArrayList<String> al1 = new ArrayList<String>(List.of("林心如", "张曼玉", "林青霞", "柳岩", "林志玲", "小明", "王祖贤"));
Stream.concat(al.stream(), al1.stream()).forEach(s -> System.out.println(s));

System.out.println("--------------------------------------------------------------");
//  Stream<T> distinct()         返回 去掉流数据中 重复的元素后剩余数据组成的流
Stream.concat(al.stream(), al1.stream()).distinct().forEach(s -> System.out.println(s));

skip和limit一起操作

ArrayList<String> al = new ArrayList<String>(List.of("周润发", "成龙", "小明", "刘德华", "吴京", "周星驰", "李连杰"));
//跳过前2个数据 剩余的数据再获取前面2个
al.stream().skip(2).limit(2).forEach(s -> System.out.println(s));

Stream流终结操作方法

概念

  • 终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作

常见方法

方法名说明
void forEach(Consumer action)对此流的每个元素执行操作
long count()返回此流中的元素数

代码

ArrayList<String> al = new ArrayList<String>(List.of("周润发", "成龙", "小明", "刘德华", "吴京", "周星驰", "李连杰"));

al.stream().skip(2).limit(2).forEach(s -> {
    System.out.println(s);
});

long count = al.stream().skip(2).count();//获取数据的数量
System.out.println(count);

collect收集操作

  • collect方法 获取流中剩余的数据,但是他不负责创建容器,也不负责把数据添加到容器中.
  • Collectors提供了具体的收集方式
    • 收集到List 、收集到Set、收集到Map
方法名说明
public static Collector toList()把元素收集到List集合中
public static Collector toSet()把元素收集到Set集合中
public static Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中

收集到list和set的代码

  • 把集合转为流,然后把偶数留下,收集到新的集合中(list或者set)返回
public static void main(String[] args) {
    ArrayList<Integer> al = new ArrayList<>();
    for (int i = 1; i <= 10; i++) {
        al.add(i);
    }
    //添加一些重复数据  为了后面set集合演示去重复
    al.add(10);
    al.add(10);
    al.add(10);
    al.add(10);

    //使用流 获取所有的偶数 最后collect收集到List集合里
    List<Integer> list = al.stream().filter(number -> number % 2 == 0).collect(Collectors.toList());
    System.out.println(list);

    //使用流 获取所有的偶数 最后collect收集到set集合中返回,这里返回的是set集合,重复的数据最后会默认去除
    Set<Integer> set = al.stream().filter(number -> number % 2 == 0).collect(Collectors.toSet());
    System.out.println(set);
    
    
}

收集到map

  • 把学生的名字作为key , 年龄作为value
    public static void main(String[] args) {
        ArrayList<Student> al = new ArrayList<Student>();
        al.add(new Student("zhangsan", 15));
        al.add(new Student("lisi", 17));
        al.add(new Student("xiaoming", 19));

        //数据收集为map集合
        Map<Object, Object> map = al.stream().limit(2).collect(
                Collectors.toMap(
                        new Function<Student, Object>() {
                            @Override
                            public Object apply(Student student) {
                                //返回值作为key
                                return student.getName();
                            }
                        },
                        new Function<Student, Object>() {
                            @Override
                            public Object apply(Student student) {
                                //返回值作为value
                                return student.getAge();
                            }
                        }
                )
        );

        Map<Object, Object> map1 = al.stream().limit(2).collect(
                Collectors.toMap(
                        student -> student.getName(),
                        student -> student.getAge()
                )
        );

        System.out.println(map);

    }

Stream流综合练习

案例需求

  • 现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
    • 男演员只要名字为3个字的前三人
    • 女演员只要姓林的,并且不要第一个
    • 把过滤后的男演员姓名和女演员姓名合并到一起
    • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
  • 演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法

演员类代码

public class Actor {
    private String name;

    public Actor(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

测试类代码

public static void main(String[] args) {
    ArrayList<String> manList = new ArrayList<String>();
    manList.add("周润发");
    manList.add("成龙");
    manList.add("刘德华");
    manList.add("吴京");
    manList.add("周星驰");
    manList.add("李连杰");
    //名字为3个字的前三人
    Stream<String> manStream = manList.stream().filter(s -> s.length() == 3).limit(3);

    ArrayList<String> womanList = new ArrayList<String>();
    womanList.add("林心如");
    womanList.add("张曼玉");
    womanList.add("林青霞");
    womanList.add("柳岩");
    womanList.add("林志玲");
    womanList.add("王祖贤");
    //只要姓林的,并且不要第一个
    Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("林")).skip(1);

    //合并过滤后的男演员和女演员
    Stream<String> newStream = Stream.concat(manStream, womanStream);
    newStream.forEach(s -> {
        //创建演员对象 把名字传入
        Actor actor = new Actor(s);
        //获取演员的对象的名字打印
        System.out.println(actor.getName());
    });
}

自学Stream里的 map reduce 方法

异常(重点)

异常介绍

  • 指程序在运行后,JVM遇到无法执行的代码,从而会中断程序

举例

例如:
    int[] arr = new int[3];
    System.out.println(arr[3]);
执行结果:
           Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
           at com.itheima.demo20.Demo01.main(Demo01.java:8)
               
例如:
    int[] arr = null;
   	 System.out.println("数组长度:" + arr.length);
执行结果:
           Exception in thread "main" java.lang.NullPointerException
           at com.itheima.demo20.Demo01.main(Demo01.java:8)
    
    
例如:
Scanner sc = new Scanner(System.in);
System.out.println("请输入年龄:");
int age = sc.nextInt()
System.out.println("你的年龄是:" + age);
执行结果:
	请输入年龄:
	呵呵
    	Exception in thread "main" java.util.InputMismatchException
           ......
   	    at com.itheima.demo20.Demo01.main(Demo01.java:9)

上面的三个程序都有一个特点:

  • 编译通过,运行后程序会中断!!
  • 出现这种现象带来的后果:
    • 如果是桌面程序,会出现卡死、闪退…等现象;
    • 如果是WEB程序,服务器端需要重启,用户无法访问。

异常处理效果演示

  • Java提供了一种“异常处理机制”,它是一种语法,可以在JVM遇到异常时,“跳过”有异常的代码,使程序继续运行下去
  • 异常处理机制的作用:可以让JVM跳过有异常的代码,继续运行下去!!
Scanner sc = new Scanner(System.in);
System.out.println("请输入年龄:");
try {
    int age = sc.nextInt();
    System.out.println("你的年龄是:" + age);//上一行代码出现异常,这一行代码会跳过,不会被执行
} catch (InputMismatchException e) {
    System.out.println("你的输入有误!");
}

System.out.println("后续代码...");
  • jvm如何处理异常呢???

当JVM执行,遇到有异常的代码时:

  • 1 JVM会先识别出这个异常
  • 2 然后JVM会到类库,找到描述这个异常的“异常类”,并创建此类对象
  • 3 随后JVM会到代码中查看是否catch(捕获)(之前必须有try)
    • 没有:在控制台打印异常信息,然后结束程序!!(没有异常处理机制)
    • 有:则将“异常对象”传给catch语句,然后执行catch语句,程序不会被结束!!(有异常处理机制)

在这里插入图片描述

  • RuntimeException(运行时异常):通常由程序逻辑引起的异常,程序员应通过良好的编码避免这种异常情况—可防!
  • 除RuntimeException外的其它异常(编译期异常):由外界原因导致的异常, 例如:磁盘坏道、网络中断等—意外!

小结

1. 异常的概念:
      指代码运行时,JVM遇到了无法处理的代码,这种情况称为“异常”。
2. 异常处理的作用:
     通过一些异常处理的语法,可以使JVM在执行到有异常的代码时,跳过这段代码,使程序可以继续运行下去。
3. 常见的几种异常:
     1). NullPointerException:空指针异常
     2). ArrayIndexOutOfBoundsException:数组索引越界异常
     3). InputMismatchException:输入不匹配异常
     4). ArithmeticException :算术运算异常(整数 / 0)
     5). StringIndexOutOfBoundsException:字符串索引越界 
4. 异常类体系结构:
    Throwable
             |--Error(错误)
             |--Exception(异常)
                       |--RuntimeException:运行时异常
                       |--其它异常:编译期异常

异常捕获

格式

  • 可以catch捕获多个异常
  • 注意:
    • 进行多catch异常处理时,父类异常不能放在子类异常的前面
try {
	//可能出现异常的代码;
} catch(要捕获的异常类名 变量名) {
	//出现异常后执行的代码;
} catch(要捕获的异常类名 变量名) {
	//出现异常后执行的代码;
} ....
  • 例子 多个异常的捕获
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入年龄:");
        //捕获异常
        try {
            int age = sc.nextInt();
            System.out.println("你的年龄是:" + age);//上一行代码出现异常,这一行代码会跳过,不会被执行
            String a = null;
            System.out.println(a.length());

        } catch (NullPointerException e) {
            System.out.println("空指针了");
        } catch (InputMismatchException e) {
            System.out.println("你的输入有误!");
        }
        System.out.println("后续代码...");

    }
  • 例子父类异常不能放在子类异常的前面 如下图

在这里插入图片描述

执行流程

  • 第一种情况:try中的代码没有任何异常,那么代码会跳过catch继续向下执行。
  • 第二种情况:try中的代码有异常会从所有catch中对比,如果catch捕获到了这个异常,那么代码会从try直接跳到catch中。
  • 第三种情况:try中的代码有异常但是catch没有捕获到这个异常,这个异常会依旧向外抛

throws声明异常

注意:

  1. 如果声明抛出的是“运行时异常”,调用的代码可以不处理,语法上不强制
  2. 如果声明抛出的是“编译期异常”,调用的代码要么使用try_catch,要么使用throws必须处理,否则编译错误。

代码1编译期异常

在这里插入图片描述

代码2运行时异常

在这里插入图片描述

注意

  • 编译时异常:在编译时期必须要进行处理(try…catch或throws
  • 运行时异常:在编译时期,可以try catch处理,也可以不处理(运用代码逻辑去避免)。

在这里插入图片描述

throw关键字使用

  • 作用:用来手动向外抛出异常。
    格式: throw new 异常类名();

代码1

  • divide中如果传入的b为0,就抛出异常
  • getStudent中如果传入的age不在范围内,就抛出异常
    public static void main(String[] args) {

        divide(10, 0);
        Student stu = getStudent("zhansgan", 20);
        System.out.println(stu);
    }


    public static int divide(int a, int b) {
        if (b == 0) {
            throw new RuntimeException("除数不能为0");
        }

        return a / b;
    }


    public static Student getStudent(String name, int age) {
        if (age < 0 || age > 150) {
            throw new RuntimeException("age不在范围内");
        }
        return new Student(name, age);
    }

代码2 抛出处理过的异常 再次处理

  • 注意在getSum方法内的catch里有一个throw e
  • 这种表示,捕获异常后,把异常抛出,让调用方法的人继续去处理异常
public static void main(String[] args) {
        try {
            int[] arr = {13, 23, 12, 25, 76};
            int sum = getSum(null);
            //int sum = getSum(arr);
            System.out.println("sum = " + sum);
        } catch (Exception e) {
            System.out.println("把异常保存到文件里");
        }
    }
    public static int getSum(int[] arr) {
        int sum = 0;
        try {
            for (int i = 0; i < arr.length; i++) {  //arr.length可能会产生空指针异常
                sum += arr[i];
            }
            return sum;
        } catch (NullPointerException e) {
            System.out.println("空指针");//统一的异常处理方式
            throw e;//把异常对象抛出 希望调用的人也可以处理到这个异常
        } 
    }

代码3 抛出处理过的异常 再次处理

在这里插入图片描述

finally代码块

  • finally代码块的特点:

    • finally代码块的内容无论是否出现异常,都会执行。它通常用于方法中,
    • 当try以及catch中需要return值或者抛出异常的时候
  • 格式:

try {A】可能会出现异常的代码
} catch(要捕获的异常类名 变量名) {B】出现异常后执行的代码
} finally {C】一定会执行的代码
}

代码

  • 下面的代码 虽然有return和throw e,但是finally里的代码始终都会执行
  • 注意如果再finally里写里的return,try里的return和catch里的throw e就不执行了

执行流程 (【A】【B】【C】看上面的格式)

  • 第一种情况:如果try中的代码没有异常,执行流程为【A】【C】
  • 第二种情况:如果try中的代码有异常,并且catch捕获到了这个异常,执行流程为 【A】【B】【C】
  • 第三种情况:如果try中的代码有异常,但是catch没有捕获到这个异常,执行流程为 【A】【C】向外抛出异常
    public static void main(String[] args) {
        try {
            int[] arr = {13, 23, 12, 25, 76};
            int sum = getSum(null);
            //int sum = getSum(arr);
            System.out.println("sum = " + sum);
        } catch (Exception e) {
            System.out.println("把异常保存到文件里");
        }
    }


    public static int getSum(int[] arr) {
        int sum = 0;
        try {
            for (int i = 0; i < arr.length; i++) {  //arr.length可能会产生空指针异常
                sum += arr[i];
            }
            //return sum;
        } catch (NullPointerException e) {
            System.out.println("空指针");//统一的异常处理方式
            throw e;//把异常对象抛出 希望调用的人也可以处理到这个异常
        } finally {
            System.out.println("方法执行完毕,时间:" + System.currentTimeMillis());
        }
    }

异常的常见方法

  • public String getMessage() 返回此 throwable 的详细消息字符串
  • public String toString() 返回此可抛出的简短描述
  • public void printStackTrace() 把异常的错误信息输出在控制台(字体为红色的)

代码

  • 注意printStackTrace异常的错误信息为红色
    public static void main(String[] args) {
        int index = 10;
        test(index);
    }

    public static void test(int index) {

        try {
            int[] arr = {1, 2, 3, 4, 5};
            //虚拟机帮我们创建了一个异常对象 new ArrayIndexOutOfBoundsException();
            System.out.println(arr[index]);
        } catch (ArrayIndexOutOfBoundsException e) {
            //System.out.println("有越界");
            e.printStackTrace();
            System.out.println(e.toString());
            System.out.println(e.getMessage());
        }
        System.out.println("嘿嘿嘿");
    }

自定义异常

  • 我们之前用的异常很多都是Java中定义好的,在真正开发中,有很多在JDK中没有定义的异常,比如年龄异常,分数异常等等,如果使用这样的异常,那么就需要我们自己定义了。
  • 一般自定义异常会继承Exception,目的是让大家必须去处理

代码

  • 类AgeException继承Exception 是编译期异常
  • 注意 如果需要传入异常描述,需要要写构造方法
public class AgeException extends Exception {
    public AgeException(String message) {
        super(message);
    }
}

测试

public class Demo01 {
    public static void main(String[] args) {
        try {
            test(-2);
        } catch (AgeException e) {
            e.printStackTrace();
        }
    }
    public static void test(int age) throws AgeException{
        if (age < 0)
            throw new AgeException("年龄异常");
    }
}

小结

1. 异常处理的基本语句?
            try{
                 ...
            }catch(异常类型名 变量名){
                 ...
            }
2.catch语句?
           try{
                 ...
            }catch(异常类型名1 变量名){
                 ...
            } catch(异常类型名2 变量名){
                 ...
            }
3. finally语句?
           try{
                 ...
                 return xxx;
            }catch(异常类型名1 变量名){
                 ...
                 return xxx;
            } finally{
                 //无论是否出现异常,都会被执行的代码
            }
4. throws:方法声明处,声明抛出异常?
5. throw:方法内部,抛出一个异常对象?
6. Throwable中的常用方法?
      1.getMessage():获取异常信息
      2. toString():异常类名 + 异常信息(如果有)
      3. printStackTrace():打印异常详细信息

经验总结

1 编译期异常 必须处理  如果是在方法中,那么就看这个方法是写业务逻辑的还是工具型的被别人调用的
	1.1如果是写业务逻辑的,那么直接trycatch捕获
	1.2 如果是工具型的被别人调用的,那么直接throws声明,也可以捕获后,catch中再throw抛出,交给调用的程序员去处理这个异常
	
2 运行时异常 一般像空指针 越界这种异常,很多是因为自己的代码不够严谨导致,需要自己处理代码的逻辑bug,很少去捕获

3 一般公司中都会有自己规范的自定义异常的方式,要写详细的文档和注释。

4一般自定义异常会继承Exception,目的是让大家必须去处理
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值