Java常用类:Object类常用方法详解

作为一个稀有的Java妹子,所写的所有博客都只是当作自己的笔记,留下证据自己之前是有用心学习的~哈哈哈哈(如果有不对的地方,也请大家指出,不要悄悄咪咪的不告诉我)

Object类

相信大家一开始学习Java的时候都知道所有的类都是Object的子类,都默认继承Object,那么对于该类的一些常用方法大家是否有深入的了解呢,今天就给大家详细介绍以下几个常用的方法。

1.clone()

该方法可以在内存空间创建一个新对象,且属性值与原对象一样。
如果使用=把一个对象赋给另一个对象,只是使得两个变量指向同一个内存空间,如果其中一个变量通过set方法修改了属性值,另一个变量访问时,值也会被修改;如果使用clone(),则不会出现上述情况。

public class ObjectDemo implements Cloneable{
    private String name;
    private Integer age;
    public ObjectDemo(String name,Integer age){
        this.name = name;
        this.age = age;
    }
     public static void testClone() throws CloneNotSupportedException {
        ObjectDemo objectDemo1 = new ObjectDemo("王二",26);
        System.out.println("使用普通copy前的age:"+objectDemo1.getAge());
        ObjectDemo objectDemo2 = objectDemo1;
        objectDemo2.setAge(18);
        System.out.println("使用普通copy后的age:"+objectDemo1.getAge());
    }
}

只使用=赋值的结果:
结果
使用clone()赋值

public static void testClone() throws CloneNotSupportedException {
        ObjectDemo objectDemo1 = new ObjectDemo("王二",26);
        System.out.println("使用clone前的age:"+objectDemo1.getAge());
        //使用clone()赋值
        ObjectDemo objectDemo2 = (ObjectDemo) objectDemo1.clone();
        objectDemo2.setAge(18);
        System.out.println("使用clone后的age:"+objectDemo1.getAge());
    }

结果:通过objectDemo2修改对象的值并不会影响到原始对象的属性值
在这里插入图片描述
注意:
1.以上方法适用于成员变量是基本数据类型的,如果是对象类型的,需要重写clone方法。
2.使用clone()方法需要实现Cloneable接口,不然会报CloneNotSupportedException异常。

深拷贝例子

public class DeepCloneableTarget implements Serializable, Cloneable {
    private static final long serialVersionUID = 1L;
    private String cloneName;
    private String cloneClass;
    //构造器
    public DeepCloneableTarget(String cloneName, String cloneClass) {
        this.cloneName = cloneName;
        this.cloneClass = cloneClass;
    }
 
    //因为该类的属性,都是String , 因此我们这里使用默认的clone完成即可
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class DeepProtoType implements Serializable, Cloneable {
    public String name; //String 属性
    public DeepCloneableTarget deepCloneableTarget;// 引用类型
    public DeepProtoType() {
        super();
    }
    //深拷贝 - 通过对象的序列化实现 (推荐)
    public Object deepClone() {
        //创建流对象
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            //序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this); //当前这个对象以对象流的方式输出
 
            //反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            DeepProtoType copyObj = (DeepProtoType)ois.readObject();
 
            return copyObj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            //关闭流
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            } catch (Exception e2) {
                System.out.println(e2.getMessage());
            }
        }
    }
}

2.toString()

 public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

一般都会重写该方法,返回所有的属性值。一般来讲,该方法用于将对象的属性值打印日志,或者调试时需要知道对象的属性值。在这里也给大家安利一个注解@Data,在类上使用该注解会重写toString方法,且不用手写getter和setter,使得代码更简洁。

3.equals()

public boolean equals(Object obj) {
        return (this == obj);
    }

比较的是内存地址是否相等,如果当属性值都相等则认为对象相等的话,需要重写equals方法,如String类就重写了equals方法。
注意基本数据类型的包装类,如Integer、Bigdecimal,通过new创建两个不同的对象,值一样时,使用equals的结果为true

public static void testEquals(){
        Integer c = new Integer(10);
        Integer d = new Integer(10);
        System.out.println(c.equals(d));
        BigDecimal e = new BigDecimal(0.89);
        BigDecimal f = new BigDecimal(0.89);
        System.out.println(e.equals(f));
    }

结果:
在这里插入图片描述
原因是包装类的equals做了处理,比较的是值是否相等而不是内存地址

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

4.hashCode()

hashCode返回一个int整数类型的散列值,该值用于确定对象在“类的散列表”中的位置,散列表,指的是:Java集合中本质是散列表的类,如HashMap,Hashtable,HashSet。也就是说:hashCode() 在散列表中才有用,在其它情况下没用。在散列表中hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。
hashCode方法的作用也是比较两个对象是否相等,通过比较返回的散列值是否相等来判断,那么既然有了hashCode,为什么还要有equals呢?因为hashCode不是绝对正确的,有可能会出现两个不同对象计算出来的hash值相同,那既然结果不是绝对准确,为啥不直接使用equals,抛弃hash呢?因为hash算法比equals方法简单,效率高,所以在大量且快速的比较运算时,先使用hashCode,若不等,则两个对象肯定不相同了,就不用再equals比较了,如果不等,再使用equals比较。

5.getClass()

返回当前对象的Class对象,通过该对象可以获取所有的类相关的信息。
如getName返回类的全路径信息
getClassLoader返回类加载器等等。

其他跟线程相关的方法等后续出线程相关的文章再介绍…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值