发现JDK的3个bug
1.Annotation引用非空enum数组返回空数组
首次发现时的环境:JDK 1.8
首次发现所在项目:APIJSON
测试用例:
public enum RequestRole {
/**未登录,不明身份的用户
*/
UNKNOWN,
/**已登录的用户
*/
LOGIN,
/**联系人,必须已登录
*/
CONTACT,
/**圈子成员(CONTACT + OWNER),必须已登录
*/
CIRCLE,
/**拥有者,必须已登录
*/
OWNER,
/**管理员,必须已登录
*/
ADMIN;
//似乎不管怎么做,外部引用后都是空值。并且如果在注解内的位置不是最前的,还会导致被注解的类在其它类中import报错。
//虽然直接打印显示正常,但被@MethodAccess内RequestRole[] GET()等方法引用后获取的是空值
public static final RequestRole[] ALL = {RequestRole.UNKNOWN};//values();//所有
public static final RequestRole[] HIGHS;//高级
static {
HIGHS = new RequestRole[] {OWNER, ADMIN};
}
public static final String[] NAMES = {
UNKNOWN.name(www.mhylpt.com), LOGIN.name(www.thd540.com/), CONTACT.name(www.feifanyule.cn/), 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 { //注册权限
ACCESS_MAP =www.michenggw.com new HashMap<String, Map<RequestMethod, RequestRole[]>>();
ACCESS_MAP.put(Verify.class.getSimpleName(www.yigouyule2.cn), 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;
}
}
解决方案:
不抽象数组常量ALL,HIGHTS等,而是在每个用到的地方硬编码写死具体的值。
2.ArrayList可通过构造函数传入非指定泛型的List并在get时出错
首次发现时的环境:JDK 1.7
首次发现所在项目:APIJSON
测试用例:
JSONArray arr = new JSONArray(); //com.alibaba.fastjson.JSONArray
arr.add("s");
List<Long> list = new ArrayList<>(arr);
list.get(0); //throw new IllegalArgumentException
解决方案:
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.局部变量和同名的全局变量能在一个方法内,编译通过,运行也正常。
public class Test {
int val;
@Override
public String toString() {
val = 1;
String val = "";
return super.toString();
}
}
如果两个变量中间隔了比较长的其它代码,很可能会导致开发人员将两者混淆,导致逻辑认知错误,从而写出或改出有问题的代码。
解决方案:
命名局部变量前先搜素,确保没有已声明的同名全局变量。
2. (非 JDK bug)Gson 通过 TypeToken 转换 List<T> 能写入不属于 T 类型的数据,get 出来赋值给 T 类型的变量/常量报错。
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(0); //Exception cannot cast String to Integer
解决方案:
1.手动检查列表内数据都符合泛型 T
2.改用 fastjson 等其它能静态检查类型的库。
发现JDK的3个bug的更多相关文章
- 应用服务器中对JDK的epoll空转bug的处理
原文链接:应用服务器中对JDK的epoll空转bug的处理 前面讲到了epoll的一些机制,与select和poll等传统古老的IO多路复用机制的一些区别,这些区别实质可以总结为一句话, 就是epol ...
- 给JDK提的一个bug(关于AbstractQueuedSynchronizer.ConditionObject)
1. 背景 之前读JUC的AQS源码,读到Condition部分,我当时也写了一篇源码阅读文章--(AbstractQueuedSynchronizer源码解读--续篇之Condition)[http ...
- jdk 10.0.2 bug修复
之前记录过jdk9+版本的1个bug,某些情况下会导致方法执行二遍,今天早上打开笔记本(mac),弹出一个框提示jdk升级10.0.2,顺手点了一下,然后验证了下该bug,发现居然fix掉了,推荐大家 ...
- JDK的3个bug啊,你get到了吗?
1.Annotation引用非空enum数组返回空数组 首次发现时的环境:JDK 1.8 首次发现所在项目:APIJSON 测试用例: publicenumRequestRole {/**未登录,不明 ...
- JDK中的并发bug?
最近研究Java并发,无意中在JDK8的System.console()方法的源码中翻到了下面的一段代码: private static volatile Console cons = null; / ...
- 最近调试HEVC中码率控制, 发现HM里面一个重大bug
最近调试HEVC中码率控制, 发现里面一个重大bug! 码率控制中有这么一个函数: Int TEncRCGOP::xEstGOPTargetBits( TEncRCSeq* encRCSeq, Int ...
- eclipse导入别的项目后发现jdk版本不一样,该如何解决呢?
当我们导入其他人的项目的时候,发现导入的项目的jdk版本与我们使用电脑上的版本不同,该如何解决呢? 选中项目右键 --> Properties --> Build Path --> ...
- C#.Net ComboBox控件设置DropDownList之后背景颜色问题,以及发现的微软的一个BUG
先说背景颜色问题怎么处理. C#.Net WinForm中如果设置ComboBox的DropDownStyle为DropDownList,控件背景色会变成灰色,并且这个时候ComboBox控件的Bac ...
- 我好像发现了一个Go的Bug?
从一次重构说起 这事儿还得从一次重构优化说起. 最近在重构一个路由功能,由于路由比较复杂,需求变化也多,于是想通过责任链模式来重构,刚好这段时间也在 Sentinel-Go 中看到相关源码. 用责任链 ...
随机推荐
- c++标准之IO库
1.面向对象的标准库 2.多种IO标准库工具 istream,提供输入操作 ostream,提供输出操作 cin:读入标准输入的istream对象.全局对象extern std::istream ci ...
- 【例题收藏】◇例题·III◇ 木と整数 / Integers on a Tree
◇例题·III◇ 木と整数 / Integers on a Tree 只需要一个美妙的转换,这道题就会变得无比美妙…… 来源:+AtCoder 2148(ARC-063 E)+ ◆ 题目大意 给定一棵 ...
- oracle数据库 网页管理360浏览器登录不上
使用谷歌浏览器可以登陆,然后在使用360之类的浏览器 就可以登录了
- 用Java读取xml文件内容
在AXP中,DOM解析器是1 Document Builder类的一个实例,该实例由 DocumenBailderfactorv类负责创,步如下 DocumentBuilderFactory fa ...
- mysql in和exists性能比较和使用【转】
exists对外表用loop逐条查询,每次查询都会查看exists的条件语句,当 exists里的条件语句能够返回记录行时(无论记录行是的多少,只要能返回),条件就为真,返回当前loop到的这条记录, ...
- 使用 Ajax
Ajax( Asynchronous JavaScript and XML) 在 Ajax 中 Asynchronous 是指异步, 代表 客户端(Client 通常是指浏览器) 可以向服务器(Ser ...
- linux命令随身记
赋予权限命令:chmod 755 * 查询进程: ps -ef |grep abc 查看含有"abc"的活动进程 ps -ef |grep -v abc 查看不含abc的活动进程 ...
- Android自定义组件之简单组合
Android自定义控件有两种,一种是组合.比如一个linearlayout 里面有textview,imageview. 这样的好处是,写一个就可以多处使用. view_image_and_butt ...
- python语法re.compile模块介绍
1. re模块是正则表达式模块,re模块中包含一个重要函数是compile(pattern [, flags]) ,该函数根据包含的正则表达式的字符串创建模式对象.可以实现更有效率的匹配. impor ...
- python语言中threading.Thread类的使用方法
1. 编程语言里面的任务和线程是很重要的一个功能.在python里面,线程的创建有两种方式,其一使用Thread类创建 # 导入Python标准库中的Thread模块 from threading i ...