JDK的3个bug

1.Annotation引用非空enum数组返回空数组

首次发现时的环境:JDK 1.8

首次发现所在项目:APIJSON

测试用例:

1public enum RequestRole { 2 3 /**未登录,不明身份的用户 4 */ 5 UNKNOWN, 6 7 /**已登录的用户 8 */ 9 LOGIN, 10 11 /**联系人,必须已登录 12 */ 13 CONTACT, 14 15 /**圈子成员(CONTACT + OWNER),必须已登录 16 */ 17 CIRCLE, 18 19 /**拥有者,必须已登录 20 */ 21 OWNER, 22 23 /**管理员,必须已登录 24 */ 25 ADMIN; 26 27 //似乎不管怎么做,外部引用后都是空值。并且如果在注解内的位置不是最前的,还会导致被注解的类在其它类中import报错。 28 //虽然直接打印显示正常,但被@MethodAccess内RequestRole[] GET()等方法引用后获取的是空值 29 public static final RequestRole[] ALL = {RequestRole.UNKNOWN};//values();//所有 30 public static final RequestRole[] HIGHS;//高级 31 static { 32 HIGHS = new RequestRole[] {OWNER, ADMIN}; 33 } 34 35 public static final String[] NAMES = { 36 UNKNOWN.name(), LOGIN.name(), CONTACT.name(), CIRCLE.name(), OWNER.name(), ADMIN.name() 37 }; 38 39 40} 41 42 43@MethodAccess( 44 GETS = RequestRole.ALL, 45 HEADS = RequestRole.HIGHS 46 ) 47public class Verify { 48 49} 50 51 52public class DemoVerifier { 53 // <TableName, <METHOD, allowRoles>> 54 // <User, <GET, [OWNER, ADMIN]>> 55 public static final Map<String, Map<RequestMethod, RequestRole[]>> ACCESS_MAP; 56 static { //注册权限 57 ACCESS_MAP = new HashMap<String, Map<RequestMethod, RequestRole[]>>(); 58 ACCESS_MAP.put(Verify.class.getSimpleName(), getAccessMap(Verify.class.getAnnotation(MethodAccess.class))); 59 } 60 61 public static HashMap<RequestMethod, RequestRole[]> getAccessMap(MethodAccess access) { 62 if (access == null) { 63 return null; 64 } 65 66 HashMap<RequestMethod, RequestRole[]> map = new HashMap<>(); 67 map.put(GET, access.GET()); 68 map.put(HEAD, access.HEAD()); 69 map.put(GETS, access.GETS()); 70 map.put(HEADS, access.HEADS()); 71 map.put(POST, access.POST()); 72 map.put(PUT, access.PUT()); 73 map.put(DELETE, access.DELETE()); 74 75 return map; 76 } 77 78}

解决方案:

不抽象数组常量ALL,HIGHTS等,而是在每个用到的地方硬编码写死具体的值。

2.ArrayList可通过构造函数传入非指定泛型的List并在get时出错

首次发现时的环境:JDK 1.7

首次发现所在项目:APIJSON

测试用例:

1JSONArray arr = new JSONArray(); //com.alibaba.fastjson.JSONArray 2arr.add("s"); 3 4List<Long> list = new ArrayList<>(arr);  5list.get(0); //Exception cannot cast String to Long

解决方案:

1.改用 Open JDK8

2.升级 JDK

注:后面多次测试,已无法复现。

3.基本类型在三元表达式内可赋值为null,编译通过但运行出错

首次发现时的环境: JDK 1.7

测试用例:

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

首次发现所在项目:ZBLibrary

解决方案:

在给基础类型用3元表达式赋值时,null 先转为基础类型的默认值。

最后再提2个不是bug,但容易引发编程bug的问题:

1.局部变量和同名的全局变量能在一个方法内,编译通过,运行也正常。

1    public class Test { 2         3        int val; 4        @Override 5        public String toString() { 6            val = 1; 7            String val = ""; 8            return super.toString(); 9        } 10    }

如果两个变量中间隔了比较长的其它代码,很可能会导致开发人员将两者混淆,导致逻辑认知错误,从而写出或改出有问题的代码。

解决方案:

命名局部变量前先搜素,确保没有已声明的同名全局变量。

2. (非 JDK bug)Gson 通过 TypeToken 转换 List<T> 能写入不属于 T 类型的数据,get 出来赋值给 T 类型的变量/常量报错。

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

解决方案:

1.手动检查列表内数据都符合泛型 T

2.改用 fastjson 等其它能静态检查类型的库。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )