1. 首页
  2. IT资讯

Java 开发中如何正确的踩坑

“u003Cpu003E技术博文,及时送达u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRelVn4tG7zucng” img_width=”535″ img_height=”10″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cpu003Eu003Cstrong toutiao-origin=”span” class=”highlight-text”u003E来自:mafly | 责编:乐乐u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003Eu003Cstrong toutiao-origin=”span” class=”highlight-text”u003E链接:cnblogsu003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-6″u003E.comu003Cu002Fiu003Eu002Fmaflyu002Fpu002Ftrap.htmlu003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch1 toutiao-origin=”h2″u003E为什么说一个好的员工能顶 100 个普通员工?u003Cu002Fh1u003Eu003Cpu003E我们的做法是,要用最好的人。我一直都认为研发本身是很有创造性的,如果人不放松,或不够聪明,都很难做得好。你要找到最好的人,一个好的工程师不是顶10个,是顶100个。u003Cu002Fpu003Eu003Cpu003E所以,在核心工程师上面,大家一定要不惜血本去找,千万不要想偷懒只用培养大学生的方法去做。最好的人本身有很强的驱动力,你只要把他放到他喜欢的事情上,让他自己有玩的心态,他才能真正做出一些事情,打动他自己,才能打动别人。所以你今天看到我们很多的工程师,他自己在边玩边创新。u003Cu002Fpu003Eu003Cpu003E所以,找最好的人,要给他做他喜欢和擅长的事情。研发人员千万不要去管太严,一管就“死”了。工程师很讨厌跟规章制度打交道,作汇报他都很烦,大家不要管他,让用户去管他。他做好了一个产品,用户表扬他,这个大神多牛逼。他做不好了,用户骂他,他自己赶紧去改。u003Cu002Fpu003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch1 toutiao-origin=”h2″u003E再谈阿里巴巴 Java 开发手册u003Cu002Fh1u003Eu003Cpu003E之前在这个手册刚发布的时候看过一遍,当时感觉真是每个开发者都应该必读的一本手册,期间还写过一篇关于日志规约的文章:u003Cu002Fpu003Eu003Cblockquoteu003Eu003Cpu003Ehttp:u002Fu002Fu003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-2″u003Ewwwu003Cu002Fiu003E.cnblogsu003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-6″u003E.comu003Cu002Fiu003Eu002Fmaflyu002Fpu002Fslf4j.htmlu003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Cpu003E最近由于在总结一些我们日常开发中容易忽略的问题,可能是最低级的编码常见问题,往往这也是最最容易忽略的,所以,又重新看了一遍这个手册,好像最近它也更新到了 1.2 版本。u003Cu002Fpu003Eu003Cpu003E这个手册目的就是让我们尽可能少踩坑,杜绝踩重复的坑。我接下来就打算试着写一些“坑”出来,来看看我们如何一不留神踩坑的,以及如何用正确的姿势跳出坑。u003Cu002Fpu003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch1 toutiao-origin=”h2″u003E随随便便写出 NPEu003Cu002Fh1u003Eu003Cpu003E首先声明一个 User 对象,接下来所有代码可能都会用到这个对象做演示,在下面将不在赘述。很简单,不上代码,上图片:u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRfrw5kLBNIoRVl” img_width=”1000″ img_height=”483″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch2 toutiao-origin=”h3″u003Eu003Cstrongu003E1.自动解箱抛 NPEu003Cu002Fstrongu003Eu003Cu002Fh2u003Eu003Cpu003E代码只有一行,再简单不过了:int method { return new User.getId; }u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002FRfrw5kh3LGHFp2″ img_width=”1000″ img_height=”470″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cblockquoteu003Eu003Cpu003E踩坑姿势:包装类型为 时,进行自动转换为基本数据类型报错。解决方案:返回之前进行判断与处理或者改为相同类型。u003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch2 toutiao-origin=”h3″u003Eu003Cstrongu003E2.级联调用易产生 NPEu003Cu002Fstrongu003Eu003Cu002Fh2u003Eu003Cpu003E这段代码有点容易迷惑人,因为它进行了集合元素的 isEmpty 判断,按说不会出问题了吧。看代码:u003Cu002Fpu003Eu003Cpreu003Eu003Ccodeu003Estatic void method1 {u003Cu002Fcodeu003Eu003Ccodeu003E List<User> list = new ArrayList<User>;u003Cu002Fcodeu003Eu003Ccodeu003E list.au003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-2″u003Eddu003Cu002Fiu003E(new User);u003Cu002Fcodeu003Eu003Cbru003Eu003Ccodeu003E if (!CollectionUtils.isEmpty(list)) {u003Cu002Fcodeu003Eu003Ccodeu003E for (User user : list) {u003Cu002Fcodeu003Eu003Ccodeu003E System.out.println(“userid:” + user.getId.toString);u003Cu002Fcodeu003Eu003Ccodeu003E }u003Cu002Fcodeu003Eu003Ccodeu003E }u003Cu002Fcodeu003Eu003Ccodeu003E}u003Cu002Fcodeu003Eu003Cu002Fpreu003Eu003Cpu003E不废话,看运行结果:u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRfrw5kwIVIBtri” img_width=”1000″ img_height=”486″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cpu003E没错,还是报错了。u003Cu002Fpu003Eu003Cpu003E踩坑姿势:其实就是尽管你在之前做了对象不为空的判断,但你并不能保证对象中的值不为空,而且这时候去级联调用就会抛 NPE 。u003Cu002Fpu003Eu003Cpu003E手册中关于 NPE 的描述:u003Cu002Fpu003Eu003Cblockquoteu003Eu003Cpu003E防止 NPE 是调用者的责任。即使被调用方法返回空集合或者空对象,对调用者来说,也并非高枕无忧,必须考虑到远程调用失败、序列化失败、运行时异常等场景返回 的情况。集合里的元素即使 isEmpty,取出的数据元素也可能为 。u003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Cpu003E级联调用 obj.getA.getB.getC;一连串调用,易产生 NPEu003Cu002Fpu003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch2 toutiao-origin=”h3″u003Eu003Cstrongu003E3.关于 Equalsu003Cu002Fstrongu003Eu003Cu002Fh2u003Eu003Cpu003E这是日常开发中用于相等比较使用最多的方法了吧,因为当年谁没被 == 坑过阿。现在一般我们都会这么写:user.getName.equals(“mafly”);u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp9.pstatp.comu002Flargeu002Fpgc-imageu002FRfrw5lFDVkfWRb” img_width=”1000″ img_height=”473″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cblockquoteu003Eu003Cpu003E踩坑姿势:一不小心使用了 值调用了 Equals 方法。解决方案:很简单咯,这么写:”mafly”.equals(user.getName);u003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Cpu003Eequals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。u003Cu002Fpu003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch2 toutiao-origin=”h3″u003Eu003Cstrongu003E4.Map 下的 NPEu003Cu002Fstrongu003Eu003Cu002Fh2u003Eu003Cpu003EMap 应该是我们开发中使用最频繁的了,最常用的可能有 HashMap、ConcurrentHashMap 这俩了,可能会一不留神写出这样的代码:u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRfrw5m635fanbz” img_width=”1000″ img_height=”383″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cblockquoteu003Eu003Cpu003E踩坑姿势:可能我们知道 ConcurrentHashMap 的 Ku002FV 都不能为空,但我们有时候并不知道传进来的值是否为空。解决方案:设置时做下检验,对它的特性正确理解及使用。u003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Cpu003E由于 HashMap 的干扰,很多人认为 ConcurrentHashMap 是可以置入 值,而事实上,存储 值时会抛出 NPE 异常。u003Cu002Fpu003Eu003Cpu003EMap 类集合 Ku002FV 能不能存储 值的情况,如下表格:u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRfrw6Ny5iVltTi” img_width=”555″ img_height=”212″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch1 toutiao-origin=”h2″u003E简单聊聊常用的集合u003Cu002Fh1u003Eu003Ch2 toutiao-origin=”h3″u003Eu003Cstrongu003E5.foreach 遍历集合删除元素u003Cu002Fstrongu003Eu003Cu002Fh2u003Eu003Cpu003E大家应该都知道,在遍历集合时对元素进行 au003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-2″u003Eddu003Cu002Fiu003Eu002Fremove 操作要使用 Iterator,使用 for 循环时会报错,一定会报错吗?看代码:u003Cu002Fpu003Eu003Cpreu003Eu003Cdivu003Eu003Cpreu003Eu003Ccodeu003Epublic static void main(String[] args) {u003Cu002Fcodeu003Eu003Ccodeu003E List<String> a = new ArrayList<>;u003Cu002Fcodeu003Eu003Ccodeu003E a.au003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-2″u003Eddu003Cu002Fiu003E(“1”);u003Cu002Fcodeu003Eu003Ccodeu003E a.au003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-2″u003Eddu003Cu002Fiu003E(“2”);u003Cu002Fcodeu003Eu003Ccodeu003E a.au003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-2″u003Eddu003Cu002Fiu003E(“3”);u003Cu002Fcodeu003Eu003Cbru003Eu003Ccodeu003E for (String temp : a) {u003Cu002Fcodeu003Eu003Ccodeu003E if (“2”.equals(temp)) {u003Cu002Fcodeu003Eu003Ccodeu003E a.remove(temp);u003Cu002Fcodeu003Eu003Ccodeu003E }u003Cu002Fcodeu003Eu003Ccodeu003E }u003Cu002Fcodeu003Eu003Cbru003Eu003Ccodeu003E Iterator<String> it = a.iterator;u003Cu002Fcodeu003Eu003Ccodeu003E while (it.hasNext) {u003Cu002Fcodeu003Eu003Ccodeu003E String temp = it.next;u003Cu002Fcodeu003Eu003Ccodeu003E if (“2″.equals(temp)) {u003Cu002Fcodeu003Eu003Ccodeu003E it.remove;u003Cu002Fcodeu003Eu003Ccodeu003E }u003Cu002Fcodeu003Eu003Ccodeu003E }u003Cu002Fcodeu003Eu003Ccodeu003E}u003Cu002Fcodeu003Eu003Cu002Fpreu003Eu003Cu002Fdivu003Eu003Cu002Fpreu003Eu003Cpu003E应该会报错的吧?因为在 for 循环中移出了元素,如果你运行了就会惊讶的,输出如下:u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRfrw6OC3itK0Az” img_width=”1000″ img_height=”393″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cpu003E不解释其中原因了,感兴趣的可以看这篇文章:u003Cu002Fpu003Eu003Cblockquoteu003Eu003Cpu003Ehttp:u002Fu002Fblog.csdn.netu002Fbimuyulailau002Farticleu002Fdetailsu002F52088124u003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Cpu003E不管是不是倒数第二个元素才没问题,我们依然要注意不要在 foreach 循环里进行元素的 removeu002Fau003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-2″u003Eddu003Cu002Fiu003E 操作。remove 元素请使用 Iterator 方式(代码第二种),如果并发操作,需要对 Iterator 对象加锁。u003Cu002Fpu003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch2 toutiao-origin=”h3″u003Eu003Cstrongu003E6.Arrays.asList 数组转换集合u003Cu002Fstrongu003Eu003Cu002Fh2u003Eu003Cpu003E这个工具类应该都用过,可以很方便的把数组转换为集合,直接看结果吧:u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRfrw6OVHHDBZsO” img_width=”1000″ img_height=”514″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cblockquoteu003Eu003Cpu003E踩坑姿势:Arrays.asList把数组转换成集合时,不能使用其修改集合相关的方法,它的 au003Ci class=”chrome-extension-mutihighlight chrome-extension-mutihighlight-style-2″u003Eddu003Cu002Fiu003Eu002Fremoveu002Fclear 方法会抛出 UnsupportedOperationException 异常。asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。解决方案:在转换之前操作咯。还需要注意一点,在你转换后,再对数组的值进行修改时,集合也会跟着变哦(注释掉的代码)。u003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch2 toutiao-origin=”h3″u003Eu003Cstrongu003E7. toArray 集合转换数组u003Cu002Fstrongu003Eu003Cu002Fh2u003Eu003Cpu003E当我们需要把一个集合转换为数组时,往往会调用 toArray 方法,如果你用的是无参的这个可以吗?u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp9.pstatp.comu002Flargeu002Fpgc-imageu002FRfrw6Oh8LxhCxB” img_width=”1000″ img_height=”443″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cpu003E当然不可以啦!会报 ClassCastException 异常。u003Cu002Fpu003Eu003Cblockquoteu003Eu003Cpu003E踩坑姿势:直接使用 toArray 无参方法返回值只能是 Object类,若强转其它类型数组将会抛异常。u003Cu002Fpu003Eu003Cpu003E解决方案:使用 u003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Cpu003E代码如下:u003Cu002Fpu003Eu003Cpreu003Eu003Cdivu003Eu003Cpreu003Eu003Ccodeu003EString array = new String[list.size()];u003Cu002Fcodeu003Eu003Ccodeu003Earray = list.toArray(array);u003Cu002Fcodeu003Eu003Cu002Fpreu003Eu003Cu002Fdivu003Eu003Cu002Fpreu003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch2 toutiao-origin=”h3″u003Eu003Cstrongu003E8. subList 的使用u003Cu002Fstrongu003Eu003Cu002Fh2u003Eu003Cpu003E集合中的 subList 是用于来返回某一部分的视图内容的,可能我们不是很常用,但是其中有好多坑的,直接看代码:u003Cu002Fpu003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRfrw6Oz92TSMQo” img_width=”1000″ img_height=”695″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002FRfrw6rABlYUGzp” img_width=”1000″ img_height=”411″ alt=”Java 开发中如何正确的踩坑” inline=”0″u003Eu003Cpu003E这次我们从输出来看上面的所有关于 subList 的代码。u003Cu002Fpu003Eu003Culu003Eu003Cliu003Eu003Cpu003E18行:当你原始集合大小没有那么大时,毫无疑问抛异常。u003Cu002Fpu003Eu003Cu002Fliu003Eu003Cliu003Eu003Cpu003E20-21行:得到一个新的集合,我们往新集合中增加一条数据。u003Cu002Fpu003Eu003Cu002Fliu003Eu003Cliu003Eu003Cpu003E23-26行:遍历原始集合,竟然 size=2 了,而且往新集合中增加的数据存在与原始集合。u003Cu002Fpu003Eu003Cu002Fliu003Eu003Cliu003Eu003Cpu003E28-31行:移除新集合中一条数据,遍历新集合。u003Cu002Fpu003Eu003Cu002Fliu003Eu003Cliu003Eu003Cpu003E33-37行:原始集合增加一条数据并遍历。u003Cu002Fpu003Eu003Cu002Fliu003Eu003Cliu003Eu003Cpu003E40-42行:遍历新集合,抛出 ConcurrentModificationException 异常。u003Cu002Fpu003Eu003Cu002Fliu003Eu003Cu002Fulu003Eu003Cpu003E从上述代码中,我们应该可以得出如下结论:返回的新集合是靠原来的集合支持的,修改都会影响到彼此对方。在 subList 场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、删除均产生异常。u003Cu002Fpu003Eu003Cpu003Eu003Cu002Fpu003Eu003Ch1 toutiao-origin=”h2″u003E先总结一下u003Cu002Fh1u003Eu003Cpu003E写到这只是其中关于异常部分的一些坑吧,还有另外一些令人异常惊讶的“我的天吶”的问题,由于篇幅太长了点,感觉不能再写下去了,过两天再接着写吧。u003Cu002Fpu003Eu003Cpu003E异常真的是一个有意思的问题。u003Cu002Fpu003E”

原文始发于:Java 开发中如何正确的踩坑

主题测试文章,只做测试使用。发布者:逗乐男神i,转转请注明出处:http://www.cxybcw.com/17870.html

联系我们

13687733322

在线咨询:点击这里给我发消息

邮件:1877088071@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code