Object类
通过API文档学习Object类中的方法
类 Object 是类层次结构的根类(祖类),每个类直接或间接的继承Object,作为超类(父类),所有对象(包括数组)都实现这个类的方法。
Object中常用的方法:
1)public int hashCode()
说明:返回该对象的哈希码值(16进制的)
流程:hashCode()----->通过哈希算法(源码表去看)(哈希表:hashtable)---->地址值(不是实际意义上的地址值!)
********************************************************
2)public final Class getClass()
说明:返回此 Object(对象)的运行时类 (Java反射机制中讲!)
返回的Class对象是由所表示类的 static synchronized方法锁定的对象
返回这个对象真实的Class对象
********************************************************
注:Class类中有一个方法
public String getName();//Class类位于java.lang的包中
以 String的形式返回此 Class对象所表示的实体(类、接口、数组类、基本类型或 void)名称;
*************************************************************
实例1:
package day010;
//自定义的类
public class Student extends Object {
private String name;
private int age;
public Student() {
super();
}
}
测试类:
//测试类
public class ObjectDemo {
public static void main(String[] args) {
/*内容1:
* public int hashCode();
* 返回值:生成对应的hash码(类似地址)
* 了解hashCode()的源码
*/
//对象名不同,hash码不同
Student student1 = new Student();
System.out.println(student1.hashCode());
System.out.println("对象名(引用)不同,hash码不同-----");
Student student2 = new Student();
System.out.println(student2.hashCode());
//常量不变
System.out.println("Hello".hashCode());
System.out.println("-----------------");
/*内容2:
* public final Class getClass();
* 返回值类型:Class
* 返回此 Object(对象)的运行时类
* 语法:对象名.getClass()
* 表示此对象c1运行时类的 Class对象
*/
Class c1 = student1.getClass();
System.out.println("c1:"+c1);//c1:class day010.Student(class的含义?)
System.out.println("------------------");
/*
* 内容3:
* public String getName():
* 返回值:获取当前正在运行的该类的全路径名称!(与上作比较)
* 返回值类型:String;
* 语法格式:对象名.getName()
* */
String name = c1.getName();//Class类中的方法
System.out.println("name:"+name);//全路径名称:name:day010.Student
}
}
3)Object的toString()方法
public String toString();
说明:返回该对象的字符串表示(建议所有子类都重写此方法)
补充:对类PrintWriter中的println()方法以图解形式解析:
实例2:
package day10;
//学生类
public class Student extends Object {
//成员变量
private String name;
private int age ;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/*alt+shift+s->s-------自动生成!
注释掉看看不重写的结果
*/
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
测试类:
package day10;
/**
* 3)Object的另一个方法:
* public String toString();
* 返回该对象的字符串表示(建议所有子类都重写此方法)
*
* 4)Integer类(包装类型)中有一个方法:
* public static String toHexString(int i):
* 说明:将一个int类型的数据转换成一个十六进制的字符串表现形式
*
* */
public class ObjectDemo {
public static void main(String[] args) {
Object object=new Object();
System.out.println(object);
/**
* 上述输出结果:java.lang.Object@1db9742
* 首先对println的说明:
* 类PrintWriter中的println()方法有多种重载形式
* 其中一种形式:public void println(Object obj);
* 打印的是对象(引用),调用此方法返回的值是:
* obj.toString();
* */
/**分析:toString()
* 通过查看Object类的toString()方法源码:
* public String toString() {
return this.getClass().getName() + "@" + Integer.toHexString(this.hashCode());
}
toString()<==> 对象名.getClass().getName() +"@" +Integer.toHexString(对象名.hashCode())
深入分析一下:
Integer.toHexString(this.hashCode())的含义:
this.hashCode()是返回该对象哈希码值,通过int对应的包装类型将Integer中的toHexString()将对象转化为16进制
*/
System.out.println("分割符-----------------------------------");
//要求:如果直接输出对象名称,想要显示当前对象的成员变量的值,那么必须重写Object类中的toString()方法
//创建一个学生对象
Student s1 = new Student("高圆圆",34) ;
//直接输出对象名称
System.out.println("s1:"+s1);
/*对s1结果的说明:
*如果toString()方法不重写结果:day10.Student@106d69c
*说明:此时Student类继承了Object类本身的toString()方法
*此时重写toString()方法:
*得到的返回值:Student [name=高圆圆, age=34]
**/
System.out.println("等价形式-------------");
System.out.println("toString():"+s1.toString());//现在等价于对象调用自己的toString()方法
System.out.println("分割线--------------------------");
/**
* 出现上述现象的说明:
* 通过对Object类的toString()方法重写:
* public String toString() {
return "返回的内容为:String的对象本身";
}
注意:这又涉及到System.out.println(String s);
它输出的是:对象自身。
*/
//下列两行代码是对上述分析的一个显示的输出(对比分析结果)
System.out.println(s1.getClass().getName()+"@"+Integer.toHexString(s1.hashCode()));
System.out.println(s1.toString());
//下列两行代码说明:s1和s2的引用不一样,虽然内容一样
Student s2 = new Student("高圆圆", 27) ;
System.out.println("s2:"+s2);
System.out.println(s1==s2);
}
}
4)Object中的equal()方法
public boolean equals(Object obj)指示其它某个对象是否与此对象“相等”。
常见面试题:
==和equal()方法的区别:
1)==比较的是两个对象的地址值是否相同
2)而equals()方法默认比较的是两个对象的地址值是否相同,如果重写了Object类中的equals()方法,那么默认比较就是两个对象的内容是否相同
注意:String中有equal()方法:将此字符串与指定的对象比较;语法格式:字符串对象名.equals(字符串对象名)
说明使用工具自动生产equals()方法:
javascript中:Array对象、Number对象、String对象中的valueOf():====>语法格式:s1.valueOf(s2) ,比较是内容是否相同
实例3:
package org.westos.object_03;
public class Student {
//成员变量
private String name;
private int age ;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//重写Object类的toString()方法
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
/*重写了Object类中的equals()方法
*但是有个疑问:equal()比较的仅仅是属性,是否包含方法?
*语法:对象名 instanceof 类:判断该对象是否是该类的一个实例
* */
/*参数传递形式:Studnet s2 = new Student();
*疑问:是否可将Object换成Student(尝试过,但报错);
*是否涉及到多态(值得探究)?
*参数传递形式:Object obj=new Student();
*/@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null) //当前传入过来的对象是否为空
return false;
if (getClass() != obj.getClass()) //this.getClass() != s2.getClass()
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
测试类:
package org.westos.object_03;
public class ObjectDemo {
public static void main(String[] args) {
//创建学生对象
Student s1 = new Student("高圆圆", 27) ;
Student s2 = new Student("高圆圆",27) ;
System.out.println(s1==s2);
System.out.println("------------------");
Student s3 = s1 ;
System.out.println(s1==s3);
System.out.println("-------------------");
System.out.println(s1.equals(s2));//由于重写Object中的equals()方法,所以比较的是对象的内容是否相同!
/**
*equals()方法的源码:
* public boolean equals(Object obj) {
* return (this == obj);
* }
* 由于Object类中的equals()方法底层是通过"=="来实现的,所以默认比较的是地址值;如果想比较内容是否相同,需要重写equals()方法
* */
}
}
实例4:
package org.westos.object_04;
//学生类
public class Student implements Cloneable{
private String name ;
private int age ;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/*要去使用clone()方法,当前对象所在的类一定要实现cloneable接口;
*重写Object类中clone()
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
测试类:
package org.westos.object_04;
/**
* Object类中的其他两个方法:
* 5)protected void finalize()throws Throwable:
* 说明:当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法,但是什么时候调用垃圾回收器不确定;
* 对比System类中的一个方法:
* public void gc()----运行垃圾回收器(垃圾处理及时),这个垃圾回收器最终调用的就是finalize()方法
* 理解:这个gc()与main()构成多线程
*
* 6)protected Object clone();
* 说明:创建并返回此对象的一个副本,等于另外又开辟了一个对象
* 语法格式:对象名.clone();
* 返回值类型:Object
throws CloneNotSupportedException(暂时不是太懂?)
注意事项:
Object类的 clone()方法执行特定的复制操作;
首先如果此对象的类不能实现接口 Cloneable,则会抛出 CloneNotSupportedException。
* */
public class ObjectDemo {
public static void main(String[] args) throws CloneNotSupportedException {//该异常是编译时期异常
//创建s1这个学生对象
Student s1 = new Student() ;
s1.setName("高圆圆") ;
s1.setAge(34) ;
System.out.println(s1.getName()+"---"+s1.getAge());
//复制s1这个对象(重点)
Object obj = s1.clone();
//多态---等价于 :Object obj=new Student();
//向下转型(可以向下转型的原因:哪个方法重写了?):答:重写了Object的clone()方法
Student s2 = (Student)obj;
System.out.println(s2.getName()+"---"+s1.getAge());
System.out.println("----------------------");
/*没有讲clone方法之前:
*把s1地址值赋值s3对象,s3指向s1的堆内存中的地址值;
*即:让两个引用指向同一个对象
* */
Student s3 = s1;
System.out.println(s3.getName()+"---"+s3.getAge());
}
}
参考文献(后续补充)
未完待续......