为什么说一个好的员工能顶 100 个普通员工

我们的做法是,要用最好的人。我一直都认为研发本身是很有创造性的,如果人不放松,或不够聪明,都很难做得好。你要找到最好的人,一个好的工程师不是顶10个,是顶100个。所以,在核心工程师上面,大家一定要不惜血本去找,千万不要想偷懒只用培养大学生的方法去做。最好的人本身有很强的驱动力,你只要把他放到他喜欢的事情上,让他自己有玩的心态,他才能真正做出一些事情,打动他自己,才能打动别人。所以你今天看到我们很多的工程师,他自己在边玩边创新。所以,找最好的人,要给他做他喜欢和擅长的事情。研发人员千万不要去管太严,一管就“死”了。工程师很讨厌跟规章制度打交道,作汇报他都很烦,大家不要管他,让用户去管他。他做好了一个产品,用户表扬他,这个大神多牛逼。他做不好了,用户骂他,他自己赶紧去改。

再谈阿里巴巴 Java 开发手册

之前在这个手册刚发布的时候看过一遍,当时感觉真是每个开发者都应该必读的一本手册,期间还写过一篇关于日志规约的文章:《下一个项目为什么要用 SLF4J》,最近由于在总结一些我们日常开发中容易忽略的问题,可能是最低级的编码常见问题,往往这也是最最容易忽略的,所以,又重新看了一遍这个手册,好像最近它也更新到了 1.2 版本。

这个手册目的就是让我们尽可能少踩坑,杜绝踩重复的坑。我接下来就打算试着写一些“坑”出来,来看看我们如何一不留神踩坑的,以及如何用正确的姿势跳出坑。

随随便便写出 NPE

首先声明一个 User 对象,接下来所有代码可能都会用到这个对象做演示,在下面将不在赘述。很简单,不上代码,上图片:

1.自动解箱抛 NPE

代码只有一行,再简单不过了:int method() { return new User().getId(); }

踩坑姿势:包装类型为 null 时,进行自动转换为基本数据类型报错。

解决方案:返回之前进行判断与处理或者改为相同类型。

2.级联调用易产生 NPE

这段代码有点容易迷惑人,因为它进行了集合元素的 isEmpty 判断,按说不会出问题了吧。看代码:

static void method1() {
List<User> list = new ArrayList<User>();
list.add(new User()); if (!CollectionUtils.isEmpty(list)) {
for (User user : list) {
System.out.println("userid:" + user.getId().toString());
}
}
}

不废话,看运行结果:

没错,还是报错了。

踩坑姿势:其实就是尽管你在之前做了对象不为空的判断,但你并不能保证对象中的值不为空,而且这时候去级联调用就会抛 NPE 。

手册中关于 NPE 的描述:

防止 NPE 是调用者的责任。即使被调用方法返回空集合或者空对象,对调用者来说,也并非高枕无忧,必须考虑到远程调用失败、序列化失败、运行时异常等场景返回 null 的情况。

集合里的元素即使 isEmpty,取出的数据元素也可能为 null。

级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE

3.关于 Equals

这是日常开发中用于相等比较使用最多的方法了吧,因为当年谁没被 == 坑过阿。现在一般我们都会这么写:user.getName().equals("mafly");

踩坑姿势: 一不小心使用了 null 值调用了 Equals 方法。

解决方案: 很简单咯,这么写:"mafly".equals(user.getName());

equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。

4.Map 下的 NPE

Map 应该是我们开发中使用最频繁的了,最常用的可能有 HashMapConcurrentHashMap 这俩了,可能会一不留神写出这样的代码:

踩坑姿势: 可能我们知道 ConcurrentHashMap 的 K/V 都不能为空,但我们有时候并不知道传进来的值是否为空。

解决方案: 设置时做下检验,对它的特性正确理解及使用。

由于 HashMap 的干扰,很多人认为 ConcurrentHashMap 是可以置入 null 值,而事实上,

存储 null 值时会抛出 NPE 异常

Map 类集合 K/V 能不能存储 null 值的情况,如下表格:

集合类 Key Value Super 说明
Hashtable 不允许为 null 不允许为 null Dictionary 线程安全
ConcurrentHashMap 不允许为 null 不允许为 null AbstractMap 分段锁技术
TreeMap 不允许为 null 允许为 null AbstractMap 线程不安全
HashMap 允许为 null 允许为 null AbstractMap 线程不安全

简单聊聊常用的集合

5.foreach 遍历集合删除元素

大家应该都知道,在遍历集合时对元素进行 add/remove 操作要使用 Iterator,使用 for 循环时会报错,一定会报错吗?看代码:

public static void main(String[] args) {
List<String> a = new ArrayList<>();
a.add("1");
a.add("2");
a.add("3"); for (String temp : a) {
if ("2".equals(temp)) {
a.remove(temp);
}
} Iterator<String> it = a.iterator();
while (it.hasNext()) {
String temp = it.next();
if ("2".equals(temp)) {
it.remove();
}
}
}

应该会报错的吧?因为在 for 循环中移出了元素,如果你运行了就会惊讶的,输出如下:

不解释其中原因了,感兴趣的可以看这篇文章:《foreach遍历list删除元素一定会报错?》。不管是不是倒数第二个元素才没问题,我们依然要注意不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator 方式(代码第二种),如果并发操作,需要对 Iterator 对象加锁。

6.Arrays.asList() 数组转换集合

这个工具类应该都用过,可以很方便的把数组转换为集合,直接看结果吧:

踩坑姿势: Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。 asList() 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。

解决方案: 在转换之前操作咯。还需要注意一点,在你转换后,再对数组的值进行修改时,集合也会跟着变哦(注释掉的代码)。

7. toArray() 集合转换数组

当我们需要把一个集合转换为数组时,往往会调用 toArray() 方法,如果你用的是无参的这个可以吗?

当然不可以啦!会报 ClassCastException 异常。

踩坑姿势: 直接使用 toArray() 无参方法返回值只能是 Object[]类,若强转其它类型数组将会抛异常。

解决方案: 使用 <T> T[] toArray(T[] a); 有参数这个方法,代码如下:

String[] array = new String[list.size()];
array = list.toArray(array);

8. subList 的使用

集合中的 subList 是用于来返回某一部分的视图内容的,可能我们不是很常用,但是其中有好多坑的,直接看代码:



这次我们从输出来看上面的所有关于 subList 的代码。

  • 18行: 当你原始集合大小没有那么大时,毫无疑问抛异常。
  • 20-21行:得到一个新的集合,我们往新集合中增加一条数据。
  • 23-26行:遍历原始集合,竟然 size=2 了,而且往新集合中增加的数据存在与原始集合。
  • 28-31行:移除新集合中一条数据,遍历新集合。
  • 33-37行:原始集合增加一条数据并遍历。
  • 40-42行:遍历新集合,抛出 ConcurrentModificationException 异常。

从上述代码中,我们应该可以得出如下结论:返回的新集合是靠原来的集合支持的,修改都会影响到彼此对方。在 subList 场景中,高度注意对原集合元素个数的修改,会导致子列表的遍历、增加、删除均产生异常。

先总结一下

写到这只是其中关于异常部分的一些坑吧,还有另外一些令人异常惊讶的“我的天吶”的问题,由于篇幅太长了点,感觉不能再写下去了,过两天再接着写吧。

异常真的是一个有意思的问题。

Java 开发中如何正确踩坑的更多相关文章

  1. Java开发中碰到的Map的坑

    这属于我在开发中碰过的坑 ,容器中存放者对象,当clear()的时候,出现的奇葩问题.好了,直接看代码: package com.DataType.yinyong; import java.util. ...

  2. 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)

    编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...

  3. 记一次SpringBoot 开发中所遇到的坑和解决方法

    记一次SpringBoot 开发中所遇到的坑和解决方法 mybatis返回Integer为0,自动转型出现空指针异常 当我们使用Integer去接受数据库中表的数据,如果返回的数据中为0,那么Inte ...

  4. Java开发中常见的危险信号(中)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  5. java开发中遇到的问题及解决方法(持续更新)

    摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他 ...

  6. Java开发中常见的危险信号(上)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  7. [ 转载 ] Java开发中的23种设计模式详解(转)

    Java开发中的23种设计模式详解(转)   设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类 ...

  8. JAVA基础(零)—— 踩坑与错误(常更)

    JAVA基础(零)-- 踩坑与错误(常更) 1 坑 考虑输入为null的情况 自动转换 x/Math.pow(10,i)*Math.pow(10,i) //由于math.pow()返回double类型 ...

  9. paip.java 开发中web server的选择jboss resin tomcat比较..

    paip.java 开发中web server的选择jboss resin tomcat比较.. 作者Attilax  艾龙, EMAIL:1466519819@qq.com 来源:attilax的专 ...

随机推荐

  1. SpringCloud网关ZUUL集成consul

    最近一直在搞基于springcloud的微服务开发,为了不限定微服务开发语言,服务发现决定采用consul不多说上代码 pom文件 <project xmlns="http://mav ...

  2. 文本处理sed常用操作

    文本处理sed常用操作 linux sed (stream editor) is a Unix utility that parses and transforms text, using a sim ...

  3. 前端随手优化不完全篇-SEO篇

    一代码优化概述 关于代码优化的知识是纯理论的知识,学习的很枯燥.在学到CSS时,不免遇到CSS+div进行代码优化的知 识,因此在网上看了一些关于这方面的知识,简单的整合一下,梳理自己所了解的代码优化 ...

  4. fir.im Weekly - 如何在 iOS 上构建 TensorFlow 应用

    本期 fir.im Weekly 收集了最近新鲜出炉的 iOS /Android 技术分享,包括 iOS 系统开发 TensorFlow 教程.iOS 新架构.iOS Notifications 推送 ...

  5. CF #345 Div1 D Zip-line

    题目链接:http://codeforces.com/contest/650/problem/D 大意是给一个数组,若干询问,每一次把一个数字改为另一个数字,问当前数组最长上升子序列,询问之间是独立的 ...

  6. Ubuntu搭建ssh连接(连接方式:桥接网卡、网络地址转换(NAT))

    操作系统:Ubuntu Server 16.04.2 SSH软件:Putty(远程连接工具,视本机操作系统选择对应版本的putty) --------------------------------- ...

  7. 设置spring-boot的logging

    spring-boot默认使用logback来记录logger,spring-boot的包里面org.springframework.boot.logging.logback路径下面有一些配置文件,默 ...

  8. Struts2框架的基本使用

         前面已经介绍过了MVC思想,Struts2是一个优秀的MVC框架,大大降低了各个层之间的耦合度,具有很好的扩展性.从本篇开始我们学习Struts2的基本用法,本篇主要包括以下内容: Stru ...

  9. java.util.NoSuchElementException: None.get的解决方法

    在Java中用null表示无值返回.在Java 里,null 是一个关键字,不是一个对象,所以对它调用任何方法都是非法的 笔者就常在类型转换时见到空指针错误,便是由null的特殊性导致的 而在scal ...

  10. JDK的下载与配置

    一.下载JDK 1.进入oracle官网 下载完成后直接运行就能生成jdk文件. 二.配置环境 1.打开环境配置 右击计算机选择属性 选择高级系统数据 点击环境变量 2.配置JAVA_HOME 新建一 ...