【慕课记录】Java实操避坑指南 -- 代码规范(一)

课程地址

Java空指针和异常

2-1

常犯指数5星
NullPointException

在这里插入图片描述
运行时异常的一个子类
在这里插入图片描述
在这里插入图片描述

  1. 对象没有初始化就去使用了
  2. 访问了空对象的属性
  3. 当数组是一个空对象时,取长度
  4. null当做Throwable的值
  5. 方法的返回值是null,调用方法直接去使用

在这里插入图片描述
拆装箱引发的空指针:
在这里插入图片描述
2-2
javac jdk编译java的源代码的工具,用于生成源代码class文件

javap jdk自带的反解析文件
在这里插入图片描述
在这里插入图片描述
2-3
空对象调用equals方法,所以null放后面
调用equals的对象不为空,即前面的x
在这里插入图片描述
对象数组new出来,但是元素没有初始化

list对象addAll传递null会抛出空指针
在这里插入图片描述
2-4
友情链接
在这里插入图片描述
在这里插入图片描述

package com.imooc.java.escape;

import java.util.Optional;

/**
 * <h1>学会 Optional, 规避空指针异常</h1>
 * */
@SuppressWarnings("all")
public class OptionalUsage {

    private static void badUsageOptional() {

        Optional<User> optional = Optional.ofNullable(null);
        User user = optional.orElse(null); // good
        user = optional.isPresent() ? optional.get() : null; // bad
    }

    public static class User {
        private String name;

        public String getName() {
            return name;
        }
    }

    private static void isUserEqualNull() {

        User user = null;
        if (user != null) {
            System.out.println("User is not null");
        } else {
            System.out.println("User is null");
        }

        Optional<User> optional = Optional.empty();
        if (optional.isPresent()) {
            System.out.println("User is not null");
        } else {
            System.out.println("User is null");
        }
    }

    private static User anoymos() {
        return new User();
    }

    public static void main(String[] args) {

        // 没有意义的使用方法
        isUserEqualNull();

        User user = null;
        Optional<User> optionalUser = Optional.ofNullable(user);
        // 存在即返回, 空则提供默认值
        optionalUser.orElse(new User());
        // 存在即返回, 空则由函数去产生
        optionalUser.orElseGet(() -> anoymos());
        // 存在即返回, 否则抛出异常
        optionalUser.orElseThrow(RuntimeException::new);

        // 存在才去做相应的处理
        optionalUser.ifPresent(u -> System.out.println(u.getName()));

        // map 可以对 Optional 中的对象执行某种操作, 且会返回一个 Optional 对象
        optionalUser.map(u -> u.getName()).orElse("anymos");

        // map 是可以无限级联操作的
        optionalUser.map(u -> u.getName()).map(name -> name.length()).orElse(0);
    }
}

2-5
在这里插入图片描述
在这里插入图片描述
运行时异常+检查性异常

package com.imooc.java.escape;

/**
 * <h1>Java 异常处理</h1>
 * */
@SuppressWarnings("all")
public class ExceptionProcess {

    private static class User {}

    /**
     * <h2>Java 异常本质 -- 抛出异常</h2>
     * */
    private void throwException() {

        User user = null;
        // ....
        if (null == user) {
            throw new NullPointerException();
        }
    }

    /**
     * <h2>不能捕获空指针异常</h2>
     * */
    private void canNotCatchNpeException() {

        try {
            throwException();
        } catch (ClassCastException cce) {
            System.out.println(cce.getMessage());
            System.out.println(cce.getClass().getName());
        }
    }

    /**
     * <h2>能够捕获空指针异常</h2>
     * */
    private void canCatchNpeException() {

        try {
            throwException();
        } catch (ClassCastException cce) {
            System.out.println(cce.getMessage());
            System.out.println(cce.getClass().getName());
        } catch (NullPointerException npe) {
            System.out.println(npe.getMessage());
            System.out.println(npe.getClass().getName());
        }
    }

    public static void main(String[] args) {

        ExceptionProcess process = new ExceptionProcess();
        process.canCatchNpeException();
        System.out.println("程序不会终止");
//        process.canNotCatchNpeException();
    }
}

运行结果:
null
java.lang.NullPointerException
程序不会终止

正确的抛出异常和正确的捕获异常,才能使程序健康的运行下去。

2-6
在这里插入图片描述
2-7
在这里插入图片描述
ClassCastException 类型转换异常
不要在迭代器里对list做modify操作,会引发快速失败机制报错
在这里插入图片描述
枚举类异常处理

package com.imooc.java.escape;

import com.google.common.base.Enums;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * <h1>编码中的常见的异常</h1>
 * */
@SuppressWarnings("all")
public class GeneralException {

    public static class User {

        private String name;

        public User() {}

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

        public String getName() {
            return name;
        }
    }

    public static class Manager extends User {}

    public static class Worker extends User {}

    private static final Map<String, StaffType> typeIndex = new HashMap<>(
            StaffType.values().length
    );

    static {
        for (StaffType value : StaffType.values()) {
            typeIndex.put(value.name(), value);
        }
    }

    private static void concurrentModificationException(ArrayList<User> users) {

        // 直接使用 for 循环会触发并发修改异常
//        for (User user : users) {
//            if (user.getName().equals("imooc")) {
//                users.remove(user);
//            }
//        }

        // 使用迭代器则没有问题
        Iterator<User> iter = users.iterator();
        while (iter.hasNext()) {
            User user = iter.next();
            if (user.getName().equals("imooc")) {
                iter.remove();
            }
        }
    }

    private static StaffType enumFind(String type) {

//        return StaffType.valueOf(type);

        // 1. 最普通、最简单的实现
//        try {
//            return StaffType.valueOf(type);
//        } catch (IllegalArgumentException ex) {
//            return null;
//        }

        // 2. 改进的实现, 但是效率不高
//        for (StaffType value : StaffType.values()) {
//            if (value.name().equals(type)) {
//                return value;
//            }
//        }
//        return null;

        // 3. 静态 Map 索引, 只有一次循环枚举的过程
//        return typeIndex.get(type);

        // 4. 使用 Google Guava Enums, 需要相关的依赖
        return Enums.getIfPresent(StaffType.class, type).orNull();
    }

    public static void main(String[] args) {

        // 1. 并发修改异常
//        ArrayList<User> users = new ArrayList<User>(
//                Arrays.asList(new User("qinyi"), new User("imooc"))
//        );
//        concurrentModificationException(users);

        // 2. 类型转换异常
//        User user1 = new Manager();
//        User user2 = new Worker();

//        Manager m1 = (Manager) user1;
//        Manager m2 = (Manager) user2;

//        System.out.println(user2.getClass().getName());
//        System.out.println(user2 instanceof Manager);

        // 3. 枚举查找异常
        System.out.println(enumFind("RD"));
        System.out.println(enumFind("abc"));
    }
}

以上
注意:使用map index索引的方式遍历enum,并使用guava工具包改进
2-8
传统try finally的缺点
在这里插入图片描述
使用 try with resources

package com.imooc.java.escape.try_with_resources;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.Buffer;

/**
 * <h1>解决使用 try finally 的资源泄露隐患</h1>
 * */
public class Main {

    /**
     * <h2>传统的方式实现对资源的关闭</h2>
     * */
    private String traditionalTryCatch() throws IOException {

        // 1. 单一资源的关闭
//        String line = null;
//        BufferedReader br = new BufferedReader(new FileReader(""));
//        try {
//            line = br.readLine();
//        } finally {
//            br.close();
//        }
//        return line;

        // 2. 多个资源的关闭
        // 第一个资源
        InputStream in = new FileInputStream("");
        try {
            // 第二个资源
            OutputStream out = new FileOutputStream("");
            try {
                byte[] buf = new byte[100];
                int n;

                while ((n = in.read(buf)) >= 0)
                    out.write(buf, 0, n);
            } finally {
                out.close();
            }
        } finally {
            in.close();
        }

        return null;
    }

    /**
     * <h2>java7 引入的 try with resources 实现自动的资源关闭</h2>
     * */
    private String newTryWithResources() throws IOException {

        // 1. 单个资源的使用与关闭
//        try (BufferedReader br = new BufferedReader(new FileReader(""))) {
//            return br.readLine();
//        }

        // 2. 多个资源的使用与关闭
        try (FileInputStream in = new FileInputStream("");
             FileOutputStream out = new FileOutputStream("")
        ) {
            byte[] buffer = new byte[100];
            int n = 0;
            while ((n = in.read(buffer)) != -1) {
                out.write(buffer, 0, n);
            }
        }
        return null;
    }

    public static void main(String[] args) throws MyException {

//        AutoClose autoClose = new AutoClose();
//        try {
//            autoClose.work();
//        } finally {
//            autoClose.close();
//        }

        try (AutoClose autoClose = new AutoClose()) {
            autoClose.work();
        }
    }
}

package com.imooc.java.escape.try_with_resources;

public class MyException extends Exception {

    public MyException() {
        super();
    }

    public MyException(String message) {
        super(message);
    }
}

package com.imooc.java.escape.try_with_resources;

public class AutoClose implements AutoCloseable {

    @Override
    public void close() {
        System.out.println(">>> close()");
        throw new RuntimeException("Exception in close()");
    }

    public void work() throws MyException {
        System.out.println(">>> work()");
        throw new MyException("Exception in work()");
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值