JDK类库的根类:Object
1)、任何一个类默认继承Object,就是没有直接继承,最后也会间接继承
2)、Object中有哪些常用的方法?去哪儿找?
-第一种方法:去源代码当中(但是这种方法比较麻烦,源代码也比较难)
-第二种方法:去查阅Java的类库帮助文档。
什么是API?
应用程序编程接口(Application Program Interface)
整个JDK的类库就是一个javase的API。每个API都会配置一套API帮助文档。
3)、目前我们需要知道:
-
protected Object clone()//负责对象克隆
不常用。 分为深克隆与浅克隆。
-
int hashCode()//获取对象哈希值
(1) 源代码
public native int hashCode();
这个方法不是抽象方法,带有native关键字,底层调用C++程序。
(2) hashCode()方法返回的是哈希码:
实际上就是一个Java对象的内存地址,经过哈希算法,得出的一个值。所以hashCode()方法的执行结果可以等同看做一个Java对象的内存地址。
示例:
package java核心技术;
public class HashCodeTest01 {
public static void main(String [] args) {
Object obj = new Object();
int hashCodeValue = obj.hashCode();
System.out.println(hashCodeValue);//366712642
}
}
-
boolean equals (Object obj)//判断两个对象是否相等
(1) 源代码
public boolean equals(Object obj){
return (this == obj);
}
以上这个方法是Object类的默认实现。(2) SUN公司设计equals方法的目的
通过此方法判断两个对象是否相等(3) 判断两个Java对象是否相等不能用“”,因为“”比较的是两个对象的内存地址。
(4)Object类给的equals方法够不够用?
在Object类中的equals方法当中,默认采用的是“”判断两个对象是否相等。而“”判断的是两个Java对象的内存地址,我们应该判断两个对象的内容是否相等。所以需要在子类中重写方法。(5) Java中基本数据类型比较是否相等,使用“==”
Java中所有的引用数据类型统一使用equals方法来判断是否相等。
例1 :
package java核心技术;
public class EqualsTest01 {
public static void main(String [] args) {
MyTime1 t1 = new MyTime1(2000, 1, 2);
MyTime1 t2 = new MyTime1(2000, 1, 2);
MyTime1 t3 = new MyTime1(2008, 1, 3);
System.out.println(t1 == t2);//运行结果:false
/*
//equals方法重写前
boolean b = t1.equals(t2);
System.out.println(b);//运行结果:false
*/
//equals方法重写后调用
System.out.println(t1.equals(t2));//运行结果:true
System.out.println(t1.equals(t3));//运行结果:false
}
}
class MyTime1{
int year;
int month;
int day;
public MyTime1() {
}
public MyTime1(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
/*
//重写equals方法
public boolean equals(Object obj) {
int year1 = this.year;
int month1 = this.month;
int day1 = this.day;
if(obj instanceof MyTime1) {
MyTime1 t = (MyTime1) obj;
int year2 = t.year;
int month2 = t.month;
int day2 = t.day;
if(year1 == year2 && month1 == month2 && day1 == day2)
return true;
}
return false;
}*/
//以上方法执行效率低,对equals方法重新进行改良
public boolean equals(Object obj) {
if(obj == null || !(obj instanceof MyTime1)) {
return false;
}
if(obj == this) {
return true;
}
MyTime1 t = (MyTime1) obj;
return this.year == t.year &&
this.month == t.month &&
this.day == t.day;
}
}
例2:
package java核心技术;
public class EqualsTest02 {
public static void main(String [] args) {
Address addr1 = new Address("湖南", "长沙", "111");
Address addr2 = new Address("湖南", "长沙", "111");
User01 u1 = new User01("zhangsan", addr1);
User01 u2 = new User01("zhangsan", addr2);
System.out.println(u1.equals(u2));
}
}
class User01{
String name;
Address addr;
public User01() {
}
public User01(String name, Address addr) {
this.name = name;
this.addr = addr;
}
public boolean equals (Object obj) {
if(obj == null || !(obj instanceof User01))
return false;
if(obj == this)
return true;
User01 u = (User01)obj;
if(this.name.equals(u.name) && this.addr.equals(u.addr))
return true;
return false;
}
}
class Address{
String city;
String street;
String zipcode;
public Address() {
}
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
public boolean equals(Object obj) {
if(obj == null || !(obj instanceof Address))
return false;
if(obj == this)
return true;
Address a = (Address) obj;
if(this.city.equals(a.city) &&
this.street.equals(a.street) &&
this.zipcode.equals(a.zipcode))
return true;
return false;
}
}
-
protected void finalize()//垃圾回收器负责调用的方法
(1) 源代码:
protected void finalize()throws Throwable{ }
GC负责调用finalize()方法(2) finalize()方法只有一个方法体,里面没有代码,而且这个方法是protected修饰的。
(3) 这个方法不需要程序员手动调用,JVM的垃圾回收器负责调用这个方法。
(4) finalize()方法的执行时机:
当一个Java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize()方法。(5) finalize()方法实际上是SUN公司为Java程序员准备的一个时机,垃圾销毁时机。如果希望在对象销毁时机执行一段代码的话,这段代码要写到finalize()方法当中。
(6) 有一段代码可以建议启动垃圾回收器(只是建议,可能不启动可能启动,只是启动的概率变大)
System.gc();
示例:
package java核心技术;
public class FinalizeTest01 {
public static void main(String [] args) {
Person p = new Person();
//怎么把Person对象变成垃圾?
p = null;
//有一段代码可以建议垃圾回收期器启动
System.gc();
}
}
class Person{
//重写finalize方法
//Person类型的对象被垃圾回收器回收的时候,垃圾回收器负责调用:p.finalize();
protected void finalize () throws Throwable{
System.out.println("即将被销毁");
}
}
-
String toString()//将对象转换成字符串形式
(1) 源代码
public String toString(){
return this.getClass().getName() + “@” + Integer.toHexString(hashCode());
}
默认实现是:
类名@对象的内存地址转换为十六进制形式(2) SUN公司设计此方法的目的
通过调用这个方法可以将一个“Java对象”转换成“字符串”形式
(3) SUN公司建议所有的子类都去重新toString()方法。toString()方法应该是简洁的、详实的、易阅读的。
注:String类已经重写了equals方法和toString方法。
例:
package java核心技术;
public class ObjectInString {
public static void main(String [] args) {
//大部分情况下采用这样的方式创建字符串对象
String s1 = "Tea";
String s2 = "Tea";
//实际上String也是一个类,不属于基本数据类型
String s3 = new String("Test1");
String s4 = new String("Test1");
//s3、s4保存的是内存地址
System.out.println(s3 == s4);//运行结果:false
//调用String中重写的equals方法
System.out.println(s3.equals(s4));//运行结果:true
//调用String中重写的toString方法
System.out.println(s3);//运行结果:Test1
}
}
例:【调用类中自己重写的toString 方法】
package java核心技术;
public class ToStringTest01 {
public static void main(String [] args) {
MyTime t1 = new MyTime(1999, 1, 1);
/*
//不重写toString方法,直接调用
String s1 = t1.toString();
System.out.println(s1);//运行结果:java核心技术.MyTime@15db9742
*/
//调用重写后的toString方法
String s1 = t1.toString();
System.out.println(s1);//运行结果:1999年1月1日
System.out.println(t1);//运行结果:1999年1月1日
System.out.println(t1.toString());//运行结果:1999年1月1日
}
}
class MyTime{
int year;
int month;
int day;
public MyTime() {
}
public MyTime(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
//重写toString方法
public String toString() {
return this.year + "年" + this.month + "月" + this.day + "日";
}
}