文章目录
引入
Object类是类层次结构的根,Java中所有的类从根本上都继承自这个类。Object类是Java中其他所有类的祖先,没有Object类Java面向对象无从谈起。
Object类是Java中唯一没有父类的类。其他所有的类,包括标准容器类,比如数组,都继承了Object类中的方法。
Object 类位于 java.lang 包中,编译时会自动导入,我们创建一个类时,如果没有明确继承一个父类,那么它就会自动继承 Object,成为 Object 的子类。
Object 类可以显示继承,也可以隐式继承,以下两种方式时一样的:
显示继承:
public class A extends Object{
}
隐式继承:
public class A {
}
类的构造器(构造方法)
public Object()
//构造一个新对象。
Object类的方法
Object clone() 方法
Object clone() 方法用于创建并返回一个对象的拷贝。
clone 方法是浅拷贝,对象内属性引用的对象只会拷贝引用地址,而不会将引用的对象重新分配内存,相对应的深拷贝则会连引用的对象也重新创建。
以下实例创建了 obj1 对象,然后拷贝 obj1 给 obj2,通过 obj2 输出变量的值:
class RunoobTest implements Cloneable {
// 声明变量
String name;
int likes;
public static void main(String[] args) {
// 创建对象
RunoobTest obj1 = new RunoobTest();
// 初始化变量
obj1.name = "Runoob";
obj1.likes = 111;
// 打印输出
System.out.println(obj1.name); // Runoob
System.out.println(obj1.likes); // 111
try {
// 创建 obj1 的拷贝
RunoobTest obj2 = (RunoobTest) obj1.clone();
// 使用 obj2 输出变量
System.out.println(obj2.name); // Runoob
System.out.println(obj2.likes); // 111
} catch (Exception e) {
System.out.println(e);
}
}
}
输出结果:
Runoob
111
Runoob
111
Object equals() 方法
Object equals() 方法用于比较两个对象是否相等。
equals() 方法比较两个对象,是判断两个对象引用指向的是同一个对象,即比较 2 个对象的内存地址是否相等。
注意:如果子类重写了 equals() 方法,就需要重写 hashCode() 方法,比如 String 类就重写了 equals() 方法,同时也重写了 hashCode() 方法。
演示了 equals() 方法的使用:
class RunoobTest {
public static void main(String[] args) {
// Object 类使用 equals() 方法
// 创建两个对象
Object obj1 = new Object();
Object obj2 = new Object();
// 判断 obj1 与 obj2 是否相等
// 不同对象,内存地址不同,不相等,返回 false
System.out.println(obj1.equals(obj2)); // false
// obj1 赋值给 obj3
// String 重写了 equals() 方法
// 对象引用,内存地址相同,相等,返回 true
Object obj3 = obj1;
System.out.println(obj1.equals(obj3)); // true
}
}
false
true
String 类重写了 equals() 方法,用于比较两个字符串是否相等:
class RunoobTest {
public static void main(String[] args) {
// String 类使用 equals() 方法
// 创建两个对象
String obj1 = new String();
String obj2 = new String();
// 判断 obj1 与 obj2 是否相等
// 初始化的两个对象都为 null,所以是相等,返回 true
System.out.println(obj1.equals(obj2)); // true
// 给对象赋值
obj1 = "Runoob";
obj2 = "Google";
// 判断 obj1 与 obj2 是否相等
// 两个值不同,内存地址也不同,所以不相等,返回 false
System.out.println(obj1.equals(obj2)); // false
}
}
Object hashCode() 方法
Object hashCode() 方法用于获取对象的 hash 值。
hashCode() 方法的使用:
class RunoobTest {
public static void main(String[] args) {
// Object 使用 hashCode()
Object obj1 = new Object();
System.out.println(obj1.hashCode());
Object obj2 = new Object();
System.out.println(obj2.hashCode());
Object obj3 = new Object();
System.out.println(obj3.hashCode());
}
}
225534817
1878246837
929338653
String 和 ArrayList 类使用 hashCode() 方法,String 和 ArrayList 类都继承了 Object,所以可以直接使用 hashCode() 方法:
import java.util.ArrayList;
class RunoobTest {
public static void main(String[] args) {
// String 使用 hashCode()
String str = new String();
System.out.println(str.hashCode()); // 0
// ArrayList 使用 hashCode()
ArrayList<Integer> list = new ArrayList<>();
System.out.println(list.hashCode()); // 1
}
}
0
1
演示如果两个对象相等,则它们的哈希值也是相等的:
class RunoobTest {
public static void main(String[] args) {
// Object 使用 hashCode()
Object obj1 = new Object();
// obj1 赋值给 obj2
Object obj2 = obj1;
// 判断两个对象是否相等
System.out.println(obj1.equals(obj2)); // true
// 获取 obj1 与 obj2 的哈希值
System.out.println(obj1.hashCode()); // 225534817
System.out.println(obj2.hashCode()); // 225534817
}
}
Object getClass() 方法
Object getClass() 方法用于获取对象的运行时对象的类。
演示 getClass() 方法的使用,String 和 ArrayList 继承了 Object,所以可以直接使用 getClass() 方法:
import java.util.ArrayList;
class RunoobTest {
public static void main(String[] args) {
// getClass() with Object
Object obj1 = new Object();
System.out.println("obj1 的类为: " + obj1.getClass());
// getClass() with String
String obj2 = new String();
System.out.println("obj2 的类为: " + obj2.getClass());
// getClass() with ArrayList
ArrayList<Integer> obj3 = new ArrayList<>();
System.out.println("obj3 的类为: " + obj3.getClass());
}
}
obj1 的类为: class java.lang.Object
obj2 的类为: class java.lang.String
obj3 的类为: class java.util.ArrayList
自定义类调用 getClass() 方法:
class RunoobTest {
public static void main(String[] args) {
// 创建 RunoobTest 类的对象
RunoobTest obj = new RunoobTest();
// RunoobTest 继承 Object 类,Object 是所有类的超类
// 调用 getClass() 方法
System.out.println(obj.getClass());
}
}
class RunoobTest
Object toString() 方法
Object toString() 方法用于返回对象的字符串表示形式。
默认返回格式:对象的 class 名称 + @ + hashCode 的十六进制字符串。
演示 toString() 方法的使用:
class RunoobTest {
public static void main(String[] args) {
// toString() with Object
Object obj1 = new Object();
System.out.println(obj1.toString());
Object obj2 = new Object();
System.out.println(obj2.toString());
Object obj3 = new Object();
System.out.println(obj3.toString());
}
}
java.lang.Object@d716361
java.lang.Object@6ff3c5b5
java.lang.Object@3764951d
输出格式说明:
java.lang.Object - 类名
@ - 符号
d716361 - 哈希值的十六进制值
Array 类调用 toString() 方法:
class RunoobTest {
public static void main(String[] args) {
// toString() with array
// 创建数组
String[] array = { "Google", "Runoob", "Taobao" };
System.out.println(array.toString());
// 数组元素值返回一个字符串的表示形式
// Array 继承了 Object 类,所以可以直接使用 toString() 方法
System.out.println(array[1].toString()); // Runoob
}
}
Runoob
Object finalize() 方法
Object finalize() 方法用于实例被垃圾回收器回收的时触发的操作。
当 GC (垃圾回收器) 确定不存在对该对象的有更多引用时,对象的垃圾回收器就会调用这个方法。
演示了finalize() 方法的使用:
import java.util.*;
class RunoobTest extends GregorianCalendar {
public static void main(String[] args) {
try {
// 创建 RunoobTest 对象
RunoobTest cal = new RunoobTest();
// 输出当前时间
System.out.println("" + cal.getTime());
// finalize cal
System.out.println("Finalizing...");
cal.finalize();
System.out.println("Finalized.");
} catch (Throwable ex) {
ex.printStackTrace();
}
}
}
Sun Oct 11 11:36:46 CST 2020
Finalizing...
Finalized.
wait,notify,notifyAll方法
wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生。
其他线程调用了该对象的notify方法。
其他线程调用了该对象的notifyAll方法。
其他线程调用了interrupt中断该线程。
时间间隔到了。
此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。
notify方法
该方法唤醒在该对象上等待的某个线程。
notifyAll方法
该方法唤醒在该对象上等待的所有线程。
Object类型转换
Object转String
方法1:采用 Object.toString()方法
Object object = getObject();
System.out.println(object.toString());
在这种使用方法中,因为java.lang.Object类里已有public方法.toString(),所以对任何严格意义上的java对象都可以调 用此方法。但在使用时要注意,必须保证object不是null值,否则将抛出NullPointerException异常。采用这种方法时,通常派生类会覆盖Object里的toString()方法。
方法2:采用String.valueOf(Object)
String.valueOf(Object)的基础是Object.toString()。采用此方法,将不用担心object是否为null值这一问题。为了便于说明问题,我们来分析一下相关的源代码。Jdk里String. valueOf(Object)源码如下:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
object转int
1.如果object是byte,short,int,char类型生成的,那么不用转换直接赋值就ok了。
2.如果object是字符串类型生成的,先把object转换为String类型的,再把String类型转换为int类型。
String myInt="123";
Object os=myInt;
int b=Integer.parseInt((String)os);//还可以os.toString()
3.如果object是float,double,long类型生成的,思路和上面一样,先把object转换为相应的数据类型,然后再转换为int类型。
object转Date
SimpleDateFormat可以将String转为Date,也可以Date转为String.
.parse(String)
.format(Date)
即:
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-mm-dd");
String indate=sdf.format(date);
Date indate=sdf.parse(String);
如果你使用SpinnerDateModel.
可以试一下直接将你这个Object强制转换为Date
Date date = (Date) object;
Object数组引用讨论
Java 数组的本质是一个Java类,它是通过new语句来实例化,但是这个new语句却不会实例化数组中的对象。
对于基本类型的数组,在new语句创建数组实例时,会为该数组分配指定长度的内存空间,并把数组的每个元素的初始化为0。那么,引用类型的数组又是如何来创建和初始化这些内存空间的?其实,引用数据类型的数组也会分配指定长度的内存空间,只不过这些内存空间是用来保存引用的,而不是具体的值,它的初始化值为null。
那如果new Object[5]语句是否创建了5个object对象?我们来看下:
Object[]obj=new Object[5];
以上代码中,创建了一个Object数组,长度为5,这5个元素的值都是null,然后把创建好的数组实例的引用赋给obj变量。如果需要为这些元素分配具体的对象,则需要分别指定或用{}符号进行初始化,如下所示:
Object[]obj=new Object[]{new Object(),null,null,null,new String("123")};//引用类型的数组
或
obj[0]=new Object();//数组元素在赋对象引用
obj[4]=new String("123");
以上数组实例的内存构成,如图:
总结:
答案为否。其实是创建了一个数组实例,长度为5,每个数组元素的值均为null,并没有创建5个Object对象。如果需要创建5个Object对象,则需要为每个数组元素分别指定或用符号{}。