javase -- Object类


Object.

是所有java类的根父类

  • Object只有一个 无参构造器

Object类中的功能.

1、clone.

protected native Object clone().

  • 创建并返回一个对象的副本(新的对象:包含旧对象的状态)
  • 要想对象能被克隆 必须遵守的规则
    • 1.该类 必须 实现 Cloneable 这个接口(标记接口:没有方法的接口)
    • 2.重写 clone() 方法 ,但是在方法内无需任何操作 至于访问修饰符 可以 改为 public
    • 3.新建对象,调用clone() 即可
  • 像那些 类(已经被定义好的类:不是自定义的);如何实现clone方法
    • 间接实现
      • 继承这个类,通过子类,实现Cloneable接口,重写clone方法,然后生成子类对象是,利用向上转型(多态性),通过父类引用调取子类clone方法
      • 但是,如果一个类 (已定义好的类) 既没有实现Cloneable接口,也没有实现clone方法,最重要的是它还被final修饰,那么将无法实现clone方法
public class A{
    public static void main(String[] args) throws CloneNotSupportedException {

        B b = new B();
        b.b = 2;

        B b_clone = (B)b.clone();

        System.out.println("两对象是否是同一对象:" + (b == b_clone));// false 克隆出来不是同一对象
        System.out.println("克隆对象的属性值:" + b_clone.b);// 2 克隆不仅仅是创建新对象,还包含内容旧对象的状态
    }
}

/*
 * 要想对象能被克隆 必须遵守的规则
 *  1.该类 必须 实现 Cloneable 这个接口(标记接口:没有方法的接口)
 *  2.重写 clone() 方法 ,但是在方法内无需任何操作 : 至于访问修饰符 可以 改为 public
 *  3.新建对象,调用clone() 即可
 */
class B implements Cloneable{
    int b;
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

.

浅克隆: 克隆的对象 和 原始对象的引用类型引用同一个对象

深克隆: 克隆的对象 和 原始对象的引用类型引用不同对象

最好不要使用clone方法

2、finalize(垃圾回收).

protected void finalize().

@Deprecated(since="9")

当垃圾回收器(garbage collector,GC)发现一个对象没有引用指向时,就会回收这个对象

而对象回收之前,(该对象)调用该方法

  • 自动被调用
  • 垃圾回收机制的关键点
    • 垃圾回收机制只回收 JVM堆内存里的对象空间
    • 对其他物理连接,比如数据库连接。输入输出流、Socket连接 无能为力
    • 现有的JVM有多种垃圾回实现算法,表现各异
    • 垃圾回收发生具有不可预知性,程序无法精确控制垃圾回收机制执行
    • 可以将对象的引用设置为null,暗示垃圾回收机制可以回收该对象
    • 程序员可以通过System.gc()或则Runtime.getRuntime.gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定
    • 垃圾回收机制回收任何对象之前,总会先调用它的finalize方法(如果覆盖该方法,让一个新的引用变量重新引用该对象,则会重新激活对象)
    • 永远不要手动调用某个对象的finalize方法,应该交给垃圾回收机制调用
public class A{
    int a;
    public static void main(String[] args) throws CloneNotSupportedException {
        A a = new A();
        a.a = 1;
        a = null;//此时对象实体是垃圾对象,等待被回收,但时间不确定
        System.gc();//强制回收释放
    }

    @Override
    protected void finalize() throws Throwable {
        //对象回收之前,会调用该方法
        System.out.println("对象释放"+this);
        super.finalize();
    }

    @Override
    public String toString() {
        return "A [a=" + a + "]";
    }
}

3、getClass (反射).

public final native Class<?> getClass().

获取当前类型的所属类

  • 获取 当前对象的创建类

    String a = "";
    System.out.println(a.getClass()); // class java.lang.String

4、hashCode(集合).

public native int hashCode().

返回对象的哈希值

5、notify(线程通信).

public final native void notify().

用在同步代码块或同步方法中,释放优先级最高的线程的wait

6、notifyAll(线程通信).

public final native void notifyAll().

用在同步代码块或同步方法中,释放所有的线程的wait

7、wait(线程通信).

public final void wait().

用在同步代码块或同步方法中,阻塞当前线程,并释放锁

  • public final native void wait(long timeoutMillis)
  • public final void wait(long timeoutMillis, int nanos) 等待时间 ms ; 额外时间 ns

8、equals.

public boolean equals(Object obj).

比较两个对象是否相等,是否是同一对象

== &equals

  • ==

    • 比较运算符
    • 使用在基本类型变量和引用类型变量中
      • 如果比较的是基本类型 :比较两个变量的保存数据是否相等类型可以不同(类型自动提升:除了boolean类型))
      • 如果比较的是引用类型 :比较两个对象的地址值是否相等(两个对象引用是指向堆里同一个对象实体)
  • equals

  • 方法

  • 只用于引用数据类型

    • 如果equals方法没有被重写:作用相当于==比较引用类型时

        public boolean equals(Object obj) {
            return (this == obj);
        }
    • 如果equals方法被重写:按重写的来,一般是比较实体内容是否相同(比较属性值是否相等)

        // IDEA 自动生成的重写方法
        //class A 
        //field int a String b 
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            A other = (A) obj;
            if (a != other.a)
                return false;
            if (b == null) {
                if (other.b != null)
                    return false;
            } else if (!b.equals(other.b))
                return false;
            return true;
      }
      
        ```java
        //class A 
        //field int a String b 
        @Override
        public boolean equals(Object obj) {
             if(this == obj){
                return true;
            }   
            if(obj == null){// 可以不要
                return false;
            }
            if(obj instanceof A){
                A o = (A)obj;
                return o.a == this.a && o.b == null ? this.b == null : o.b.equals(this.b);
            }
            return false;
      }
equals的重写需要满足以下五个条件.
  • 自反性
x.equals(x); // ture
  • 对称性
x.equals(y) == y.equals(x); // ture 
  • 传递性
if (x.equals(y) && y.equals(z))
    x.equals(z); // true;
  • 一致性

多次调用 equals() 方法结果不变

x.equals(y) == x.equals(y); // true
  • 与null的比较,返回永远是false
x.equals(null); // false;

9、toString.

public String toString().

  • 当我们输出对象的引用时,实际上是输出对象的toString()

  • StringDateFile包装类都重写了Object类里的toString()方法

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

注意.

  • 在重写equals()方法是应当总是重写hashCode()方法,保证等价的两个对象的哈希值也相等
  • HashSet 和 HashMap 等集合类使用了 hashCode() 方法来计算对象应该存储的位置,因此要将对象添加到这些集合类中,需要让对应的类实现 hashCode() 方法。

文章作者: liuminkai
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 liuminkai !
评论
 上一篇
javase -- instanceof关键字 javase -- instanceof关键字
instanceof. 为了避免在向下转型是出现ClassCastException异常,我们在向下转型之前,先使用instanceof进行判断 对象 instanceof 类或接口:对象 是否是 类或接口 的一个实例(该类的对象或子对象
2020-07-29
下一篇 
javase -- 多态性的表现 javase -- 多态性的表现
多态性. 可理解为一个事物的多种形态 父类的引用指向子类对象(或子类的对象赋给父类的引用) 多态的使用.虚拟方法调用. 当调用子父类同名的方法时,实际执行的是子类重写父类的方法 父类根据子类更据赋给它的不同子类对象,动态调用属于子类的
2020-07-29
  目录