1.1 Object类的含义
Object是所有的类的父类,在定义新的类或者Java本身已定义的类中都会直接或者间接继承Object类,因此有的时候也称它为其他Java类的根父类,内部声明的方法具有通用性,有的时候它也是基类。
Object类中的几个特殊方法:
clone():这是用来复制一个跟原来一模一样的对象的方法,可以看做是创建Java中对象的第二种方式。
finalize():当垃圾回收器在回收对象前,对象会调用此方法。
面试题:final、finally、finalize这三者之间有什么不同?
final、finallly、finalize本质上就是不一样的事物,其中:
final:是修饰符,也就是关键字。被final修饰的类不能被继承。被final修饰的变量在使用的过程中不被修改。被声明为final的变量必须在声明时给出变量的初始值,而在以后的引用中只能读取。被final声明的方法也同样只能使用,即不能方法重写。
2、finally
finally是在异常处理时提供的用来执行必须要执行的操作。不管有没有异常被抛出、捕获,finally块都会被执行。try块中的内容是在无异常时执行到结束。catch块中的内容,是在try块内容发生catch所声明的异常时,跳转到catch块中执行。finally块则是无论异常是否发生,都会执行finally块的内容,所以在代码逻辑中有需要无论发生什么都必须执行的代码,就可以放在finally块中。
3、finalize是方法名。
java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者被执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
hashcode():关于集和的方法【见集和内容部分】
wait()、notify()、notifyAll():关于线程通信内容【见线程通信内容部分】
1.2 几个重要的object类的方法
1.2.1 equals()的使用
java.lang.object类的equals()的使用:
1.java.lang.Object类的equals()的声明:
public boolean equals(Object obj){
return (this == obj);
}
说明:Object类中的equals()是比较两个对象的地址值是否相同。(或比较两个引用是否指向堆空间中的同一个对象)
2.像在String \File\Date类等重写了Object类中的equals()。重写的规则就是判断它们是否内容或者说属性值是否都相等。
3. 自定义类重写Object类的equals()前,比较的都是两个引用地址值是否相等。但是一般开发中,凡是调用了equals(),都是想比较两个对象的实体内容是否相等,这也意味着我们需要重写equals方法。
代码举例
public class Order {
private String orderName;
private int orderId;
public Order(String orderName, int orderId) {
this.orderName = orderName;
this.orderId = orderId;
}
public Order() {
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
//
//手动重写equals(),比较两个对象的实体内容是否相等
// @Override
/* public boolean equals(Object obj) {
System.out.println("order equals().....");
if (this == obj) {
return true;
}
if (obj instanceof Order) {
Order order = (Order) obj;
//比较当前Order对象this与order对象的实体内容
if (this.orderId == order.orderId && this.orderName == order.orderName){
return true;
}
// return false;或者在这里在写个,但是这样代码就冗余了
}
return false;
}*/
//自动生成
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Order order = (Order) o;
return getOrderId() == order.getOrderId() &&
getOrderName().equals(order.getOrderName());
}
}
面试题:==和equals()方法的区别?
==和equals()方法都是表示判断是否相等,但==可以用来比较基础数据类型和引用数据类型,而equals()方法我们通常是用来判断引用数据类型。
【1】==在比较基础数据类型的时候是去判断两个数据值是否相等,判断引用数据类型是判断引用是否指向堆空间中的同一个对象,除了判断String类型的时候,会有一些例外,主要是因为:
Java运行时会维护一个String Pool(String池),String Pool与JAVA堆栈是各自独立的。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。
String对象的创建遵循以下几个原则。
原则1:只要使用new关键字来创建对象(String str = new String("123")),则一定会(在堆区或栈区)创建一个新的对象。
我们知道,只要一个对象是New出来的,那JVM肯定会在内存中为此对象分配一个唯一的地址,因此New出的对象跟任意一个对象用“==”判断肯定为false。
原则2:使用直接指定来创建String对象(如String str="123"),则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。
原则3:使用包含变量的表达式来创建对象String(String str = "123"+"456"),则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。
代码示例
public class StringTest {
public static void main(String[] args) {
通过字面量的方式进行字符串的赋值操作。
此时的字符串数据保存在字符串常量池中。
字符串常量池中,不存在内容相同的字符串。
String s1 = "hello";[字面量赋值的方式]
String s2 = "hello";
String s3 = new String("hello");
String s4 = new String("hello");
System.out.println(s1.equals(s2));//true
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s1 == s4);//false
System.out.println(s3 == s4);//false
}
}
所以在使用==去判断是否String相等的时候,应该注意它的原则!
【2】而使用equals方法去对引用数据类型去判断的时候,可以看到Java中equals的源码,他就是去判断两个类型是否指向堆空间同一个地址值,所以如果我们是对String类型进行判断,(判断是否值相等或者说内容相等),通常是我们对equals方法进行了重写。
1.2.3 toString()方法的使用
Object类中对于toString()的源码展示:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
几个注意点:
1.如果当我们并没有重写Object类中的toString()方法的时候,当输出对象的引用时,默认调用Object中的toString()方法,输出对象的地址值。
2.像String\日期\Date\File类等类型都重写了Object类中的toString()方法,返回其实体内容。
3.如果我们希望调用自定义类的toString()时,希望返回其内部实体内容,需要进行重写。
代码示例
public class Order {
private String orderName;
private int orderId;
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public Order(String orderName, int orderId) {
this.orderName = orderName;
this.orderId = orderId;
}
public Order() {
}
//手动生成的:
// public String toString() {
// return "Order[orderName : " + orderName + ",orderId : " + orderId + "]";
// }
//自动生成的:
@Override
public String toString() {
return "Order{" +
"orderName='" + orderName + '\'' +
", orderId=" + orderId +
'}';
}
}