漫画:Object类很大,你忍一下

简介: getClass()getClass方法是干什么的呢?首先,getClass方法用于获取一个对象的运行时类(Class),进而通过返回的Class对象,获取该类的相关信息,比如获取该类的构造方法、该类有哪些方法、该类有哪些成员变量等信息。


640.png

640.png640.png640.png640.png640.png640.png640.png

 

 

————————————

640.png640.png640.png640.png640.png640.png


想要了解clone方法的小伙伴,可以看看之前所讲解 原型模式

 

getClass()




getClass方法是干什么的呢?首先,getClass方法用于获取一个对象的运行时类(Class),进而通过返回的Class对象,获取该类的相关信息,比如获取该类的构造方法、该类有哪些方法、该类有哪些成员变量等信息。

640.png640.png

 

// Java用native方法实现 getClass()
public final native Class<?> getClass();
// Android 特殊的实现方式
private transient Class<?> shadow$_klass_;
public final Class<?> getClass() {
    return shadow$_klass_;
}

 

Java默认的Hotspot虚拟机并没有开辟单独的Method Area空间,而是有GC Heap的老生代的Metaspace实现的。而Android采用ART VM,这才造成了这种差异。大黄:这是因为是

 

finalize()




finalize()方法,是Objectprotected方法,在发生GC时触发该方法。

该方法的大致流程,是当对象变成GC Roots不可达时,GC判断该对象是否覆盖了finalize()方法,若未覆盖,则直接将其回收;否则,若对象未执行过finalize()方法,将其放入F-Queue队列,由一低优先级线程执行该队列中对象的finalize()方法。

执行finalize()方法完毕后,GC会再次判断该对象是否可达,若不可达,则进行回收;否则,对象复活

子类可以override该方法,用于防止对象被回收,亦或是防止对象不被回收。

要防止对象被回收,只需让该对象与GC ROOTS之间存在可达链即可。

我们重点看看FileInputStreamFileOutputStreamConnection等类怎么防止用户忘记释放资源吧,如下是FileInputStream的部分源码:

 

protected void finalize() throws IOException {
    // Android新增 CloseGuard确保FlieInputStream回收更安全
    if (guard != null) {
        guard.warnIfOpen();
    }
    //Java利用 FileDescriptor确保FileInputStream不可达,可以被安全回收
    if ((fd != null) &&  (fd != FileDescriptor.in)) {
        close();
    }
}


toString()




toString()方法,恐怕是大家最常用的方法了,该方法返回该对象的String表示。

640.png

 640.png


举个例子,IntegertoString()方法,就针对Android做了一定适配:

 

public String toString() {
    return toString(this.value);
  }
  //返回指定十进制整数的 String
  public static String toString(int i) {
    if (i == Integer.MIN_VALUE)
        return "-2147483648";
    // small是 Android特有的变量,用二维Array缓存较小(两位数)数字的 String
    boolean negative = i < 0;
    boolean small = negative ? i > -100 : i < 100;
    if (small) {
        final String[] smallValues = negative ?
SMALL_NEG_VALUES : SMALL_NONNEG_VALUES;
        if (negative) {
            i = -i;
            if (smallValues[i] == null) {
                smallValues[i] =
                    i < 10 ?
new String(new char[]{'-', DigitOnes[i]}):
new String(new char[]{'-', DigitTens[i], DigitOnes[i]});
            }
        } else {
            if (smallValues[i] == null) {
                smallValues[i] =
                    i < 10 ?
new String(new char[]{DigitOnes[i]}):
new String(new char[]{DigitTens[i], DigitOnes[i]});
            }
        }
        return smallValues[i];
    }
    int size = negative ? stringSize(-i) + 1 :
stringSize(i);
    // getChars()方法略
    char[] buf = new char[size];
    getChars(i, size, buf);
    return new String(buf);
}

equals() 和 hashcode()


640.png640.png640.png

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

640.png

想要比较值是否相同,该怎么办呢?需要重写equals()。

重写equals(),要注意以下几点注意事项:

 

1)对任意xx.equals(x)一定返回true

2)对任意xy,如果x.equals(y)返回true,则y.equals(x)也一定返回true

3)对任意xyz,如果x.equals(y)返回truey.equals(z)也返回true,则x.equals(z)也一定返回true

4)对任意xy,如果对象中用于比较的信息没有改变,那么无论调用多少次x.equals(y),返回的结果应该保持一致,要么一直返回true,要么一直返回false

5)对任意不是nullxx.equals(null)一定返回false

640.png640.png

 

下面,我们先看一下String类是如何实现equals方法的:

//比较这个String和另一个对象,当且仅当那个对象不为null,且与这个String有相同的字符排列顺序时返回true
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = length();
        if (n == anotherString.length()) {
            int i = 0;
            while (n-- != 0) {
                if (charAt(i) != anotherString.charAt(i))
                   return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

 

接下来,我们再看一下String类是如何实现hashcode方法的:

//缓存String的hashcode()
private int hash; // 默认为0
public int hashCode() {
    int h = hash;
    final int len = length();
    if (h == 0 && len > 0) {
        for (int i = 0; i < len; i++) {
            h = 31 * h + charAt(i);
        }
        hash = h;
    }
    return h;
}


如果两个对象的hashCode返回值相同,但它们的equals()方法却有可能最终返回false,这种情况叫做hash碰撞。 

熟悉HashMap底层原理的朋友,对这个概念一定不会陌生。

640.png640.png

相关文章
|
10天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
49 4
|
1月前
|
Java
Java Object 类详解
在 Java 中,`Object` 类是所有类的根类,每个 Java 类都直接或间接继承自 `Object`。作为所有类的超类,`Object` 定义了若干基本方法,如 `equals`、`hashCode`、`toString` 等,这些方法在所有对象中均可使用。通过重写这些方法,可以实现基于内容的比较、生成有意义的字符串表示以及确保哈希码的一致性。此外,`Object` 还提供了 `clone`、`getClass`、`notify`、`notifyAll` 和 `wait` 等方法,支持对象克隆、反射机制及线程同步。理解和重写这些方法有助于提升 Java 代码的可读性和可维护性。
|
3月前
|
Java
【Java基础面试二十】、介绍一下Object类中的方法
这篇文章介绍了Java中Object类的常用方法,包括`getClass()`、`equals()`、`hashCode()`、`toString()`、`wait()`、`notify()`、`notifyAll()`和`clone()`,并提到了不推荐使用的`finalize()`方法。
【Java基础面试二十】、介绍一下Object类中的方法
|
2月前
|
Python
类与面向对象编程(Object-Oriented Programming, OOP)
类与面向对象编程(Object-Oriented Programming, OOP)
|
3月前
|
前端开发 Java 编译器
【前端学java】java中的Object类和前端中的Object有什么区别(9)
【8月更文挑战第10天】java中的Object类和前端中的Object有什么区别
43 0
【前端学java】java中的Object类和前端中的Object有什么区别(9)
|
3月前
|
算法 Java
12 Java常用类(一)(内部类+object类+包装类)
12 Java常用类(一)(内部类+object类+包装类)
37 5
|
4月前
|
Java
Java中的Object类 ( 详解toString方法 | equals方法 )
Java中的Object类 ( 详解toString方法 | equals方法 )
|
5月前
|
Java
【Java】Object类简单解析
【Java】Object类简单解析
63 1
|
5月前
|
前端开发 JavaScript Java
Java基础10-深入理解Class类和Object类(二)
Java基础10-深入理解Class类和Object类(二)
48 5
|
5月前
|
Java C++
Java基础10-深入理解Class类和Object类(一)
Java基础10-深入理解Class类和Object类(一)
72 4