<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JDK的3個(gè)bug

          共 3908字,需瀏覽 8分鐘

           ·

          2021-09-10 11:17

          作者:孤獨(dú)的探索號(hào)  

          來源地址:my.oschina.net/tommylemon/blog/2967187


          1.Annotation引用非空enum數(shù)組返回空數(shù)組

          首次發(fā)現(xiàn)時(shí)的環(huán)境:JDK 1.8

          首次發(fā)現(xiàn)所在項(xiàng)目:APIJSON

          測試用例:

          public enum RequestRole {

           /**未登錄,不明身份的用戶
            */

           UNKNOWN,

           /**已登錄的用戶
            */

           LOGIN,

           /**聯(lián)系人,必須已登錄
            */

           CONTACT,

           /**圈子成員(CONTACT + OWNER),必須已登錄
            */

           CIRCLE,

           /**擁有者,必須已登錄
            */

           OWNER,

           /**管理員,必須已登錄
            */

           ADMIN;

           //似乎不管怎么做,外部引用后都是空值。并且如果在注解內(nèi)的位置不是最前的,還會(huì)導(dǎo)致被注解的類在其它類中import報(bào)錯(cuò)。
           //雖然直接打印顯示正常,但被@MethodAccess內(nèi)RequestRole[] GET()等方法引用后獲取的是空值
           public static final RequestRole[] ALL = {RequestRole.UNKNOWN};//values();//所有
           public static final RequestRole[] HIGHS;//高級(jí)
           static {
             HIGHS = new RequestRole[] {OWNER, ADMIN};
           }

           public static final String[] NAMES = {
               UNKNOWN.name(), LOGIN.name(), CONTACT.name(), CIRCLE.name(), OWNER.name(), ADMIN.name()
           };


          }


          @MethodAccess(
             GETS = RequestRole.ALL,
             HEADS = RequestRole.HIGHS
             )
          public class Verify {

          }


          public class DemoVerifier {
           // <TableName, <METHOD, allowRoles>>
           // <User, <GET, [OWNER, ADMIN]>>
             public static final Map<String, Map<RequestMethod, RequestRole[]>> ACCESS_MAP;
           static { //注冊(cè)權(quán)限
                 ACCESS_MAP = new HashMap<String, Map<RequestMethod, RequestRole[]>>();
             ACCESS_MAP.put(Verify.class.getSimpleName(), getAccessMap(Verify.class.getAnnotation(MethodAccess.class)));
           }

           public static HashMap<RequestMethod, RequestRole[]> getAccessMap(MethodAccess access) {
             if (access == null) {
               return null;
             }

             HashMap<RequestMethod, RequestRole[]> map = new HashMap<>();
             map.put(GET, access.GET());
             map.put(HEAD, access.HEAD());
             map.put(GETS, access.GETS());
             map.put(HEADS, access.HEADS());
             map.put(POST, access.POST());
             map.put(PUT, access.PUT());
             map.put(DELETE, access.DELETE());

             return map;
           }

          }

          解決方案:

          不抽象數(shù)組常量ALL,HIGHTS等,而是在每個(gè)用到的地方硬編碼寫死具體的值。

          2.ArrayList可通過構(gòu)造函數(shù)傳入非指定泛型的List并在get時(shí)出錯(cuò)

          首次發(fā)現(xiàn)時(shí)的環(huán)境:JDK 1.7

          首次發(fā)現(xiàn)所在項(xiàng)目:APIJSON

          測試用例:

          JSONArray arr = new JSONArray(); //com.alibaba.fastjson.JSONArray
          arr.add("s");

          List<Long> list = new ArrayList<>(arr);
          list.get(0); //Exception cannot cast String to Long

          解決方案:

          1.改用 Open JDK8

          2.升級(jí) JDK

          注:后面多次測試,已無法復(fù)現(xiàn)。

          3.基本類型在三元表達(dá)式內(nèi)可賦值為null,編譯通過但運(yùn)行出錯(cuò)

          首次發(fā)現(xiàn)時(shí)的環(huán)境:JDK 1.7

          測試用例:

          int i = true ? null : 0; //Exception in thread "main" java.lang.NullPointerException

          首次發(fā)現(xiàn)所在項(xiàng)目:ZBLibrary

          解決方案:

          在給基礎(chǔ)類型用3元表達(dá)式賦值時(shí),null 先轉(zhuǎn)為基礎(chǔ)類型的默認(rèn)值。

          最后再提2個(gè)不是bug,但容易引發(fā)編程bug的問題:

          1.局部變量和同名的全局變量能在一個(gè)方法內(nèi),編譯通過,運(yùn)行也正常。

          public class Test {
                 
                 int val;
                 @Override
                 public String toString() {
                     val = 1;
                     String val = "";
                     return super.toString();
                 }
             }

          如果兩個(gè)變量中間隔了比較長的其它代碼,很可能會(huì)導(dǎo)致開發(fā)人員將兩者混淆,導(dǎo)致邏輯認(rèn)知錯(cuò)誤,從而寫出或改出有問題的代碼。

          解決方案:

          命名局部變量前先搜素,確保沒有已聲明的同名全局變量。

          2. (非 JDK bug)Gson 通過 TypeToken 轉(zhuǎn)換 List<T> 能寫入不屬于 T 類型的數(shù)據(jù),get 出來賦值給 T 類型的變量/常量報(bào)錯(cuò)。

          String json = "[1, '2', 'a']";
                 Type type = new TypeToken<Integer>(){}.getType();
                 Gson gson = new Gson();
                 List<Integer> list = gson.fromJson(json, type);
                 
                 Integer i = list == null || list.isEmpty() ? null : list.get(1); //Exception cannot cast String to Integer

          解決方案:

          1.手動(dòng)檢查列表內(nèi)數(shù)據(jù)都符合泛型 T

          2.改用 fastjson 等其它能靜態(tài)檢查類型的庫。


          瀏覽 28
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级黄色片免费观看 | 波多野结衣无码电影 | 无码人妻精品一区二区蜜桃在线看 | 日本大乳高潮视频在线观看 | 草草影院国产第一页 |