Java日常错误及需要注意细节,持续更新......

记录日常工作中一些容易被忽视的错误及细节,持续更新......

一、问题:HashMap<Long, String>中,用get(Integer key)取不到值

        Map<Long, String> map = new HashMap<Long, String>();map.put(1L, "1");System.err.println(map.get(1));// nullSystem.err.println(map.get(1L));// 1

1.首先想到Long与Integer的hashCode方法不同,Integer-value   Long-(int)(value ^ (value >>> 32))

但是!!计算出的hashCode值是相同的,不是问题所在

2.查看HashMap源码:注意加亮部分

  先比较key.hash,然后first.key == key || key.equals(first.key)

     /*** 先比较key.hash,然后first.key == key || key.equals(first.key)*/final Node<K,V> getNode(int hash, Object key) {Node<K,V>[] tab; Node<K,V> first, e; int n; K k;if ((tab = table) != null && (n = tab.length) > 0 && (first = tab[(n - 1) & hash]) != null) {if (first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k))))return first;if ((e = first.next) != null) {if (first instanceof TreeNode)return ((TreeNode<K,V>)first).getTreeNode(hash, key);do {if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))return e;} while ((e = e.next) != null);}}return null;}

 先看first.key == key:"=="比较地址值,l是Long cache[]中的1,o是Integer cache[]中的1,false

        Long l = 1L;Object o = 1;System.err.println(l == o);// false// 反编译后:Long l = Long.valueOf(1L);Object o = Integer.valueOf(1);System.err.println(l == o);

然后看key.equals(first.key):先检查类型,false

        //Long的equals方法public boolean equals(Object obj) {if (obj instanceof Long) {return value == ((Long)obj).longValue();}return false;}

引发新的问题:为什么这个是true?——反编译解决

        Long l = 1L;System.err.println(l == 1);// true// 反编译后:Long l = Long.valueOf(1L);System.err.println(l.longValue() == 1L);//编译器直接将1转成1L

 二、两个值相等的Integer不“==”

        Integer c = 99999;Integer d = 99999;System.out.println(c == d);// false

 Integer c = 99999;// 反编译:Integer c = Integer.valueOf(99999);

查看Integer源码:

-128 <= i <= 127时,直接在Integer cache[]中取;否则,new Integer(i)

        public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);}

结论:

        int a = 99999;int b = 99999;System.err.println(a == b);// true
Integer c = 99999;Integer d = 99999;System.out.println(c == d);// false
        Integer e = 127;Integer f = 127;System.out.println(e == f);// true    

 三、List.remove()方法调用错误

注意list两个remove方法,remove(int index)  remove(Object o)

    public static void main(String[] args) {List<Integer> list = new LinkedList<Integer>();for (int i = 0; i < 9999999; i++) {list.add(i);}// remove(int index)long before = System.currentTimeMillis();int i = 8888888;list.remove(i);long after = System.currentTimeMillis();System.err.println("index=" + (after - before));// 6ms// remove(Object o)long before = System.currentTimeMillis();Integer i = 8888888;list.remove(i);long after = System.currentTimeMillis();System.err.println("Object=" + (after - before));// 96ms
        }

四、三目运算符与自动拆装箱

        Map<String,Boolean> map = new HashMap<String, Boolean>();Boolean b = (map!=null ? map.get("test") : false);// Exception in thread "main" java.lang.NullPointerException

查问题:

  NullPointerException找不出原因

  反编译看: ((Boolean)map.get("test")) == null

        HashMap map = new HashMap();Boolean boolean1 = Boolean.valueOf(map == null ? false : ((Boolean)map.get("test")).booleanValue());

结论:

  三目运算符的语法规范,参见 jls-15.25。

  三目运算符 当第二,第三位操作数分别为基本类型和对象时,其中的对象就会拆箱为基本类型进行操作。

以后注意:

1、保证三目运算符的第二第三位操作数都为对象类型

        Map<String,Boolean> map =  new HashMap<String, Boolean>();Boolean b = (map!=null ? map.get("test") : Boolean.FALSE);

 2、自动拆装箱问题

        Integer integer = 1; // 装箱  Integer integer=Integer.valueOf(1); new Integer()int i = integer; // 拆箱  int i=integer.intValue(); 

 

1)包装对象的数值比较,不能简单的使用==(只有-128到127之间IntegerCache内的数字可以,但是这个范围之外还是需要使用equals比较)。

2)自动拆箱,如果包装类对象为null,那么自动拆箱时就有可能抛出NPE。

3)如果一个for循环中有大量装箱操作,会浪费很多资源。

五、switch语句忘记break

本来我跟你现在想的一样,一定不会忘,直到遇到了这个问题。

        int i = 3;switch (i) {case 1:System.out.println(1);break;case 2:System.out.println(2);break;case 3:System.out.println(3);// 没有break, 不会有问题}

当你需要在之后接着case的时候,直接复制case 3,就bug了。

(1)case完一定break,除非特别需要穿透到下一个case;

(2)复制代码前后都要检查是否有问题。

六、数值溢出问题

    // 为了更好的展示问题,代码举出的是较极端的情况public void overFlow(int a) {int b = 999999 * a; // 6个9 int最大值=2147483647int limit = 999999999; // 9个9if (b < limit) {System.out.println("a*b小于limit");}}

如果a传入一个较大的int值,a*999999之后会超过int的最大值

而默认结果是int类型,会将a*999999的结果强转成int,导致不是想要的结果的结果

即使a*999999是大于limit的,强转成int后,b可能会比limit小,甚至可能是负数

解决:

    // 用long类型计算(还会用一定风险)public void overFlow(int a) {long b = 999999L * a;int limit = 999999999;if (b < limit) {System.out.println("a*999999小于limit");}}// 将加法和乘法转变成减法和除法运算public void overFlow(int a) {int limit = 999999999;if (a < limit/999999) {System.out.println("a*999999小于limit");}}

七、对象引用问题

public static void main(String[] args) {Map<Integer, Inner> map = new HashMap<Integer, Inner>();// inner1.list [1]Inner inner1 = new Inner(new LinkedList<Integer>());inner1.getList().add(1);map.put(1, inner1);// inner2.list [1, 2]Inner inner2 = new Inner(map.get(1).getList());inner2.getList().add(2);map.put(2, inner2);for (Entry<Integer, Inner> entry : map.entrySet()) {System.err.println("" + entry.getKey() + " " + entry.getValue().getList());}/*** 目的:inner1.list [1]   inner2.list [1, 2]* 结果:inner1.list [1, 2]   inner2.list [1, 2]*/}static class Inner {List<Integer> list;public List<Integer> getList() {return list;}public Inner(List<Integer> list) {this.list = list;}}

 

分析:

1.将inner1.list的引用给了inner2.list,nner1.list inner2.list指向的是同一个List。

2.很简单的问题,开发时习惯了构造方法里这样写:this.list = list;

解决:

this.list = list;  改成   this.list = new LinkedList<Integer>(list);

 

转载于:https://www.cnblogs.com/hexinwei1/p/9720310.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/537724.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tp5 html获取get,tp5获取请求参数

1.问题&#xff1a;照着tp5快速入门手册里学习&#xff0c;运行一段代码和书中的结果(资源类型)不同2.相关代码&#xff1a;public function hello(Request $request){echo 请求参数;dump(input());echo name: .$request->param(name);echo 资源类型&#xff1a; .$request-…

matlab 滤波器设计 coe_一种半带滤波器的低功耗实现方法

在如今数字技术中&#xff0c;半带滤波器因其通带阻带对称&#xff0c;系数具有偶对称性且滤波器阶数为奇数&#xff0c;有效系数少等特点广泛应用于通信、视频处理、语音识别等数字信号处理应用中&#xff0c;尤其常用于实现信号的2倍抽取。对于一个阶数为N(N为偶数)&#xff…

产品设计:APP个人信息保护指引

需求分析 2019年11月4日&#xff0c;工业和信息化部展开APP侵犯用户权益专项整治行动。即日起各安卓应用市场根据最新的规则审核市场里的各应用&#xff0c;审核不通过将下架处理。 调研了“手机qq”、“抖音”、“快手”、“今日头条”、“澎湃新闻”等APP&#xff0…

说说GIL

上一篇&#xff1a;线程深入篇引入 Code&#xff1a;https://github.com/lotapp/BaseCode/tree/master/python/5.concurrent/Thread/3.GIL 说说GIL 尽管Python完全支持多线程编程&#xff0c; 但是解释器的C语言实现部分在完全并行执行时并不是线程安全的&#xff0c;所以这时候…

2021重庆高考成绩名次排名查询,重庆高考排名对应大学-重庆高考位次大学(2021年理科)...

选择科目测一测我能上哪些大学选择科目领取你的专属报告>选择省份关闭请选择科目确定v>每年高考结束后&#xff0c;报大学、选专业、填志愿就成了考生与家长十分关心的一件事情。本期&#xff0c;圆梦志愿为大家整理了重庆高考理科2020年位次排名对应的大学&#xff0c;供…

Project项目信息的日程排定方法区别

日程排定方法分&#xff1a;项目开始日期&#xff0c;项目结束日期。 项目开始日期 设置如下 在“工期”单元格输入任意数字&#xff0c;任务开始日期会从项目开始日期2020年3月1日开始 给项目任务设置工期的时候&#xff0c;从任务的第一个开始设置&#xff0c;按正序进行&a…

gis里创建要素面板怎么打开_周末技术流 | GIS三维热力图分析

周末技术流&#xff2e;&#xff2f;&#xff37;现在行动&#xff01;我们的技术流是一个系列&#xff0c;最终带大家出一套完整图纸哦~(未经允许严禁盗用&#x1f6ab;)Rhino日照分析1.前期回顾本期内容一直关注我们的朋友到这期可能会有点熟悉&#xff0c;确实&#xff0c;我…

第三章实验二小谈

第三章实验二小谈 这周很忙...时间很赶...很多作业还没做... 首先想谈&#xff08;tu&#xff09;论&#xff08;cao&#xff09;一下计算机的严谨性。 编程语言严谨是一种好事&#xff0c;越严谨&#xff0c;把它转化为机器语言就越方便&#xff0c;在资源占用、运行速度等方面…

project提醒:无法链接这些任务,因为它们已通过另一个任务链链接

给45任务指定前置任务111时&#xff0c;提示“无法链接这些任务&#xff0c;因为它们已通过另一个任务链链接” 查了好久没找到原因&#xff0c;后来无意在46任务前置任务输入111&#xff0c;没有提示。 解决方法&#xff1a; 删除了提示的45任务&#xff0c;新建任务&#x…

企业网站 源码 e-mail_天津seo优化套餐服务收费_天津网站优化关键词价格

天津华阳在线专注于SEO关键词排名优化&#xff0c;品牌网站建设&#xff0c;营销型网站建设&#xff0c;App、小程序开发&#xff0c;搜索引擎seo优化&#xff0c;竞价托管sem&#xff0c;品牌口碑建设与代运营等服务。企业通过引进前BAT产品经理不断丰富产品线优化技术实力&am…

计算机网络与综合布线系统设计,计算机网络与通信技术10-综合布线系统.ppt

计算机网络与通信技术10-综合布线系统.ppt5.7 电气防护系统设计 电气防护设计应把握以下原则&#xff1a; 1)为了保证综合布线系统正常运行&#xff0c;设备间或干线交接间内应设有独立、稳定、可靠的交流50Hz、220V电源&#xff0c;以便于维护检修和日常管理&#xff0c;有条件…

必须Mark下,2019 年度中国质量协会质量技术优秀奖

曾经和一群可爱的人儿做的项目&#xff0c;获得了2019 年度中国质量协会质量技术优秀奖&#xff0c;无心插柳柳成荫。 那几年工作得很快乐&#xff0c;工作与家庭都兼顾&#xff0c;是同事也是朋友。2019年末去过一次移动宁波分公司&#xff0c;特意去看了原来驻场的办公室&am…

python文件编码及执行

兼容中文编码 由于Python源代码也是一个文本文件&#xff0c;所以&#xff0c;当你的源代码中包含中文的时候&#xff0c;在保存源代码时&#xff0c;就需要务必指定保存为UTF-8编码。 当Python解释器读取源代码时&#xff0c;为了让它按UTF-8编码读取&#xff0c;我们通常在文…

html5链接mvc,LinkExtensions.ActionLink 方法 (System.Web.Mvc.Html) | Microsoft Docs

对于指定的链接文本、操作、控制器、协议、主机名、URL 片段、作为路由值字典的路由值和作为字典的 HTML 属性&#xff0c;返回一个定位点元素&#xff0c; (元素) 。public static System.Web.Mvc.MvcHtmlString ActionLink (this System.Web.Mvc.HtmlHelper htmlHelper, stri…

这些Windows 10隐藏秘技,你知道几个?

1. 虚拟桌面 玩电脑的老鸟&#xff0c;估计都听说过虚拟桌面。简言之&#xff0c;平时要做的工作太多&#xff0c;又没有第二个显示器&#xff0c;那么“虚拟桌面”也就成了不二之选。微软Windows 10的虚拟桌面隐藏在WinTAB中&#xff0c;也就是所谓的时间线视图&#xff08;T…

vant toast loading 倒计时_日期倒计时软件哪个好 苹果日期倒计时软件推荐

日期倒计时软件哪个好&#xff0c;相信大家也是经常会查看日期&#xff0c;来保证一些重要的事情能够按时进行&#xff0c;那么哪一款日期倒计时软件比较好用&#xff0c;能够提醒用户们日期将至呢。这里就为大家推荐几款。日期倒计时软件哪个好1.Days Matter Air作为Days Matt…

浏览器的差距

浏览器 浏览器默认字体是16px&#xff0c;谷歌的最小字体是12px&#xff0c;其他的是10px。 HACK Hack就是针对不同的浏览器去写不同的HTML、CSS样式&#xff0c;从而让各浏览器能达到一致的渲染效果。 Hack分两种写法 Html的hack&#xff1a;写在html的标签中 Css的hack&#…

业务应用系统的业务操作日志设计

目的&#xff1a;记录业务的访问活动 操作时间&#xff1a;精确到秒 服务器IP&#xff1a;可能部署多台服务器&#xff0c;记录当前线程服务器IP地址 访问者IP&#xff1a;访问者ip地址 访问者账号&#xff1a;系统通过手机号登录&#xff0c;记录手机号 业务名称&#xf…

微型计算机控制技术试卷B,微型计算机控制技术试卷b..doc

微型计算机控制技术试卷b.微型计算机控制技术试卷B一、选择题(本题共10小题&#xff0c;每小题 1.5分&#xff0c;共15分) 1. 防止抖动是能否正确读取键值的必要环节&#xff0c;实现方法是( )。 A&#xff0e;可以用硬件电路或软件程序实现?? B&#xff0e;只能用滤波电路或…

c char转int_c/c++基础之sizeof用法

在 C/C 中&#xff0c;sizeof() 是一个判断数据类型或者表达式长度的运算符。1 sizeof 定义 sizeof 是 C/C 中的一个操作符&#xff08;operator&#xff09;&#xff0c;返回一个对象或者类型所占的内存字节数。The sizeof keyword gives the amount of storage, in bytes, as…