java.lang.Object类 方法(转)

本文深入解析Java中Object类的核心方法,包括构造方法、equals、hashCode、toString等,并探讨这些方法的作用及其实现细节。
Object类的方法



构造方法:public Object()
在Object的源代码中并没有Object的构造方法,而是采用了java内置的默认构造方法。即在编译时由编译器完成这项工作。

值得注意的是在Object源码的开始,有这样一段:



private static native void registerNatives();

static {

registerNatives();

}



使用JNI特性(有其他语言实现这个功能)来做的这样一个方法,这个方法由Java虚拟机在创造对象时调用,其功能是初始化一个对象:分配内存空间,定义变量,产生this指针等等。



紧接着下面的静态代码块(当该类被实例化、继承、构造方法调用时都优先执行该代码块):也就是说,java中所有代码执行前都要执行这一个JNI实现的方法。



public final native Class<?> getClass();
native方法,返回当前对象的运行时类。(运行时类是指在程序运行时所确定的类型)

public native int hashCode();
native方法,返回对象的hash码值,支持此方法是为了提供hash表的性能。

这里需要特别注意:

在object类中,一般情况下不同的实例对象调用hashCode方法返回不用的哈希码值,但当对象数量太多时就会出现重复。所以不建议使用比较哈希码值的方法来判断实例对象是否同一。



public boolean equals(Object obj)
源码如下:

public boolean equals(Object obj) {

return (this == obj);

}

可以发现,此处使用了关系运算符"=="所判断的是实例对象而不是实例对象的取值.这里我们不难推测关系运算符判断引用数据类型都是从实例对象出发的。

其实就是,Object中的equals方法等价于”==”操作。当继承类复写了equals方法时才会有equal()与”==”不等的说法。

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

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

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

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

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

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

  并且覆写equals()方法时,应该同时覆写hashCode()方法,反之亦然。





protected native Object clone() throws CloneNotSupportedException
native方法,创建并且返回该对象的一个副本。要调用这个方法必须实现cloneable接口。该方法的注释有这样一个描述:

x.clone() != x

x.clone().getClass() == x.getClass()

x.clone().equals(x)

都为真



notify()方法
方法申明如下:

public final native void notify ();

唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。

notifyAll()方法
方法申明:

public final native void notifyAll();

唤醒在此对象监视器上等待的所有线程。线程通过调用其中一个wait 方法,在对象的监视器上等待。





wait(long timeout)方法
源码:

public final native void wait(long timeout) throws InterruptedException;

在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。

也就是说wait方法要在其他线程调用对象的 notify方法或notifyAll方法或超过指定的时间量前调用才有意义。



9. String toString()方法

源码如下:

public String toString() {

return getClass().getName() + "@" + Integer.toHexString(hashCode());

}

返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。



10. protected void finalize() throws Throwable

源码:



注释说的是:当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类重写 finalize 方法,以配置系统资源或执行其他清除。

也就是说:

子类如果想在释放该对象的同时释放掉其他对象的话就重写该方法,但要注意如释放的对象仍然有引用的话容易出现错误,抛出异常
你遇到的这个错误: ``` 对于thenReturn(java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.String>>), 找不到合适的方法 方法 org.mockito.stubbing.OngoingStubbing.thenReturn(java.util.Map<java.lang.String,java.lang.Object>)不适用 (参数不匹配; java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.String>>无法换为java.util.Map<java.lang.String,java.lang.Object>) ``` 是 **Java 泛型型不匹配** 导致的。 --- ### ❓ 问题原因 你写的代码大概是这样的: ```java PowerMockito.when(AsyncUtils.parallelExecute(Mockito.anyMap(), Mockito.anyInt())) .thenReturn(amountsMap); ``` 而你的 `amountsMap` 是: ```java Map<String, Map<String, String>> amountsMap = new HashMap<>(); ``` 但 Mockito 的 `thenReturn(...)` 方法期望的返回型是: ```java Map<String, Object> ``` 所以你传入的 `Map<String, Map<String, String>>` 被认为是 **不兼容** 的。 --- ### ✅ 解决方案 1:使用 `thenAnswer` 替代 `thenReturn` 你可以使用 `thenAnswer()` 方法来绕过泛型限制,直接返回你需要的型。 ```java PowerMockito.when(AsyncUtils.parallelExecute(Mockito.anyMap(), Mockito.anyInt())) .thenAnswer(invocation -> amountsMap); ``` ✅ 这是最推荐的解决方案,适用于所有复杂泛型返回值的情况。 --- ### ✅ 解决方案 2:强制换(不推荐) 你也可以将 `amountsMap` 强为 `Map<String, Object>`: ```java PowerMockito.when(AsyncUtils.parallelExecute(Mockito.anyMap(), Mockito.anyInt())) .thenReturn((Map<String, Object>) (Object) amountsMap); ``` ⚠️ 这种方式虽然能编译通过,但会失去型安全性,不推荐使用。 --- ### ✅ 解决方案 3:重新定义泛型(更安全) 如果你能控制 `parallelExecute` 的返回型,可以考虑使用更泛化的返回型,例如: ```java Map<String, ? extends Object> parallelExecute(...); ``` 这样 Mockito 就不会报错了。 --- ### ✅ 示例完整代码 ```java Map<String, Map<String, String>> amountsMap = new HashMap<>(); Map<String, String> data = new HashMap<>(); data.put("user123", "90"); data.put("user456", "80"); amountsMap.put("100", data); PowerMockito.mockStatic(AsyncUtils.class); PowerMockito.when(AsyncUtils.parallelExecute(Mockito.anyMap(), Mockito.anyInt())) .thenAnswer(invocation -> amountsMap); // ✅ 使用 thenAnswer ``` --- ### ✅ 为什么 `thenAnswer` 有效? - `thenAnswer` 接受一个 `Answer` 接口,返回值型是泛型的 `V`,由你决定返回什么。 - 它不会进行严格的泛型检查,而是运行时决定型。 - 所以它可以绕过 Mockito 的泛型限制。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值