首页技术文章正文

Java的Object类及其主要方法

更新时间:2018-10-19 来源:黑马程序员技术社区 浏览量:

Object类介绍

Object类位于java.lang包,是所有Java类的根父类(唯一没有父类的类),所有类的直接或者间接父类。Java中的每个类都是由这个类扩展而来。

java.lang包在使用的时候无需显示导入,编译时由编译器自动导入。

Java认为所有的对象都具备一些基本的共性内容,这些内容可以不断的向上抽取,最终就抽取到了一个最顶层的类中的,该类中定义的就是所有对象都具备的功能。

如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类。 

public class Test [extends Object]{ // 默认继承了Object类
    //...
}


接收任意引用类型的对象

既然Object类是所有对象的父类,则肯定所有的对象都可以向Object进行转换,在这其中也包含了数组和接口类型,即:一切的引用数据类型都可以使用Object进行接收。

使用Object接收接口实例:

public class Test {
    public static void main(String[] args) {
        A ab = new B() ; // 为接口实例化
        Object obj = ab ; // 对象向上转型
        A a = (A)obj ; // 对象向下转型
        a.print();
    }
}
interface A { // 定义接口A
    public void print() ; // 定义抽象方法
}
class B implements A { // 子类实现接口
    public void print(){ // 覆写接口中的抽象方法
        System.out.println("test") ;
    }
}
使用Object接收数组:

public class Test {
    public static void main(String[] args) {
        int[] array = {1, 3, 5, 7, 9} ; // 定义数组
        Object obj = array ; // 使用Object接收数组
        print(obj) ; // 传递数组引用
    }
    public static void print(Object o){ // 接收一个对象
        if(o instanceof int[]) { // 判断对象的类型
            int x[] = (int[])o ; // 向下转型
            for(int i=0;i<x.length;i++){ // 循环输出
                System.out.print(x + "\t") ;
            }
        }
    }
}


Object的主要方法

Object类中定义了一些有用的方法,由于是根类,所以这些方法都在其他类中存在,一般是进行了重载或者覆盖,实现了各自自己的具体功能。



public boolean equals(Object obj)

Object类中的equlas()方法用来检测两个对象是否等价,查看Object源码为:

public boolean equals(Object obj) {
    return (this == obj);
}
equals()只能比较引用类型,其作用与“==”相同,比较是否指向同一个对象(其实内部比较的就是两个对象地址)。对象比较的是引用,即对象在内存中的内存地址,而基本数据类型比较的是值。

用“==”进行比较时,符号两边的数据类型必须兼容(可自动转换的基本数据类型除外),否则编译出错。



equals()方法需要具有如下特点:

自反性(reflexive):任何非空引用x,x.equals(x)返回为true。

对称性(symmetric):任何非空引用x和y,x.equals(y)返回true当且仅当y.equals(x)返回true。

传递性(transitive):任何非空引用x和y,如果x.equals(y)返回true,并且y.equals(z)返回true,那么x.equals(z)返回true。

一致性(consistent):两个非空引用x和y,x.equals(y)的多次调用应该保持一致的结果,(前提条件是在多次比较之间没有修改x和y用于比较的相关信息)。

约定:对于任何非空引用x,x.equals(null)应该返回为false。

Student s1 = new Student(); 
Student s2 = new Student();
System.out.println(s1 == s2);   // false
Student s3 = s1;
System.out.println(s3 == s1);   // true
System.out.println(s1.equals(s2));  // false
System.out.println(s1.equals(s1));  // true
System.out.println(s1.equals(s3));  // true
当用equals()方法进行比较时,对类File、String、Date及包装类(Wrapper Class)来说,是比较类型及内容而不考虑引用的是否是同一个对象;因为在这些类中重写了Object类的equals()方法。下面就是String重写的equals()方法:

// 重写了Object类中的equlas()方法    
public boolean equals(Object anObject) {
    // 判断两个字符串的内存地址是否相等,如果相等,就说明这两个字符串是同一个
    if (this == anObject) {
        return true;
    }
    // 判断参数对象是不是String类型的
    if (anObject instanceof String) {
        // 如果是,就向上转型成一个String对象
        String anotherString = (String)anObject;
        // 对字符串逐个字符进行比较,每个字符都相等,返回true
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1 != v2)
                    return false;
                    i++;
            }
            return true;
        }
    }
    return false;
}


public int hashCode()

返回该对象的哈希码值。哈希值是根据哈希算法计算出来的一个值。这个值和地址值有关,但不是实际地址值。

该方法用于哈希查找,可以减少在查找中使用equals的次数,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。

一般必须满足obj1.equals(obj2)==true,可以推出obj1.hashCode()==obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。如果不重写hashcode(),在HashSet中添加两个equals的对象,会将两个对象都加入进去。

// 对象不同,哈希值一般也不同
Student s1 = new Student();
System.out.println(s1.hashCode()); // 366712642
Student s2 = new Student();
System.out.println(s2.hashCode());  // 1829164700
System.out.println("-------");


public final Class getClass()

返回Object运行时类,也就是说是字节码文件对象。

不可重写,要调用的话,一般和getName()联合使用,如getClass().getName()。

Student s = new Student();
// getClass方法会返回一个Class类的实例对象,然后调用Class类的getName()方法返回全路径名
System.out.println(s.getClass().getName());  // com.zwj.objectdemo.Student


public String toString()

Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于: getClass().getName() + ‘@’ + Integer.toHexString(hashCode())

// toString方法:返回对象的字符串表示
System.out.println(s.toString());  // com.zwj.objectdemo.Student@7852e922
//直接输出对象的名称其实就是调用了对象的toString方法
System.out.println(s);   //com.zwj.objectdemo.Student@7852e922


protected void finalize()

当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法,用于垃圾回收。但是具体什么时间调用此方法不确定。 

Java允许在类中定义一个名为finalize()的方法。它的工作原理是:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法。并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。

关于垃圾回收,有三点需要记住:

1)对象可能不被垃圾回收。只要程序没有濒临存储空间用完的那一刻,对象占用的空间就总也得不到释放。

2)垃圾回收并不等于“析构”。

3)垃圾回收只与内存有关。使用垃圾回收的唯一原因是为了回收程序不再使用的内存。

finalize()的用途:

无论对象是如何创建的,垃圾回收器都会负责释放对象占据的所有内存。这就将对finalize()的需求限制到一种特殊情况,即通过某种创建对象方式以外的方式为对象分配了存储空间。

不过这种情况一般发生在使用“本地方法”的情况下,本地方法是一种在Java中调用非Java代码的方式。



protected Object clone()

创建并返回此对象的一个副本,需要重写该方法。

要克隆的类去实现Cloneable接口 ,Cloneable接口是标记接口,实现该接口的类就可以实现对象的复制。

public class Student implements Cloneable{
    private String name; // 姓名

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
我们来测试一下:

public class StudentTest{
    public static void main(String[] args) throws CloneNotSupportedException {
        // 创建显示对象
        Student s = new Student();
        s.setName("zwj");      
        // 克隆学生对象
        Student cloneStu = (Student) s.clone();
        // 引用
        Student s2 = s;
        System.out.println(s.getName());   // zwj,
        System.out.println(cloneStu.getName());  // zwj
        System.out.println(s2.getName());   // zwj

        s2.setName("爪哇菌");
        System.out.println(s.getName());   // 爪哇菌
        System.out.println(cloneStu.getName());  // zwj
        System.out.println(s2.getName());  // 爪哇菌
    }
}
由以上代码代码可以看出Clone()方法的使用比较简单,使用时注意如下几点即可:

什么时候使用shallow Clone,什么时候使用deep Clone,这个主要看具体对象的域是什么性质的,基本型别还是reference variable。

调用Clone()方法的对象所属的类必须实现(implements )Clonable接口,否则在调用Clone方法的时候会抛出CloneNotSupportedException。
--------------------- 
【转载】
作者:下班后的爪哇菌 
原文:https://blog.csdn.net/lxxiang1/a ... 874?utm_source=copy

本文版权归黑马程序员JavaEE培训学院所有,欢迎转载,转载请注明作者出处。谢谢!

作者:黑马程序员JavaEE培训学院
首发:http://java.itcast.cn/?skc





分享到:
在线咨询 我要报名
和我们在线交谈!