最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

分享一個(gè)你不知道的Java異常實(shí)現(xiàn)的缺陷

 更新時(shí)間:2022年12月07日 11:29:53   作者:程序員濟(jì)癲  
Java中一個(gè)大家熟知的知識點(diǎn)就是異常捕獲,try...catch...finally組合,但是很多人不知道這里面有一個(gè)關(guān)于Java的缺陷,或者說是異常實(shí)現(xiàn)的一點(diǎn)不足之處。本文就通過一個(gè)很簡單的實(shí)驗(yàn)給大家演示下效果玩玩兒,希望大家能覺得有趣

前言

Java中一個(gè)大家熟知的知識點(diǎn)就是異常捕獲,try...catch...finally組合,但是很多人不知道這里面有一個(gè)關(guān)于Java的缺陷,或者說是異常實(shí)現(xiàn)的一點(diǎn)不足之處。

我這邊就通過一個(gè)很簡單的實(shí)驗(yàn)給大家演示下效果玩玩兒,希望大家能覺得有趣。

模擬

1、自定義異常

這里,我們首先寫一個(gè)自定義業(yè)務(wù)異常,專門用來拋出。

/**
 * <p>
 * 自定義業(yè)務(wù)異常
 * </p>
 *
 * @author 程序員濟(jì)癲,公眾號:【Java分享客棧】
 * @since 2022/12/6 19:20
 */
public class BusinessException extends RuntimeException {
   public BusinessException() {
      super();
   }

   public BusinessException(String errMsg) {
      super(errMsg);
   }

   public BusinessException(String errMsg, Throwable throwable) {
      super(errMsg, throwable);
   }

}

2、模擬異常

然后,我們寫個(gè)測試方法來捕獲并拋出空指針異常。

/**
 * <p>
 * 測試異常缺陷
 * </p>
 *
 * @author 程序員濟(jì)癲,公眾號:【Java分享客?!?
 * @since 2022/12/6 19:22
 */
@Slf4j
public class ExceptionTest {
   public static void main(String[] args) {
      try {
         UserInfo userInfo = null;
         System.err.println(userInfo.getName());
      } catch (Exception ex) {
         throw new BusinessException("捕獲try的異常: " + ex.getMessage());
      }
   }
}

看下效果,OK沒問題。

接下來,我們加上finally看看。

/**
 * <p>
 * 測試異常缺陷
 * </p>
 *
 * @author 程序員濟(jì)癲,公眾號:【Java分享客?!?
 * @since 2022/12/6 19:22
 */
@Slf4j
public class ExceptionTest {
   public static void main(String[] args) {
      try {
         UserInfo userInfo = null;
         System.err.println(userInfo.getName());
      } catch (Exception ex) {
         throw new BusinessException("捕獲try的異常: " + ex.getMessage());
      } finally {
         System.err.println("----------finally最終執(zhí)行---------");
      }
   }
}

看下效果,OK也沒問題。

接下來我們這么做,在finally中拋出一個(gè)異常。

/**
 * <p>
 * 測試異常缺陷
 * </p>
 *
 * @author 程序員濟(jì)癲,公眾號:【Java分享客?!?
 * @since 2022/12/6 19:22
 */
@Slf4j
public class ExceptionTest {
   public static void main(String[] args) {
      try {
         UserInfo userInfo = null;
         System.err.println(userInfo.getName());
      } catch (Exception ex) {
         throw new BusinessException("捕獲try的異常: " + ex.getMessage());
      } finally {
         System.err.println("----------finally最終執(zhí)行---------");
         throw new BusinessException("覆蓋catch的異常");
      }
   }
}

看下效果,發(fā)現(xiàn)catch的異常竟然被覆蓋了。

雖然這種場景很特殊,但這其實(shí)就是Java在異常實(shí)現(xiàn)上美中不足的地方,因?yàn)楫惓J亲鳛槌绦虺鲥e(cuò)的標(biāo)志絕對不應(yīng)忽略,可是這種場景下異常的的確確丟失了。

接下來,我們再測試一種情況,在finally中使用return,看看會(huì)發(fā)生什么。

/**
 * <p>
 * 測試異常缺陷
 * </p>
 *
 * @author 程序員濟(jì)癲,公眾號:【Java分享客棧】
 * @since 2022/12/6 19:22
 */
@Slf4j
public class ExceptionTest {
   public static void main(String[] args) {
      try {
         UserInfo userInfo = null;
         System.err.println(userInfo.getName());
      } catch (Exception ex) {
         throw new BusinessException("捕獲try的異常: " + ex.getMessage());
      } finally {
         System.err.println("----------finally最終執(zhí)行---------");
         return;
      }
   }
}

看看效果,發(fā)現(xiàn)catch中捕獲的異常干脆直接沒了,仿佛從沒來過。

最后,我們再演示一種你可能工作中干過或者見過的莫名其妙的事情。

我們修改一下這個(gè)測試方法,看代碼。

/**
 * <p>
 * 測試異常缺陷
 * </p>
 *
 * @author 程序員濟(jì)癲,公眾號:【Java分享客?!?
 * @since 2022/12/6 19:22
 */
@Slf4j
public class ExceptionTest {
   public static void main(String[] args) {
      try {
         // 調(diào)用其他類的查詢方法
         queryData();
      } catch (Exception ex) {
         // 捕獲這個(gè)查詢方法拋出的異常
         throw new BusinessException(ex.getMessage());
      }
   }

   private static void queryData() {
      try {
         // 這個(gè)方法剛好你也try..catch了,并且在finally中做了一些末尾必須執(zhí)行的業(yè)務(wù)邏輯處理。
         UserInfo userInfo = null;
         System.err.println(userInfo.getName());
      } finally {
         doSomething();
      }
   }

   private static void doSomething() {
      // 業(yè)務(wù)處理過程中你同樣習(xí)慣性地拋出了某個(gè)業(yè)務(wù)異常
      System.err.println("--------處理末尾業(yè)務(wù)--------");
      throw new BusinessException("處理末尾業(yè)務(wù)拋出邏輯異常");
   }
}

簡單描述一下,你調(diào)用其他類的一個(gè)查詢方法,那個(gè)方法可能習(xí)慣性的try..catch..finally了,而finally中還做了一些末尾必須要執(zhí)行的操作,這個(gè)業(yè)務(wù)邏輯處理可能有幾十行,你很可能又習(xí)慣性的做了一些判斷以及異常的拋出。

別不相信,當(dāng)一個(gè)項(xiàng)目進(jìn)入中期甚至趕進(jìn)度的時(shí)候,方法套方法,不少人已經(jīng)在機(jī)械的茫然的寫代碼,也可能是在別人的基礎(chǔ)上改代碼,你很可能不會(huì)太仔細(xì)地一行一行去看那些代碼里究竟有什么,恰巧測試的時(shí)候也沒出什么大問題。

那么結(jié)果可能就是下面這樣,你會(huì)發(fā)現(xiàn)自己一開始特意拋出的那個(gè)捕獲該查詢方法異常的玩意兒沒一點(diǎn)效果,也不知道去哪兒了,怎么找也找不到,不知從哪兒冒出來下面這個(gè)莫名其妙的異常,后來想不到也就算了。

原因

這其實(shí)就是Java異常實(shí)現(xiàn)的一個(gè)不足,異常是程序出錯(cuò)的標(biāo)志,怎么都不應(yīng)該被忽略掉,更不用說是finally這種常用的行為,直接或間接地造成了異常的丟失。

《Thinking In Java》的作者有明確指出這個(gè)異常,認(rèn)為這是相當(dāng)嚴(yán)重的缺陷,是一個(gè)可能造成異常完全丟失的缺陷,而且是以一種更微妙、更難以察覺的方式在進(jìn)行。

而C++就處理的很好,會(huì)將這種在第一個(gè)異常被處理之前拋出第二個(gè)異常的情況視為嚴(yán)重的編程錯(cuò)誤。

總結(jié)

知道了這個(gè)缺陷后,其實(shí)就很好避免了。

1、避免在finally中拋出異常;

2、避免在finally中使用return;

3、catch中一定要養(yǎng)成log.error記錄異常日志的好習(xí)慣,因?yàn)閘og是一定會(huì)記錄下來的,至少不會(huì)讓你毫無線索。

結(jié)尾再演示下加了日志的效果,只要是catch我都加上日志,那么一定不會(huì)錯(cuò)過。

到此這篇關(guān)于分享一個(gè)你不知道的Java異常實(shí)現(xiàn)的缺陷的文章就介紹到這了,更多相關(guān)Java異常實(shí)現(xiàn)缺陷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java項(xiàng)目Guava包?HashMultimap使用及注意事項(xiàng)

    Java項(xiàng)目Guava包?HashMultimap使用及注意事項(xiàng)

    guava基本上可以說是java開發(fā)項(xiàng)目中,大概率會(huì)引入的包,今天介紹的主角是一個(gè)特殊的容器HashMultmap,可以簡單的將它的數(shù)據(jù)結(jié)構(gòu)理解為Map<K,?Set<V>>,今天主要介紹下基礎(chǔ)的知識點(diǎn)?HashMultmap級使用,感興趣的朋友一起看看吧
    2022-05-05
  • Spring ApplicationListener源碼解析

    Spring ApplicationListener源碼解析

    這篇文章主要為大家介紹了Spring ApplicationListener源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 關(guān)于Maven的使用,這些你都真的了解么

    關(guān)于Maven的使用,這些你都真的了解么

    這篇文章主要介紹了關(guān)于Maven的使用,這些你都真的了解么?具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java泛型最全知識總結(jié)

    Java泛型最全知識總結(jié)

    面試被問到Java泛型怎么辦,有了這篇文章,讓你直接保送,文中有非常詳細(xì)的知識總結(jié)及相關(guān)代碼示例,需要的朋友可以參考下
    2021-06-06
  • Servlet中配置和使用過濾器的步驟記錄

    Servlet中配置和使用過濾器的步驟記錄

    這篇文章主要介紹了在Servlet中配置和使用過濾器的方法,包括創(chuàng)建過濾器類、配置過濾器以及在Web應(yīng)用中使用過濾器等步驟,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-01-01
  • java rocketmq--消息的產(chǎn)生(普通消息)

    java rocketmq--消息的產(chǎn)生(普通消息)

    這篇文章主要介紹了java rocketmq--消息的產(chǎn)生(普通消息),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下
    2019-06-06
  • Java基礎(chǔ)知識之StringWriter流的使用

    Java基礎(chǔ)知識之StringWriter流的使用

    這篇文章主要介紹了Java基礎(chǔ)知識之StringWriter流的使用,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 使用Sentinel實(shí)現(xiàn)流控和服務(wù)降級的代碼示例

    使用Sentinel實(shí)現(xiàn)流控和服務(wù)降級的代碼示例

    Sentinel是面向分布式、多語言異構(gòu)化服務(wù)架構(gòu)的流量治理組件,本文將詳細(xì)為大家介紹如何使用Sentinel實(shí)現(xiàn)流控和服務(wù)降級,文中有相關(guān)的代碼示例,需要的朋友可以參考下
    2023-05-05
  • JAVA8 的StringJoiner 使用及原理解析

    JAVA8 的StringJoiner 使用及原理解析

    這篇文章主要介紹了JAVA8 的StringJoiner 使用及原理解析,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • 基于SpringBoot實(shí)現(xiàn)郵箱找回密碼的代碼示例

    基于SpringBoot實(shí)現(xiàn)郵箱找回密碼的代碼示例

    本文主要介紹了如何基于SpringBoot實(shí)現(xiàn)郵箱找回密碼,文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02

最新評論

册亨县| 廊坊市| 仲巴县| 南宫市| 绥江县| 板桥市| 六枝特区| 永城市| 洛川县| 江山市| 桂东县| 尼玛县| 林芝县| 浦北县| 措美县| 贵州省| 垫江县| 宁南县| 来宾市| 贞丰县| 全南县| 奉新县| 嵊州市| 金湖县| 阜宁县| 沙河市| 平阴县| 利辛县| 营口市| 曲水县| 肇庆市| 密山市| 武宣县| 镇雄县| 中西区| 长垣县| 班玛县| 东平县| 林芝县| 儋州市| 抚顺县|