优雅编程之这样处理异常,你就“正常”了!

开心一笑

【一交警在开罚单,一男子叼着烟过来喊:你除了开罚单还会干什么?

交警没理睬,男子继续:有种拖走啊!

交警很愤怒,男子继续:有种拖走啊!

交警忍无可忍拿出对讲机,拖车时交 警和蔼说:下午到五大队来处理!

男子:关我鸟事!车又不是我的!

说完哼着小曲骑着电瓶车走了】

提出问题

如何处理异常才能使代码更简洁???

解决问题

1)使用异常而非返回码,这里的异常处理就是我们经常写的try catch;

package com.hwy.test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CodeCleanTest {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    public boolean eat(){

        boolean isCompleted = false;

        try{
            System.out.println("美味");
            isCompleted = true;
        }catch (Exception e){
            log.info(e.getMessage());
        }

        return isCompleted;
    }

}

2)不要返回null值:这样的话调用者就要处理null,增加工作量;解决:抛出异常或者返回特例对象(利用Collections.emptyList());

错误示例:

package com.hwy.test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;

public class CodeCleanTest {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 约会
     */
    public void datWithGirl(){
        List<String> snacksList =  buySnacks();
        if(null != snacksList){
            List<String> litter =  eatSnacks(snacksList);
            dropLitter(litter);
        }
    }

    /**
     * 买零食(事实这些注释都是不需要,只是为了大家理解)
     * @return
     */
    public List<String> buySnacks(){

        List<String> snacksList = new ArrayList<>();
        snacksList.add("牛奶");
        snacksList.add("巧克力");
        snacksList.add("土豆片");
        return snacksList;
    }

    /**
     * 吃零食(事实这些注释都是不需要,只是为了大家理解)
     * @param snacks
     */
    public List<String> eatSnacks(List<String> snacks){
        if(null != snacks) {
            for (String snack : snacks) {
                System.out.println("一起吃" + snack);
            }
        }
        return snacks;
    }

    /**
     * 仍垃圾(事实这些注释都是不需要,只是为了大家理解)
     * @param litter
     */
    public void dropLitter(List<String> litter){

        if(null != litter){
            for(String snack:litter){
                System.out.println("一起吃" + snack);
            }
        }
    }
}

正确示例:可看里面详细的注释,要有耐心哦!

package com.hwy.test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;

public class CodeCleanTest {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 约会
     */
    public void datWithGirl() throws Exception {
        List<String> snacksList =  buySnacks();
        /** 利用逆向思维,抛出一个业务异常,这里我只是用简单的exception代替 **/
        if(null == snacksList || snacksList.size() ==0){
            throw new Exception("你没买到零食或买到的零食有问题,请检查!");
        }
        /** 代码执行到这一步就说明snacksList不为null,之后的所有
         * 操作都不用判断snacksList是否为空 **/
        List<String> litter =  eatSnacks(snacksList);
        dropLitter(litter);
    }

    /**
     * 买零食(事实这些注释都是不需要,只是为了大家理解)
     * @return
     */
    public List<String> buySnacks(){

        List<String> snacksList = new ArrayList<>();
        snacksList.add("牛奶");
        snacksList.add("巧克力");
        snacksList.add("土豆片");

        /** 在这里如果snacksList为空的话,可以用Collections.emptyList(),就不用
        ** 在上面处理异常了 **/
        //return Collections.emptyList();
        return snacksList;
    }

    /**
     * 吃零食(事实这些注释都是不需要,只是为了大家理解)
     * @param snacks
     */
    public List<String> eatSnacks(List<String> snacks){
        for (String snack : snacks) {
            System.out.println("一起吃" + snack);
        }
        return snacks;
    }

    /**
     * 仍垃圾(事实这些注释都是不需要,只是为了大家理解)
     * @param litter
     */
    public void dropLitter(List<String> litter){

        for(String snack:litter){
            System.out.println("一起吃" + snack);
        }
    }
}

3)在方法中返回null值是很糟糕的,但讲null传递给其他方法就更糟糕了,具体解决方法如下:

package com.hwy.test;

import org.junit.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;

public class CodeCleanTest {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    public static void main(String[] args) throws Exception {
        datWithGirl();
    }

    /**
     * 约会
     */
    public static void datWithGirl(){
        /** 这里返回为null **/
        List<String> snacksList =  buySnacks();
        /** 在吃零食方法中,需要处理异常 **/
        List<String> litter =  eatSnacks(snacksList);
        dropLitter(litter);
    }

    /**
     * 买零食(事实这些注释都是不需要,只是为了大家理解)
     * @return
     */
    public static List<String> buySnacks(){
        return null;
    }

    /**
     * 吃零食(事实这些注释都是不需要,只是为了大家理解)
     * @param snacks
     */
    public static List<String> eatSnacks(List<String> snacks){

        /** 第一种处理方法 **/
//        if(null == snacks){
//            throw new NullPointerException("没有零食吃!!!");
//        }

        /** 第二种处理方法, **/
        Assert.assertNotNull("没有零食吃!!!",snacks);
        for (String snack : snacks) {
            System.out.println("一起吃" + snack);
        }
        return snacks;
    }

    /**
     * 仍垃圾(事实这些注释都是不需要,只是为了大家理解)
     * @param litter
     */
    public static void dropLitter(List<String> litter){
        for(String snack:litter){
            System.out.println("一起吃" + snack);
        }
    }
}

运行结果:

java.lang.AssertionError: 没有零食吃!!!
at org.junit.Assert.fail(Assert.java:93)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertNotNull(Assert.java:526)
at com.hwy.test.CodeCleanTest.eatSnacks(CodeCleanTest.java:48)
at com.hwy.test.CodeCleanTest.datWithGirl(CodeCleanTest.java:23)
at com.hwy.test.CodeCleanTest.main(CodeCleanTest.java:13)

4)不管做哪种类型的应用,都应该尽可能向用户隐藏异常的发生,除非发生了不可挽救的状况,这才是符合最小惊讶原则的设计

5)异常的信息应该足够充分(包含出错的位置以及原因)

6)避免使用可控异常(checked exception):因为处理它们需要修改函数头(在每个调用该函数的函数添加throw Exception),违反了开放-闭合原则;应该使用不可控异常(runtime exception);

读书感悟

来自《峰与谷》

  • 在我们的工作和生活中,每个人都会遭遇高峰和低谷,这是人生的常态。
  • 看着你所失去的,你就会跌入不幸的谷底;看着你所拥有的,你就会处在幸福的高峰。
  • 征服内心的恐惧,就意味着你处在人生的高峰状态。
  • 上天之所以制造苦难,是为了唤醒你的觉知——要关注那些被你忽视的真相。
  • 通过制订愿景来攀登高峰是一个好办法。它能够让你产生一种渴望,并且愿意用自己的行动把愿景变成现实。
  • 从高峰上迅速跌落低谷的原因,往往是不了解真相的骄傲自满;在低谷里无法重新振作的原因,往往是不了解真相的忧虑恐惧。
  • 高峰和低谷不仅是外部的顺境和逆境,更是你内心深处的感觉和变化。
  • 每一个人选择好心态的时候,就意味着他将要离开人生的谷底。
  • 人生的高原期是用来休养生息、深思熟虑和自我更新的时期。
  • 峰谷相连不分。今日顺境之错,换得他日逆境;今日逆境之智,换得他日顺境。

其他

如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎转载,点赞,顶,欢迎留下宝贵的意见,多谢支持!

时间: 2024-12-30 02:09:54

优雅编程之这样处理异常,你就“正常”了!的相关文章

T-SQL编程中的异常处理-异常捕获(try catch)与抛出异常(throw)

原文:T-SQL编程中的异常处理-异常捕获(try catch)与抛出异常(throw) 本文出处: http://www.cnblogs.com/wy123/p/6743515.html T-SQL编程与应用程序一样,都有异常处理机制,比如异常的捕获与异常的抛出(try catch throw),本文简单介绍异常捕获与异常抛出在T-SQL编程中的实际使用 . 异常处理简单说明 异常捕获在应用程序编程中非常常见,提供了处理程序运行时出现的任何意外或异常情况的方法刚毕业的时候对于异常处理迷茫不解,

select返回值可以这样子优雅编程

以前的代码: void Select(){    fd_set  fdSet;    static struct timeval tv;    tv.tv_sec=0;    tv.tv_usec = 500000;//采用select每500毫秒轮询一次查询是否有WEB写入FIFO的告警    FD_ZERO(&fdSet);    FD_SET(m_fd,&fdSet);    int nSelectRet=select((m_fd+1),&fdSet,NULL,NULL,&a

【优雅编程之道】之方法的9点建议

开心一笑 [一个去看演出的朋友回来了. 我问他:"怎么样演出好看吗?" 朋友:"人太多了,我去晚了,在后面什么也看不见,只能跳起来看几眼, 后来跳累了就不看了,也没有什么好看的." 这时我另外一个朋友也回来了. 我:"你也看戏去了?" 另外一个朋友:"恩!" 我:"好不好看?" 另外一个朋友:"好看个屁!戏没看多少,就看见前面一个SB在那里跳来跳去的!"] 提出问题 项目中如何优雅编写方

优雅编程之这样写测试用例,你就”正常“了!

开心一笑 [朋友病了,要挂盐水.给他扎针的是一个实习小护士,扎了半天都没扎进血管. 他痛得龇牙咧嘴,无奈叫来了护士长. 护士长好手法,只见她一针见血地扎进了血管,然后马上拔出来, 把针递给那个实习护士说:"看清楚没有?你再试一次!"] 提出问题 如何优雅编写测试代码??? 解决问题 1)TDD(测试驱动开发),意思是先写单元测试,然后写对应的代码,通过修改调试让写的代码通过单元测试.使用TDD,会使测试覆盖所有的代码,测试代码和生产代码的比例有可能会达到1:1 ,所以也会带来成本的问题

《java编程思想》:异常丢失

finally子句的不恰当使用,会造成异常的丢失,此处列举两种典型的错误使用示例.编程中要避免这种情况 示例一: try{ throw new ExceptionA(); }finally{ throw new ExceptionB(); } 缺少catch语句,缺少对A异常的捕获,导致A异常丢失 示例二: public void test(){ try{ throw new ExceptionA(); }finally{ return; } } 缺少catch语句,缺少对A异常的捕获,fina

使用Java实现面向对象编程——第四章 异常

1. 接口:接口就是给出一些没有内容的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来. 接口是更加抽象的抽象的类, 抽象类里的方法可以有方法体, 接口里的所有方法都没有方法体. 接口体现了程序设计的多态和高内聚低偶合的设计思想. 接口是一种规范和标准,他们可以约束类的行为,是一些方法特征的集合,但是没有方法的实现. 接口可以看作一种特殊的"抽象类",但是采用与抽象类按群不同的语法来表示: 抽象类有利于代码的重用,接口有利于代码的扩展和维护: 接口的特性: 接口不

Java编程的逻辑 (24) - 异常 (上)

之前我们介绍的基本类型.类.接口.枚举都是在表示和操作数据,操作的过程中可能有很多出错的情况,出错的原因可能是多方面的,有的是不可控的内部原因,比如内存不够了.磁盘满了,有的是不可控的外部原因,比如网络连接有问题,更多的可能是程序的编程错误,比如引用变量未初始化就直接调用实例方法. 这些非正常情况在Java中统一被认为是异常,Java使用异常机制来统一处理,由于内容较多,我们分为两节来介绍,本节介绍异常的初步概念,以及异常类本身,下节主要介绍异常的处理. 我们先来通过一些例子认识一下异常. 初始

Retrofit+RxJava 优雅的处理服务器返回异常、错误

开始本博客之前,请先阅读: Retrofit请求数据对错误以及网络异常的处理 异常&错误 实际开发经常有这种情况,比如登录请求,接口返回的 信息包括请求返回的状态:失败还是成功,错误码,User对象等等.如果网络等原因引起的登录失败可以归结为异常,如果是用户信息输入错误导致的登录失败算是错误. 假如服务器返回的是统一数据格式: /** * 标准数据格式 * @param <T> */ public class Response<T> { public int state;

3.C#/.NET编程中的常见异常(持续更新)

1.Object reference not set to an instance of an object. 未将对象引用(引用)到对象的实例,说白了就是有个对象为null,但是你在用它点出来的各种东西. 2.An entity object cannot be referenced by multiple instances of IEntityChangeTracker. 一个实体对象不能由多个IEntityChangeTracker实例引用.首先参见MSDN中对于Entity Frame