zoukankan      html  css  js  c++  java
  • Java知识点:Object类

    toString()方法

    原始实现:

    1 public String toString() 
    2 {
    3     return getClass().getName() + "@" + Integer.toHexString(hashCode());    //类名+@+对象的hash值的十六进制
    4 }

    hashCode()和equals()方法

    方法:

    • public boolean equals(Object obj);
    • public int hashCode();

    默认规则:

    • 如果两个引用变量引用的是不同对象,则hash值不同,equals返回false。
    • 如果两个引用变量引用的是同一个对象,则hash值相同,equals返回true。

    建议:

    • 要么同时实现equals和hashCode方法,要么都不要实现。
    • 在eclipse中可以自动实现,【source】->【generate hashcode() and equals()】。

    如果一个类不实现equals和hashCode方法,会有坏处:

      对于类似 HashSet 的hash数据结构(比如HashSet<Person> set = new HashSet<Person>(),其中 Person 是自己实现的类),在HashSet中加入new Person("A")、new Person("B")。
    如果想要查找是否存在一个名叫"A"的人,则需要:

    set.contains(new Person("A"));                   //返回false

    我们希望他返回true,因为确实存在一个名叫A的人,但是实际返回的是 false。因为contains(Person p) 的运行规则是:

    1. 执行 p.hashCode()找到正确的桶。
    2. 对于那个桶中的每个元素b,执行p.equals(b),如果有一个返回true,则contains方法返回true,否则返回false。

    因为查找的对象和在HashSet中的对象的hash值不同,因此根本找不到对应的桶。

    clone()方法和Cloneable接口

    方法:

    • protected native Object clone() throws CloneNotSupportedException;

    从上面的方法中可以看出:

    • 该方法并没有方法体,而是声明为native,表示这是本地方法。
    • protected: 这个方法只有在同一个包或者子类中才能够调用。
    • 函数返回的是Object,因此每次调用clone后需要强制类型转换。

    因此下面的代码并不能编译通过:

    String s1 = "hello";
    String s2 = (String)s1.clone();   // Compile Error

    不能编译通过的原因:

    • String类定义在java.lang包中。
    • String类没有实现cloneable接口。
    • 此代码所在包和String类在不同的包中。

    注意点:

    • 虽然Cloneable接口只是一个标识接口,但是只有实现了Cloneable接口,才表示这个类是可复制的。
    • 如果定义了一个类A,此类没有重写clone方法,则 类A的对象a调用clone方法时,编译错误。
    • 如果定义了一个类A,此类直接重写clone方法, 而不实现Cloneable接口,则类A的对象a调用clone方法时,会抛出:CloneNotSupportedException。
    • 默认clone方法实现的是浅层复制,而不是深层复制。
    • 在重写clone方法时,建议先执行super.clone()方法。

    深层复制和浅层复制

    浅层复制: 被复制的对象的所有成员属性都有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅层复制仅仅复制所考虑的对象,而不复制它所引用的对象。

    文字的表述不是很清晰,下面用图示来解释:

    如果想实现深层复制也可以通过串行化来实现(将对象写入字节流,再从字节流读出)。

    下面的代码演示了深层复制和浅层复制的实现:

     1 public class Object05
     2 {
     3     public static void main(String[] args) throws Exception{
     4         A a1 = new A(10);
     5         B b1 = new B(a1);
     6         B b2 = (B)b1.clone();
     7         b1.a.age = 20;
     8         System.out.println(b2.a.age);    //输出:10,改变b1并不会改变b2
     9 
    10 
    11         A a2 = new A(10);
    12         C c1 = new C(a2);
    13         C c2 = (C)c1.clone();
    14         c1.a.age = 30;
    15         System.out.println(c2.a.age);    //输出30,改变c1会改变c2
    16 
    17 
    18     }
    19 }
    20 class B implements Cloneable
    21 {
    22     A a;
    23     public B(A a)
    24     {
    25         this.a = a;
    26     }
    27     public Object clone()throws CloneNotSupportedException    //深层复制
    28     {
    29         B b = (B)super.clone();
    30         b.a = (A)this.a.clone();
    31         return b;
    32     }
    33 }
    34 class C implements Cloneable
    35 {
    36     A a;
    37     public C(A a)
    38     {
    39         this.a = a;
    40     }
    41     public Object clone()throws CloneNotSupportedException //浅层复制
    42     {
    43         return super.clone();
    44     }
    45 }
    46 class A implements Cloneable
    47 {
    48     int age;
    49     public A(int age)
    50     {
    51         this.age = age;
    52     }
    53     public Object clone()throws CloneNotSupportedException
    54     {
    55         return super.clone();
    56     }
    57 }
    View Code

    finalize()方法

    此方法是由垃圾回收器调用的,当垃圾回收器决定回收对象a时,则会调用a的finalize方法。

    getClass()方法

    此方法主要用于反射,下面的例子简单的介绍了这个方法的应用:

     1 import java.lang.reflect.Field;
     2 public class Object06
     3 {
     4     public static void main(String[] args) {
     5         Class c = new Person().getClass();
     6         System.out.println("类名:"+c.getName());
     7         Field[] fs = c.getDeclaredFields();
     8         System.out.print("字段名:");
     9         for(Field f:fs)
    10         {
    11             System.out.print(f.getName()+",");
    12         }
    13     }
    14 }
    15 class Person
    16 {
    17     private String name;
    18     private int age;
    19 }
  • 相关阅读:
    gulp自动化压缩合并、加版本号解决方案
    利用gulp 插件gulp.spritesmith 完成小图合成精灵图,并自动输出样式文件
    gulp插件(8)
    gulp插件 run-sequence(同步执行任务)
    gulp合并压缩
    Freemarker 基础概念
    querystring模块详解
    深入理解JavaScript的闭包特性如何给循环中的对象添加事件
    堆中的路径
    公式求值
  • 原文地址:https://www.cnblogs.com/xiazdong/p/3200429.html
Copyright © 2011-2022 走看看