1:【强制】Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。

正例:"test".equals(object);

反例:object.equals("test");

说明:推荐使用 java.util.Objects#equals(JDK7 引入的工具类)。其就是实例对象equals的一个健壮版本

实现:

    /**
* Returns {@code true} if the arguments are equal to each other
* and {@code false} otherwise.
* Consequently, if both arguments are {@code null}, {@code true}
* is returned and if exactly one argument is {@code null}, {@code
* false} is returned. Otherwise, equality is determined by using
* the {@link Object#equals equals} method of the first
* argument.
*
* @param a an object
* @param b an object to be compared with {@code a} for equality
* @return {@code true} if the arguments are equal to each other
* and {@code false} otherwise
* @see Object#equals(Object)
*/
public static boolean equals(Object a, Object b) {
// 可以巧妙避开空指针异常。首先判断a==b,在判断a!=null,如果a==null的话此时a.equals(b)短路
return (a == b) || (a != null && a.equals(b));
}

2:java.util.Objects.deepEquals(Object, Object)方法讲解分析,源码如下:

   /**
* Returns {@code true} if the arguments are deeply equal to each other
* and {@code false} otherwise.
*
* Two {@code null} values are deeply equal. If both arguments are
* arrays, the algorithm in {@link Arrays#deepEquals(Object[],
* Object[]) Arrays.deepEquals} is used to determine equality.
* Otherwise, equality is determined by using the {@link
* Object#equals equals} method of the first argument.
*
* @param a an object
* @param b an object to be compared with {@code a} for deep equality
* @return {@code true} if the arguments are deeply equal to each other
* and {@code false} otherwise
* @see Arrays#deepEquals(Object[], Object[])
* @see Objects#equals(Object, Object)
*/
public static boolean deepEquals(Object a, Object b) {
if (a == b)
return true;
else if (a == null || b == null)
return false;
else
return Arrays.deepEquals0(a, b);
}

java.util.Arrays.deepEquals0(Object, Object)源码如下:

   static boolean deepEquals0(Object e1, Object e2) {
assert e1 != null;
boolean eq;
     // 如下的equals是Arrays中的equals方法,是对每一个元素进行比较
if (e1 instanceof Object[] && e2 instanceof Object[])
eq = deepEquals ((Object[]) e1, (Object[]) e2);
else if (e1 instanceof byte[] && e2 instanceof byte[])
eq = equals((byte[]) e1, (byte[]) e2);
else if (e1 instanceof short[] && e2 instanceof short[])
eq = equals((short[]) e1, (short[]) e2);
else if (e1 instanceof int[] && e2 instanceof int[])
eq = equals((int[]) e1, (int[]) e2);
else if (e1 instanceof long[] && e2 instanceof long[])
eq = equals((long[]) e1, (long[]) e2);
else if (e1 instanceof char[] && e2 instanceof char[])
eq = equals((char[]) e1, (char[]) e2);
else if (e1 instanceof float[] && e2 instanceof float[])
eq = equals((float[]) e1, (float[]) e2);
else if (e1 instanceof double[] && e2 instanceof double[])
eq = equals((double[]) e1, (double[]) e2);
else if (e1 instanceof boolean[] && e2 instanceof boolean[])
eq = equals((boolean[]) e1, (boolean[]) e2);
else
eq = e1.equals(e2);
return eq;
}

java.util.Arrays.equals(char[], char[])源码如下:

/**
* Returns <tt>true</tt> if the two specified arrays of chars are
* <i>equal</i> to one another. Two arrays are considered equal if both
* arrays contain the same number of elements, and all corresponding pairs
* of elements in the two arrays are equal. In other words, two arrays
* are equal if they contain the same elements in the same order. Also,
* two array references are considered equal if both are <tt>null</tt>.<p>
*
* @param a one array to be tested for equality
* @param a2 the other array to be tested for equality
* @return <tt>true</tt> if the two arrays are equal
*/
public static boolean equals(char[] a, char[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false; int length = a.length;
if (a2.length != length)
return false; for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false; return true;
}

示例1:对于基本类型的数组,元素相同,使用Objects的equals方法判定是false,但是对于deepEquals方法是对底层每一个元素调用其equals判断是否相等。

        int[] a = { 1, 2, 3, 4, 5 };
int[] b = { 1, 2, 3, 4, 5 };
// 数组的equals方法其实就是直接判断引用是否相等,不会具体判断每一个元素
System.out.println(Objects.equals(a, b)); // false
System.out.println(Objects.deepEquals(a, b)); // true

示例2:

实体类User,此版本实现了HashCode和equals方法

class User {
public String userName; @Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((userName == null) ? 0 : userName.hashCode());
return result;
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (userName == null) {
if (other.userName != null)
return false;
} else if (!userName.equals(other.userName))
return false;
return true;
} public User(String userName) {
super();
this.userName = userName;
} public User() {
super();
// TODO Auto-generated constructor stub
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} }

此时:

        User[] u1 = { new User("daxin"), new User("mali") };
User[] u2 = { new User("daxin"), new User("mali") };
System.out.println(Objects.equals(u1, u2)); //false
System.out.println(Objects.deepEquals(u1, u2)); //true,调用的User自己实现的equals方法

示例3:没有实现hashcode和equals方法的User:

class User {
public String userName; public User(String userName) {
super();
this.userName = userName;
} public User() {
super();
// TODO Auto-generated constructor stub
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} }

此时:

        User[] u1 = { new User("daxin"), new User("mali") };
User[] u2 = { new User("daxin"), new User("mali") };
System.out.println(Objects.equals(u1, u2)); //false
System.out.println(Objects.deepEquals(u1, u2)); //false,对底层每一个元素调用默认的equals方法(此时equals方法判定的是引用)

3:【强制】所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较。 说明:对于 Integer var = ? 在-128 至 127 范围内的赋值,Integer 对象是在IntegerCache.cache 产生,会复用已有对象,这个区间内的 Integer 值可以直接使用==进行 判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑, 推荐使用 equals 方法进行判断。

示例:

       Integer a=12;
Integer b=12;
System.out.println(a==b);//true
Integer c=1550;
Integer d=1550;
System.out.println(c==d);//false
System.out.println(c.intValue()==d);//对c进行拆箱,所以导致d也拆箱。所以true
System.out.println(c==d.intValue());//对d进行拆箱,所以导致c也拆箱。所以true
System.out.println(c.intValue()==d.intValue());//都拆箱
System.out.println(Objects.equals(c, d));//使用Objects的equals方法比较

4:【推荐】使用索引访问用 String 的 split 方法得到的数组时,需做最后一个分隔符后有无 内容的检查,否则会有抛 IndexOutOfBoundsException 的风险。

说明:

String str = "a,b,c,,";
String[] ary = str.split(",");
// 预期大于 3,结果是 3
System.out.println(ary.length);

又如:

System.out.println(",,,,".split(",").length); //

5:【强制】ArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCastException 异常,即 java.util.RandomAccessSubList cannot be cast to java.util.ArrayList. 说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList ,而是 ArrayList 的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上。

        List<Integer> list =new ArrayList<>();
list.add(1);
list.add(2);
List<Integer> subList = list.subList(0, list.size());
System.out.println(subList);//[1, 2]
subList.add(3); //对subList操作反映在list上
System.out.println(list);//[1, 2, 3]

阿里巴巴Java开发手册要点笔记 (一)的更多相关文章

  1. 阿里巴巴java开发手册阅读笔记

    1. long 或者 Long 初始赋值时,必须使用大写的 L. Long a = 2L; 2. POJO 类(DO/DTO/BO/VO )必须写 toString 方法 3. final 可提高程序 ...

  2. 读书笔记 之 《阿里巴巴Java开发手册》

    一.前言 这本书主要定义了一些代码的规范以及一些注意事项.我只根据我自己的不足,摘录了一些内容,方便以后查阅. 二.读书笔记 命名 1.代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符 ...

  3. 《阿里巴巴 Java 开发手册》读书笔记

    偶然看到阿里巴巴居然出书了???趁着满减活动(节约节约....)我赶紧买来准备看看,刚拿到的时候掂量了好多下,总觉得商家给我少发了一本书,结果打开才知道..原来这本书这么小.... 编码规范的重要性 ...

  4. 读阿里巴巴Java开发手册v1.2.0之工程结构有感【架构篇】

    首先,把昨天那俩条sql语句的优化原因给大家补充一下,第一条效率极低,第二条优化后的,sql语句截图如下: 经过几个高手的评论和个人的分析: 第一条sql语句查询很慢是因为它首先使用了in关键字查询, ...

  5. 码出高效,阿里巴巴JAVA开发手册1.4.0

    码出高效,阿里巴巴JAVA开发手册1.4.0阅读笔记 一.编程规约(三) 代码格式// 关键词if与括号之间必须有一个空格,括号内的f与左括号,0与右括号不需要空格 if (flag == 0) { ...

  6. 阿里巴巴Java开发手册———个人追加的见解和补充(一)

    先上干货,<阿里巴巴Java开发手册>的下载地址 https://yq.aliyun.com/articles/69327?spm=5176.100239.blogcont69327.15 ...

  7. 阿里巴巴Java开发手册评述

    2016年底的时候阿里巴巴公开了其在内部使用的Java编程规范.随后进行了几次版本修订,目前的版本为v1.0.2版.下载地址可以在其官方社区-云栖社区https://yq.aliyun.com/art ...

  8. 阿里巴巴Java开发手册快速学习

    Java作为一门名副其实的工业级语言,语法友好,学习简单,大规模的应用给代码质量的管控带来了困难,特别是团队开发中,开发过程中的规范会直接影响最终项目的稳定性. 善医者“未有形而除之”,提高工程健壮性 ...

  9. 《阿里巴巴Java开发手册(正式版》读记

    前几天,阿里巴巴发布了<阿里巴巴Java开发手册(正式版>,第一时间下载阅读了一番. 不同于一般大厂内部的代码规范,阿里巴巴的这本Java开发手册,可谓包罗万象,几乎日常Java开发中方方 ...

随机推荐

  1. [NOI 2017]蔬菜

    Description 题库链接 小 N 是蔬菜仓库的管理员,负责设计蔬菜的销售方案. 在蔬菜仓库中,共存放有 \(n\) 种蔬菜,小 N 需要根据不同蔬菜的特性,综合考虑各方面因素,设计合理的销售方 ...

  2. Android目录结构及作用

    1.add-ons-->Google API .比如GoogleMaps 2.build-tools-->各版本SDK编译工具. 3.docs-->离线开发者文档Android SD ...

  3. Dynamics CRM 2016/365 窗体中添加按钮

    一.工具下载,及界面介绍 1.下载XrmToolBox工具(XrmToolBox for Microsoft Dynamics CRM/365 CE) 链接:https://www.xrmtoolbo ...

  4. Java学习笔记之——常用快捷键(eclipse)

    * Ctrl+C 复制 * Ctrl+V 粘贴 * Ctrl+A 全选 * Ctrl+S 保存 * Ctrl+Z 撤销 * Ctrl+Y 还原 * Ctrl+X 剪切 * Ctrl+F   查找 * ...

  5. Tests for Variances

    In each case, we'll illustrate how to perform the hypothesis tests of this lesson using summarized d ...

  6. ECMAScript正则表达式6个最新特性

    译者按: 还没学好ES6?ECMAScript 2018已经到来啦! 原文:ECMAScript regular expressions are getting better! 作者: Mathias ...

  7. JS模拟实现数组的map方法

    昨天使用map方法的时候,突然感觉一直在直接用,也没有试试是怎么实现的,本来想直接搜一篇文章盘一下子,结果没搜到合适的,好吧,那就自己来写一下子吧 今天就来实现一个简单的map方法 首先我们来看一下m ...

  8. loadrunner 运行场景-命令行运行场景

    运行场景-命令行运行场景 by:授客 QQ:1033553122 1 相对路径与绝对路径 在场景中为脚本指定一个相对位置,可以是相对于当前场景目录或lr安装目录. 当你运行一个场景,场景自动从这个相对 ...

  9. LeanCloud数据存储相关问题

    1.短信验证码 当注册用户的时候,会发现收不到短信验证码,打印e : That operation isn't allowed for clients. 含义 - 该操作无法从客户端发起.请检查该错误 ...

  10. Django中使用bookstarp框架(4)

    Django中使用bookstarp框架(4) 注意:要使用bookstarp框架前,要先有css的基础 因为主要是研究后台的使用方法,就引入前端的框架,简化html上的耗时(主要是不想把时间浪费在前 ...