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的更多相关文章

  1. 应用服务器中对JDK的epoll空转bug的处理

    原文链接:应用服务器中对JDK的epoll空转bug的处理 前面讲到了epoll的一些机制,与select和poll等传统古老的IO多路复用机制的一些区别,这些区别实质可以总结为一句话, 就是epol ...

  2. 给JDK提的一个bug(关于AbstractQueuedSynchronizer.ConditionObject)

    1. 背景 之前读JUC的AQS源码,读到Condition部分,我当时也写了一篇源码阅读文章--(AbstractQueuedSynchronizer源码解读--续篇之Condition)[http ...

  3. jdk 10.0.2 bug修复

    之前记录过jdk9+版本的1个bug,某些情况下会导致方法执行二遍,今天早上打开笔记本(mac),弹出一个框提示jdk升级10.0.2,顺手点了一下,然后验证了下该bug,发现居然fix掉了,推荐大家 ...

  4. JDK的3个bug啊,你get到了吗?

    1.Annotation引用非空enum数组返回空数组 首次发现时的环境:JDK 1.8 首次发现所在项目:APIJSON 测试用例: publicenumRequestRole {/**未登录,不明 ...

  5. JDK中的并发bug?

    最近研究Java并发,无意中在JDK8的System.console()方法的源码中翻到了下面的一段代码: private static volatile Console cons = null; / ...

  6. 最近调试HEVC中码率控制, 发现HM里面一个重大bug

    最近调试HEVC中码率控制, 发现里面一个重大bug! 码率控制中有这么一个函数: Int TEncRCGOP::xEstGOPTargetBits( TEncRCSeq* encRCSeq, Int ...

  7. eclipse导入别的项目后发现jdk版本不一样,该如何解决呢?

    当我们导入其他人的项目的时候,发现导入的项目的jdk版本与我们使用电脑上的版本不同,该如何解决呢? 选中项目右键 --> Properties --> Build Path --> ...

  8. C#.Net ComboBox控件设置DropDownList之后背景颜色问题,以及发现的微软的一个BUG

    先说背景颜色问题怎么处理. C#.Net WinForm中如果设置ComboBox的DropDownStyle为DropDownList,控件背景色会变成灰色,并且这个时候ComboBox控件的Bac ...

  9. 我好像发现了一个Go的Bug?

    从一次重构说起 这事儿还得从一次重构优化说起. 最近在重构一个路由功能,由于路由比较复杂,需求变化也多,于是想通过责任链模式来重构,刚好这段时间也在 Sentinel-Go 中看到相关源码. 用责任链 ...

随机推荐

  1. OCCI线程安全

    线程是任务调度的基本单位,一个进程中可以有多个线程,每个线程有自己的堆栈空间, 进程中的代码段.数据段和堆栈对进程中的线程是可见的.在使用线程时通常都要考虑数据的安全访问. 常用的线程同步方法有: 互 ...

  2. 爬虫学习(十一)——bs4基础学习

    ba4的介绍: bs4是第三方提供的库,可以将网页生成一个对象,这个网页对象有一些函数和属性,可以快捷的获取网页中的内容和标签 lxml的介绍 lxml是一个文件的解释器,python自带的解释器是: ...

  3. Spring Cloud 入门Eureka -Consumer服务消费(声明式Feign)(三)

    Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端.它使得编写Web服务客户端变得更加简单.我们只需要通过创建接口并用注解来配置它既可完成对Web服务接 ...

  4. LVS+Keepalived-DR模式负载均衡高可用集群

    LVS+Keepalived DR模式负载均衡+高可用集群架构图 工作原理: Keepalived采用VRRP热备份协议实现Linux服务器的多机热备功能. VRRP,虚拟路由冗余协议,是针对路由器的 ...

  5. redis 面试题

    https://www.cnblogs.com/ftl1012/p/redisExam.html 1. 使用Redis有哪些好处? (1) 速度快,因为数据存在内存中,类似于HashMap,HashM ...

  6. Python全栈day 05

    Python全栈day 05 一.数据类型补充 1. int py2和py3的2种区别 py2有int和long,int的取值范围为-2^31~2^31-1,超出范围自动转为long,长整型. py2 ...

  7. selenium库:自动化测试工具

    爬虫中主要用来解决Javascript渲染问题 1.声明浏览器对象: from selenium import webdriver browser = webdriver.浏览器名() 2.访问页面: ...

  8. 猴子吃桃问题 python

    猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个.以后每天早上都吃了前一天剩下的一半零一个.到第10天早上想再吃时,见只剩下一个桃子了.求第 ...

  9. 笔记-git-协作开发

    笔记-git-协作开发 1.      git协作开发 git协作的典型做法是,创建一个git服务器,被多个人操作. 示意图如下: 一般来说协作分为如下几个步骤: 创建一个git裸服务器 (git i ...

  10. 使用MD5比较两个文件是否相同

    MD5算法:是计算机广泛使用的一种哈希算法,将数据(如汉字)运算为另一固定长度值,用于确保信息传输完整一致.java,C++ 等多种编程语言都有MD5的实现,可直接使用. 文件MD5值:每个文件都可以 ...