Java学习笔记18

Objects是Java 7新增的一个工具类,它提供了一些工具方法来操作对象,这些工具方法大多是“空指针”安全的。

Objects实现的方法如下:

在源码中Objects工具类中equals(Object,Object)是如何定义的:

 public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }

通过以上程序不难发现当两个对象a、b都为null时,返回的也是true,而且保证了只有在其中一个对象a 不为null的情

况下去比较对象a与对象b是否相等。通过以上方法可以避免NullPointerException的异常。

OK,我们看看以下程序:

class User {

    private String name;
    private int age;

    public User(String name,int age){
    	this.name=name;
    	this.age=age;
    }

    protected String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
    	return "name="+name+"\nage="+age;
    }

}
public class Main {
	private static User user1;
	private static User user2;
	public static void main(String[] args) {
		System.out.println(Objects.equals(user1, user2));
		System.out.println(user1.equals(user2));
	}

}

输出结果:

true

Exception in thread "main" java.lang.NullPointerException

at code2.Main.main(Main.java:37)

当user1和user2都为null时,执行Objects的equals(Object,Object)方法时得到true,当执行Object的equals(Object)时,

抛出NullPointerException异常。

接着我们来看看deepEquals(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);
    }

在上面程序中,可以看出,如果两个对象的是相等,相等返回true,反之,判断其中一个是否为null,如果其中一个

为null的话返回false,反之执行Arrays.deepEquals0(a,b)的方法。我们看下Arrays.deepEquals0(a,b)在源码中是如何实

现的:

 static boolean deepEquals0(Object e1, Object e2) {
        assert e1 != null;
        boolean eq;
        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;
    }

先看看assert这个关键字,在Java中,assert这个关键字表示的是断言。当断言开启时(执行java -ea AssertFoo,默认是

不开启的:java
AssertFoo)以上assert的用法是,当assert后面的boolean表达式为true时,继续执行,如果为false,程

序抛出AssertionError,并且终止执行。assert除了以上用法之外还可以按下面格式使用:

assert<boolean表达式> : <错误信息表达式>;

那么它的功能是,当后面的boolean表达式为true时,继续执行,反之抛出java.lang.AssertionError,并且输出错误信

息。

以上使用assert确保了e1不为null,以免当执行到eq=e1.equsls(e2)时抛出异常,接着看到在if语句中使用到了

instanceof关键字来判断是否是同一个类的实例,如果是的话,分别执行对应if下的语句。

如果if(e1 instanceof Object[] && e2 instanceof Object[])为 true时,执行以下方法:

 public static boolean deepEquals(Object[] a1, Object[] a2) {
        if (a1 == a2)
            return true;
        if (a1 == null || a2==null)
            return false;
        int length = a1.length;
        if (a2.length != length)
            return false;

        for (int i = 0; i < length; i++) {
            Object e1 = a1[i];
            Object e2 = a2[i];

            if (e1 == e2)
                continue;
            if (e1 == null)
                return false;

            // Figure out whether the two elements are equal
            boolean eq = deepEquals0(e1, e2);

            if (!eq)
                return false;
        }
        return true;
    }

在程序中分别判断了两个Object数组的长度是否,相等,并通过for循环对每个对象先通过==来判断它们的地址是否

相等,否则执行deepEquals0(Object , Object)方法来判断每个对象在堆中的内容是否相等。

接着我们看看以上每个if语句后的方法:

 public static boolean equals(byte[] a, byte[] 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;
    }
 public static boolean equals(short[] a, short 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;
    }
 public static boolean equals(int[] a, int[] 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;
    }
 public static boolean equals(long[] a, long[] 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;
    }
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;
    }
 public static boolean equals(float[] a, float[] 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 (Float.floatToIntBits(a[i])!=Float.floatToIntBits(a2[i]))
                return false;

        return true;
    }
 public static boolean equals(double[] a, double[] 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 (Double.doubleToLongBits(a[i])!=Double.doubleToLongBits(a2[i]))
                return false;

        return true;
    }
public static boolean equals(boolean[] a, boolean[] 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;
    }

现在我们可以发现,以上的方法都有一个相同点,都是判断数组的长度,以及每个元素是否相同。也就是

deepEquals0方法是对数组做深层次的比较。

我们看以下程序:

public class Main {
	public static void main(String[] args) {
		int[] i_int1=new int[]{1,2,3,4};
		int[] i_int2=new int[]{1,2,3,4};
		System.out.println(Objects.deepEquals(i_int1, i_int2));
		int[] i_int3=new int[]{1,2,3,5};
		int[] i_int4=new int[]{1,2,3,4};
		System.out.println(Objects.deepEquals(i_int3, i_int4));
	}
}

通过前面对deepEquals0方法的介绍,可以很快的得出以上程序的结果。

输出结果为:

true

false

转载请注明出处:http://blog.csdn.net/hai_qing_xu_kong/article/details/43926545   情绪控_

时间: 2024-10-28 09:50:31

Java学习笔记18的相关文章

我的java学习笔记(18)关于内部类(part 3)

1.当使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要在内部类引用外部类对象时,可以将内部类为static,以便取消产生的引用. 2.只有内部类可以声明为static.静态内部类的对象除了没有对生成它的外部类对象的引用特权外,其他与所有内部类完全一样. 实例代码 测试类 public class test { public static void main(String[] args) { double[] d = new double[20]; for(int i = 0; i <

Java学习笔记_25_Collections类

25.Collections类: Collections类是一个工具类,用来对集合进行操作,它主要是提供一些排序算法,包括随机排序.反相排序等. Collections类提供了一些静态方法,实现了基于List容器的一些常用算法. Collections的一些方法列表: · void sort(List): 对List内的元素进行排序. · void shuffle(List): 对List内的元素随机排序. · void reverse(List): 对List内的元素进行逆序排列. · voi

java学习笔记3——java关键字

java学习笔记3——java关键字 虽然老师说不用刻意的去记忆,但是我还是在网上找到了非常详细的注解,再次收藏 关键字的类型表: 各个关键字的详细注解和实例,按首字母排序: 1.abstract abstract 关键字可以修改类或方法. abstract 类可以扩展(增加子类),但不能直接实例化. abstract 方法不在声明它的类中实现,但必须在某个子类中重写. -示例- public abstract class MyClass{ } public abstract String my

【Java学习笔记之二十六】深入理解Java匿名内部类

在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意的事项.如何初始化匿名内部类.匿名内部类使用的形参为何要为final. 一.使用匿名内部类内部类 匿名内部类由于没有名字,所以它的创建方式有点儿奇怪.创建格式如下: new 父类构造器(参数列表)|实现接口() { //匿名内部类的类体部分 } 在这里我们看到使用匿名内部类我们必须要继承一个父类或者

Java学习笔记之继承

一.继承的基础 在Java术语中,被继承的类叫超类(superclass),继承超类的类叫子类(subclass). 举例说明: 1 class Box 2 { 3 public double width; 4 public double height; 5 public double depth; 6 7 //重载构造方法 8 public Box(Box ob) 9 { 10 width = ob.width; 11 height = ob.height; 12 depth = ob.dep

Java学习笔记之接口

一.接口的概念与定义 首先考虑一个简单的接口的定义: public interface Output { int MAX_LINE = 40; void out(); void getData(String msg); } 定义接口使用关键字interface 修饰符interface前面的public可以省略,如果省略,则采用默认访问控制,即只有在相同包结构的代码才可以访问此接口 接口不可以有构造方法(区别于类中的构造方法) 接口里面的所有成员,包括常量.方法等都是public访问权限,所以在

Java 学习笔记(2015.7.20~24)

Java 学习笔记(2015.7.20~24) Java Java 学习笔记(2015.7.20~24) 1.StringBuffer与StringBuilder的区别: 2.基本数据类型包装类 3.Date.Calendar.DateFormat等与时间相关的类 1.常用类String 2.正则表达式 3.常用类 StringBuffer 代表可变的字符序列 拆箱与装箱 包装类的应用 匿名内部类 数组 day11 day12 day13 day14 day11 父类中使用public定义的方法

java学习笔记12--异常处理

java学习笔记系列: java学习笔记11--集合总结 java学习笔记10--泛型总结 java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Object类 java学习笔记5--类的方法 java学习笔记4--对象的初始化与回收 java学习笔记3--类与对象的基础 java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址:http://www.cnblogs.com/arch

Java学习笔记_18_字符串、包装类、原始数据类剪得转换

18. 字符串.包装类.原始数据类剪得转换: 各个转换如下: 1>String 转换成Integer: Integer integer = new Integer("string");或 Integer Integer = Integer.valueOf(String): 注:String必须是数字字符串,如:"1232". 2>Integer 转换成String: String str = Integer.toString(); 3>Intege