1、protected Object clone()克隆对象
深克隆和浅克隆,感兴趣就了解
2、int hasCode()返回对象的哈希值
不是抽象方法,有native关键字,底层调用C++程序
hashCode()方法返回的是哈希玛:实际上就是一个java对象的内存地址,经过哈希算法,得出的一个值
public native int hashCode();
package com.object.one;
public class ObjectTest01 {
public static void main(String[] args) {
Person p = new Person();
Person p2 = new Person();
System.out.println(p.hashCode());//23934342
System.out.println(p2.hashCode());//22307196
}
}
class Person {
}
3、boolean equals(Object obj)判断两个对象是否相等
源码为:
public boolean equals(Object obj) { return (this == obj);}
举例:
package com.object.two;
public class MyTime {
private int year;
private int month;
private int day;
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public MyTime(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public MyTime() {}
//默认equals方法
/*public boolean equals(Object obj) { return (this == obj);}
* Object的equals方法中用==比较对象的引用*/
//重写equals
@Override
public boolean equals(Object o) {
//如果内存地址相同,则指向堆内存的对象是同一个
if (this == o) return true;
//如果o为空或者(o instanceof MyTime)为false,大概就是这个引用必须这个类的引用
if (o == null || getClass() != o.getClass()) return false;
//排除上述三种情况,就可以直接进行强转
MyTime myTime = (MyTime) o;
return year == myTime.year && month == myTime.month && day == myTime.day;
}
}
package com.object.one;
import com.object.two.MyTime;
public class ObjectTest01 {
public static void main(String[] args) {
MyTime m = new MyTime(2001,3,5);//0x11
MyTime n = new MyTime(2001,3,5);//0x22
System.out.println(n == m);//false,它比较的是对象的引用
System.out.println(n.equals(m));//true,重写equals后
}
}
String类重写的toString()和equals()
package com.object.one;
public class ObjectTest01 {
public static void main(String[] args) {
//大部分情况下这样创建字符串对象
String s1 = "abd";
String s2 = "a";
//但还可以这样
String s3 = new String("jie");
String s4 = new String("jie");
System.out.println(s3 == s4);//false,不能用==来比较字符串
System.out.println(s3.equals(s4));//true,String其实也是一个类
System.out.println(s3);//jie
System.out.println(s3.toString());//jie
}
}
引用数据类型用equals()方法,基本数据类型用==。以后写的类最好都重写equals(),因为默认的equals()比较的是引用,但大部分我们比较的是内容
再看一个例子:重写equals要彻底
package com.object.one;
import java.util.Objects;
public class ObjectTest01 {
public static void main(String[] args) {
User u1 =new User("zhangsang",new Address("北京","hunan"));
User u2 =new User("zhangsang",new Address("北京","hunan"));
System.out.println(u1.equals(u2));
//Address没重写equals时是false,Address重写equals后是true
}
}
class User {
String name;
Address address;
public User(String name, Address address) {
this.name = name;
this.address = address;
}
//当名字和address相同时表示同一个用户
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(name, user.name) && Objects.equals(address, user.address);
}
}
class Address {
String city;
String street;
public Address() {}
public Address(String city, String street) {
this.city = city;
this.street = street;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Address address = (Address) o;
return Objects.equals(city, address.city) && Objects.equals(street, address.street);
}
}
4、String toString()
将对象转换为字符串的形式
Object类的toString方法返回一个字符串,其中包含对象实例所属类的名称、符号' @'和对象哈希码的无符号十六进制表示。换句话说,这个方法返回的字符串等于的值 ,“以文本的方式”表示这个对象,
建议所有子类都去重写toString方法,toString方法应该是一个简洁的、详实的、易阅读的,其源码为:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
package com.object.two;
public class MyTime {
private int year;
private int month;
private int day;
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public MyTime(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public MyTime() {}
//重写toString
@Override
public String toString() {
return year +
"年" + month +
"月" + day +
"日";
}
}
package com.object.one;
import com.object.two.MyTime;
public class ObjectTest01 {
public static void main(String[] args) {
MyTime m = new MyTime(2001,3,5);
// System.out.println(m.toString());
// 未重写toString结果:com.object.two.MyTime@16d3586
System.out.println(m);//输出引用时,会自动调用toString()方法
}
}
5、protected void finalize()垃圾回收器负责调用的方法
这个方法不需要程序员手动调用,JVM的垃圾回收器负责调用这个方法。GC会自动调用这个方法,了解即可,其源码为:
protected void finalize() throws Throwable
package com.object.one;
public class ObjectTest01 {
public static void main(String[] args) {
Person p = new Person();
p = null;
//垃圾回收器不会轻易启动,垃圾太少或者时间太短可能不会启动
System.gc();//这是我们建议启动gc,但也不一定
}
}
//项目开发中可能有这样的业务:所有对象在JVM中被释放的时候,请记录一下释放时间
//这个记录时间的代码就会写在finalize()中
class Person {
@Override
protected void finalize() throws Throwable {
System.out.println("即将被销毁!");
}
}
Object类是所有java类的根基类,如果在类的声明中未使用extends关键字指明其基类,则默认基类为Object类