Java SEObject类
CAMELLIA!!! note 目录
Object类
一、Object类
在Java中,Object
类是所有类的根类。也就是说,所有的类都是直接或间接地继承自 Object
类。
Object
类定义了一些所有对象都共享的方法,这些方法可以在任何类的对象上调用。
下面是一些 Object
类中常用的方法:
equals(Object obj)
: 用于比较两个对象是否相等。默认情况下,equals()
方法比较的是对象的引用是否相同,但是可以在子类中重写该方法来定义自定义的相等性比较逻辑。
hashCode()
: 返回对象的哈希码值。这个方法通常与 equals()
方法一起使用,确保相等的对象具有相同的哈希码。
toString()
: 返回对象的字符串表示。默认情况下,toString()
方法返回一个由类名和对象的哈希码组成的字符串。
getClass()
: 返回对象的运行时类的引用,即 Class
对象。
clone()
: 用于创建并返回一个对象的副本。要实现对象的克隆,需要在子类中实现 Cloneable
接口,并重写 clone()
方法。
finalize()
: 在垃圾收集器删除对象之前调用。可以在子类中重写该方法以执行资源清理等操作。
notify()
, notifyAll()
, wait()
: 这些方法是用于多线程编程的,用于线程之间的通信和同步。
getClassLoader()
: 返回对象的类加载器。
二、toString方法
2.1、Object类中的toString()方法。
对Object类中的toString不满意可以重写。
当println()输出的是一个引用的时候,会自动调用 “引用.toString()”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public void println(Object x) { String s = String.valueOf(x); if (getClass() == PrintStream.class) { writeln(String.valueOf(s)); } else { synchronized (this) { print(s); newLine(); } } }
public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); }
|
1 2 3 4 5 6 7 8 9 10
| public class Test { public static void main(String[] args) { Car car = new Car(); car=null; System.out.println(car); System.out.println(car.toString()); } }
|
三、equals方法
3.1、Object类中的equals方法
Java中的equals()方法用于比较两个对象的内容是否相等。
在Object类中,equals()方法的默认实现是比较两个对象的引用是否相等(即是否指向同一块内存地址),这相当于使用==运算符进行比较。
1 2 3 4
| public boolean equals(Object obj) { return (this == obj); }
|
3.2 ==运算符
==运算规则:比较两个变量中保存的值是否相等。
1 2 3 4 5 6 7 8 9 10 11
| class Test { public static void main(String[] args) { int a = 10; int b = 10; System.out.println(a == b); Object object1 = new Object(); Object object2 = new Object(); System.out.println(object1 == object2); } }
|
因为equal对于对象而言比较的是地址,即引用变量存储的值。但大多数我们想比较的是内容,所以要重写equals。
此外重写要彻底,因为你的一个对象比较可能涉及多个类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
@Override public boolean equals(Object obj) { if(obj == null) return false;
if(this == obj) return true;
if(obj instanceof Date){ Date d = (Date) obj; return this.year == d.year && this.month == d.month && this.day == d.day; }
return false; }
|
四、hashCode方法(入门)
关于Object类的hashCode()方法:
- hashCode:返回一个对象的哈希值,通常作为在哈希表中查找该对象的键值。
- Object类的默认实现是根据对象的内存地址生成一个哈希码(即将对象的内存地址转换为整数作为哈希值)。
- hashCode()方法是为了HashMap、Hashtable、HashSet等集合类进行优化而设置的,以便更快地查找和存储对象
- hashCode()方法在Object类中的默认实现:
- public native int hashCode();
- 这是一个本地方法,底层调用了C++写的动态链接库程序:xxx.dll
五、finalize方法(已过时,作为了解)
finalize:当java对象被回收时,由GC自动调用被回收对象的finalize方法,通常在该方法中完成销毁前的准备。从Java9开始,这个方法被标记已过时,不建议使用。作为了解。
- 可以在finalize中进行关闭连接操作。
1 2
| protected void finalize() throws Throwable { }
|
1 2 3 4 5 6 7 8
| public class Person{
@Override protected void finalize() throws Throwable { System.out.println(this + "即将被回收"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Test3 {
public static void main(String[] args) { for (int i = 0; i < 10000; i++) { Person p1 = new Person(); p1 = null;
if(i % 1000 == 0){ System.gc(); } } } }
|
六、clone方法
在 Object
类中,clone()
方法被声明为 protected
。它的签名如下:
1
| protected native Object clone() throws CloneNotSupportedException;
|
clone()
方法允许创建并返回一个对象的副本。但是,需要注意以下几点:
clone()
方法在默认情况下是 protected
的,这意味着只有类本身或其子类可以调用这个方法。因此,如果你希望在类外部调用 clone()
方法,必须在类中重新定义这个方法并将其设置为 public
。
- 调用
clone()
方法时,被克隆的类必须实现 Cloneable
接口。否则,将会抛出 CloneNotSupportedException
异常。
clone()
方法的实现通常由 native
关键字修饰,这表示它的实现是由底层的本地代码完成的。这使得 clone()
方法能够访问对象的内部状态,从而创建对象的精确副本。
使用 clone()
方法需要谨慎,因为它是浅拷贝,即它只复制了对象本身以及其引用的内部数据结构。如果对象包含其他对象的引用,那么这些引用仍然指向相同的内存地址。在这种情况下,你可能需要实现深拷贝来确保所有对象及其引用的对象都被正确复制。
6.1、浅克隆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package com.camellia.object2;
public class User implements Cloneable{ private int age;
public User() { }
public User(int age) { this.age = age; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override public String toString() { return "User{" + "age=" + age + '}'; }
@Override public Object clone() throws CloneNotSupportedException { return super.clone(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class UserTest { public static void main(String[] args) throws CloneNotSupportedException { User user = new User(20); System.out.println(user);
Object obj = user.clone(); System.out.println(user);
User copyUser = (User) obj; copyUser.setAge(100); System.out.println("克隆之后的新对象的年龄:" + copyUser.getAge());
System.out.println("原始对象的年龄:" + user.getAge()); UserTest userTest = new UserTest(); userTest.clone();
} }
|
6.2、深克隆
深克隆解决的问题是在复制对象时,确保对象及其所有引用的对象都被完全复制,而不仅仅是复制了对象本身。
通常,当我们进行对象的复制时,如果对象包含了其他对象的引用,浅复制只是复制引用而不是复制引用的对象本身,
这样就会导致新对象和原对象共享相同的引用对象,一旦其中一个对象修改了共享的引用对象,另一个对象也会受到影响,这可能会导致意外的行为或错误的结果。
6.2.1、浅克隆问题举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package com.camellia.object2;
public class Address implements Cloneable{ private String city; private String street;
@Override public String toString() { return "Address{" + "city='" + city + '\'' + ", street='" + street + '\'' + '}'; }
public Address() { }
public Address(String city, String street) { this.city = city; this.street = street; }
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
public String getStreet() { return street; }
public void setStreet(String street) { this.street = street; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package com.powernode.javase.oop41;
public class User implements Cloneable{ private String name; private Address addr;
public User() { }
public User(String name, Address addr) { this.name = name; this.addr = addr; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Address getAddr() { return addr; }
public void setAddr(Address addr) { this.addr = addr; }
@Override public String toString() { return "User{" + "name='" + name + '\'' + ", addr=" + addr + '}'; }
@Override public Object clone() throws CloneNotSupportedException { return super.clone(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.powernode.javase.oop41;
public class Test { public static void main(String[] args) throws CloneNotSupportedException {
Address a = new Address("北京", "海淀"); User user1 = new User("李四", a);
User user2 = (User)user1.clone();
System.out.println(user1); System.out.println(user2);
user2.getAddr().setCity("天津"); System.out.println("===================================");
System.out.println(user1); System.out.println(user2); } }
|
6.2.2、深克隆举例
1 2 3 4 5 6 7 8 9 10 11
| @Override public Object clone() throws CloneNotSupportedException { Address copyAddr = (Address)this.getAddr().clone();
User copyUser = (User)super.clone(); copyUser.setAddr(copyAddr); return copyUser; }
|
1 2 3 4 5 6
| @Override public Object clone() throws CloneNotSupportedException { return super.clone(); }
|