简述 :
Object类是所有java类的根基类,也就意味着所有的java对象都拥有Object类的属性和方法。如果在类的声明中未使用extends关键子指明其父类,则默认继承Object类。
以下两种类的定义的最终效果完全相同
class Person { }
class Person extends Object { }
构造方法:
可以直接实例化
Object()
//Object obj = new Object();
成员方法:
protected Object clone()创建并返回此对象的副本。
boolean equals(Object obj)指示一些其他对象是否等于此。
protected void finalize()当垃圾收集确定不再有对该对象的引用时,垃圾收集器在对象上调用该对象。
类<?> getClass()返回此 Object的运行时类。
int hashCode()返回对象的哈希码值。
void notify()唤醒正在等待对象监视器的单个线程。
void notifyAll()唤醒正在等待对象监视器的所有线程。
String toString()返回对象的字符串表示形式。
void wait()导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。
void wait(long timeout)导致当前线程等待,直到另一个线程调用 notify()方法或该对象的 notifyAll()方法,或者指定的时间已过。
void wait(long timeout, int nanos)导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法,或者某些其他线程中断当前线程,或一定量的实时时间。
方法的作用 :
1. clone()
保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。
2. getClass()
final方法,返回Class类型的对象,反射来获取对象。
3. toString()
该方法用得比较多,一般子类都有覆盖,来获取对象的信息。
4. finalize()
该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。
5. equals()
比较对象的内容是否相等
6. hashCode()
该方法用于哈希查找,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。
7. wait()
wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生。
其他线程调用了该对象的notify方法。
其他线程调用了该对象的notifyAll方法。
其他线程调用了interrupt中断该线程。
时间间隔到了。
此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。8. notify()
该方法唤醒在该对象上等待的某个线程。
9. notifyAll()
该方法唤醒在该对象上等待的所有线程。
常用的成员方法
String toString();
返回对象的字符串表示形式。
//在打印的时候调用方法
官方:
返回对象的字符串表示形式。 一般来说, `toString`方法返回一个“textually代表”这个对象的字符串。 结果应该是一个简明扼要的表达,容易让人阅读。
建议所有子类覆盖此方法。
该`toString`类方法`Object`返回一个由其中的对象是一个实例,该符号字符`的类的名称的字符串`@` ”和对象的哈希码(内存地址)的无符号的十六进制表示。 换句话说,这个方法返回一个等于下列值的字符串:
getClass().getName() + '@' + Integer.toHexString(hashCode())
示例1:
class Person {
String name;
int age;
//person类是Object类子类所以可以重写Object类下的toString()方法
@Override
public String toString() {
System.out.println("123");
//原:
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
// return
// "name=\"" + name + '\"' +
// ", age=" + age
// ;
//返回值可以随意更改为字符串类型的其他形式
}
}
public class Demo1 {
public static void main(String[] args) {
Object obj = new Object();
System.out.println(obj);
Person person = new Person();
System.out.println(person);
//在执行sout()时默认调用Person类中重写过的的toString()方法
//未重写toString()方法时输出的是Object类下的toString()方法
//为:getClass().getName() + '@' + Integer.toHexString(hashCode())
}
}
tostring方法总结:
toString 方法返回一个“textually代表”这个对象的字符串。 结果应该是一个简明扼要的表达,容易让人阅读。
建议所有子类覆盖此方法。
boolean equals(Object object);
public boolean equals(Object obj) {
return (this == obj);
}------------
官方:
- 指示一些其他对象是否等于此。
equals
方法在非空对象引用上实现等价关系:
- 自反性 :对于任何非空的参考值
x
,x.equals(x)
应该返回true
。- 它是对称的 :对于任何非空引用值
x
和y
,x.equals(y)
应该返回true
当且仅当y.equals(x)
回报true
。- 传递性 :对于任何非空引用值
x
,y
和z
,如果x.equals(y)
回报true
个y.equals(z)
回报true
,然后x.equals(z)
应该返回true
。- 它是一致的 :对于任何非空引用值
x
和y
,多次调用x.equals(y)
始终返回true
或始终返回false
,没有设置中使用的信息equals
比较上的对象被修改。- 对于任何非空的参考值
x
,x.equals(null)
应该返回false
。该
equals
类方法Object
实现对象上差别可能性最大的相等关系; 也就是说,对于任何非空的参考值x
和y
,当且仅当x
和y
引用相同的对象(x == y
具有值true
)时,该方法返回true
。请注意,无论何时覆盖该方法,通常需要覆盖
hashCode
方法,以便维护hashCode
方法的通用合同,该方法规定相等的对象必须具有相等的哈希码。
示例1:
import java.util.Objects;
class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
//返回值可以随意更改为字符串类型的其他形式
}
//重写equals方法,要求比较内容,内容一样则返回true
//person1.equals(person2)
//person2赋值给了o Object o = new Person();
//new Person() 此时 ==》person2 此为向上转型
@Override
public boolean equals(Object o) {
if (this == o){ //先比较地址
return true;
}
//若地址不一样,再比较内容
if (o instanceof Person){
//若,才去比较内容
Person person = (Person) o; //向下转型
return person.age == this.age && person.name.equals(this.name);
}
return false;
// if (o == null || getClass() != o.getClass()){
// return false;
// }
// Person person = (Person) o;
// return age == person.age && name.equals(person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
//可以返回其他十进制的值
}
}
public class Demo01_Object_method {
public static void main(String[] args) {
Object obj = new Object();
Person person1 = new Person("流子",25);
Person person2 = new Person("流子",25);
System.out.println(person1);
System.out.println(person2);
//重写Object类equals()方法前
//System.out.println(person1.equals(person2));//false 比较的是地址
//重写Object类equals()方法后
System.out.println("两个对象的内容是否相等?:" + person1.equals(person2)); //true
System.out.println();
//被重写过的hashCode()方法 根据合同,如果内容一样,哈希值也要一样
System.out.println(person1.hashCode());
System.out.println(person2.hashCode());
}
}
equals方法总结:
比较是两个对象的地址,并不看内容
Srting类的equals方法就是重写了Object类中的equals方法,不仅比较地址也比较内容
当父类的需求,满足不了子类的需求的时候要重写父类的方法
int hashCode()
返回对象的哈希码值。 //支持这种方法是为了散列表,如[`HashMap`]提供的[那样]
哈希码值: 在Object类下面,将内存地址(十六进制的值)转为十进制的的值,此时这个十进制的值就是该对象的哈希码值
----------
官方:
hashCode
的总合同是:
- 只要在执行Java应用程序时多次在同一个对象上调用该方法,
hashCode
方法必须始终返回相同的整数,前提是修改了对象中equals
比较中的信息。 该整数不需要从一个应用程序的执行到相同应用程序的另一个执行保持一致。- 如果根据
equals(Object)
方法两个对象相等,则在两个对象中的每个对象上调用hashCode
方法必须产生相同的整数结果。- 不要求如果两个对象根据
equals(java.lang.Object)
方法不相等,那么在两个对象中的每个对象上调用hashCode
方法必须产生不同的整数结果。 但是,程序员应该意识到,为不等对象生成不同的整数结果可能会提高哈希表的性能。尽可能多的合理实用,由类别
Object
定义的hashCode方法确实为不同对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但Java的编程语言不需要此实现技术。)结果
该对象的哈希码值。
示例1:
public class Demo4 {
public static void main(String[] args) {
String str = new String("a");
String str1 = new String("b");
String str2 = new String("a");
//Object类的hash值是内存地址十进制的转换
//只要内存地址不一样,hash值一定不一样
//但是str和str2 ,内存地址不一样,但是
//hash值是一样的
//原因是因为在String类中重写了hashCode方法
System.out.println(str.hashCode());//97
System.out.println(str1.hashCode());//98
System.out.println(str2.hashCode());//97
}
}
示例2:
class Dog {
int id;
String name;
public Dog(int id, String name) {
this.id = id;
this.name = name;
}
public boolean equals (Object o) {
if (this == o) {
return true;
}
if (o instanceof Dog) {
Dog dog = (Dog)o;
return this.id == dog.id && dog.name.equals(this.name);
}
return false;
}
@Override
public int hashCode() {
return name.hashCode() + id;
}
}
public class Demo5 {
public static void main(String[] args) {
Dog dog1 = new Dog( 3, "a");
Dog dog2 = new Dog( 2, "b");
System.out.println(dog1.equals(dog2));//true
System.out.println(dog1.hashCode());
System.out.println(dog2.hashCode());
//现在hashCode不一样 重写hashCode即可
//如果根据equals(Object)方法两个对象相等,
//则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。
//如果两个对象的hash值一样,对象是不一定一样的。
//但是如果两个对象相等
//那么hash值一定相等
}
}
示例3:
class Panda {
int id;
String name;
public Panda(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Panda panda = (Panda) o;
return id == panda.id && Objects.equals(name, panda.name);
}
@Override
public int hashCode() {
return id;
}
}
public class Demo6 {
public static void main(String[] args) {
String str1 = new String("ab");
String str2 = new String("a");
System.out.println(str1.equals(str2));//true
//31 * 97+ 98
System.out.println(str1.hashCode());//3105
System.out.println(str2.hashCode());
//STring类下面的hashCode重写的Object类下面的
Integer i1 = new Integer(45);
Integer i2 = new Integer(45);
System.out.println(i1 == i2);//false
System.out.println(i1.equals(i2));//true
System.out.println(i1.hashCode());
System.out.println(i2.hashCode());
Panda panda1 = new Panda(67, "黄天霸");
Panda panda2 = new Panda(67, "黄天霸");
System.out.println(panda2.equals(panda1));
System.out.println(panda1.hashCode());
System.out.println(panda2.hashCode());
}
}
hashCode总结:
哈希值一样,对象内容不一定一样
若两个对象内容一样,则哈希值 必须 一样重写equals方法,通常需要重写
hashCode
方法该方法规定相等的对象必须具有相等的哈希码