为什么说一个好的员工能顶 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. MySQL元数据库——information_schema

    平时使用MySQL客户端操作数据库的同学,只要稍微留神都会发现,除了我们建的库之外,还经常看到三个数据库的影子: 1. information_schema 2. performance_schema ...

  2. 图解函数重载以及arguments

  3. jQuery / zepto ajax 全局默认设置

    jQuery / zepto 的 $.ajax 方法需要配置很多选项, 有些是很常用的每个 ajax 请求都要用到的, 可以全局设置, 避免每次都写. 注意: 此处用的 jQuery 版本是 1.8. ...

  4. 读《effective C++》1

    条款一:视C++为一个语言联邦 学习C++半个月了,学了他的面向过程编程,面向对象编程(封装性,继承性,多态性),template泛型编程,开始只是觉得C++基础是面向对象,但是学了这么多块开始有点迷 ...

  5. 速成制作rpm包

    FPM 由于很多软件在安装时需要编译,这会浪费不少的时间,为了提升部署效率,于是就想到制作rpm包.通常rpm包的制作是使用rpmbuild命令来制作,但是你需要知道它的语法,比较繁琐.这就用到了FP ...

  6. SQLite数据库_实现简单的增删改查

    1.SQLite是一款轻量型的数据库是遵守ACID(原子性.一致性.隔离性.持久性)的关联式数据库管理系统,多用于嵌入式开发中. 2.Android平台中嵌入了一个关系型数据库SQLite,和其他数据 ...

  7. 2017百度web前端实习生在线笔试题

    代码: import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner s ...

  8. 前端JS来控制选中的项

    < script type = "text/javascript" > function change(){ document.getElementById(" ...

  9. selenium IDE的3种下载安装方式

    第一种方式: 打开firefox浏览器-----点击右上角-----附加组件----插件----搜索框输入“selenium”-----搜索的结果中下拉到页面尾部,点击“查看全部的37项结果”---进 ...

  10. POJ 3311---Hie with the Pie(状压DP)

    题目链接 Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as ...