Object类是java中所有类,或直接或间接的父类 1.public final Class getClass() 返回此对象的运行时类(Class对象) 此对象:当前对象,在哪个对象上调用,指的就是哪个对象 结论:
在每个类被加载jvm中时,都会生成一个和该类对应的Class对象,该Class对象就唯一表示一个类.类 和 Class对象 一一对应,一个类只对应唯一一个Class对象通过使用面向对象语法,访问Class对象,从所而获取其所代表的类的相关信息 Class类(共性):可以定义构造方法可以定义成员变量可以定义成员方法 对象.getClass() public class Demo1GetClass { public static void main(String[] args) { TestGetClass obj = new TestGetClass(); // 返回代表当前对象所属类的 Class对象 Class aClass = obj.getClass(); // 访问代表TestGetClass类的class对象 String name = aClass.getName(); System.out.println(name); //com.cskaoyan.object.api.TestGetClasss System.out.println(aClass.getSimpleName()); //TestGetClass } } class TestGetClass { int a; public void test() { } }2.public String toString() a. 返回该对象的字符串表示。 b. 通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。 c. 结果应是一个简明但易于读懂的信息表达式。 d. 建议所有子类都重写此方法。 啥叫对象的字符串表示? 用一个字符串表示一个对象 1. 什么能表示一个对象的特征? 对象的成员变量值就能够表示一个对象的特征 从对象的 差异性 角度来理解对象的特征,同种类型对象 ,虽然具有相同的属性,但是各个不同的对象,属性的取值可以不同,因此产生了差异 2. 所以,最终表示一个对象特征的字符串,是由 对象的成员变量值 拼接成一个字符串的得到的 Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于: getClass().getName() + ‘@’ +Integer.toHexString(hashCode())
public class Demo2ToString { public static void main(String[] args) { // 首先测试Object类的toString方法 int i = 10; double j = 3.6; ToStringClass obj = new ToStringClass(i, j); // 使用Object的toString方法 String s = obj.toString(); // 全类名: getClass().getName() // 16进制数:代表一个对象的内存地址 System.out.println(s); // com.cskaoyan.object.api.ToStringClass@4554617c // ToStringClass{ i = 10, j = 3.6} //关于toString的两注意事项 // 1. 输出对象,输出的是对象的字符串表示(toString()方法的结果) System.out.println(obj); //ToStringClass{ i = 10, j = 3.6} // 2. 字符串 和 对象拼接, 其实是和表示对象的字符串拼接 String str = "hello, " + obj; System.out.println(str); //hello, ToStringClass{ i = 10, j = 3.6} } } class ToStringClass { int i; double j; public ToStringClass(int i, double j) { this.i = i; this.j = j; } // @Override public String toString() { return "ToStringClass{ i = " + this.i + ", j = " + this.j+ "}"; } }3.public boolean equals(Object obj)
对象.equals()指示其他某个对象是否与此对象“相等”。返回值: true 相等 ,false 不相等什么叫对象相等? a. 仍然从对象的差异性角度理解,同一个类的对象,之所以产生差异, 这个差异来源于成员变量的取值不同 b. 所以我们认为,同一个类的对象,当它们对应成员变量的值都相等,我们认为两个对象相等 同类的对象才需要比较是否相等,不同类的对象一定不相等。 public class Demo3Equals { public static void main(String[] args) { // 先测试Object中equals方法 int i = 99; double j = 6.6; EqualsClass obj1 = new EqualsClass(i, j); EqualsClass obj3 = new EqualsClass(i, j); i = 1; j = 5.6; EqualsClass obj2 = new EqualsClass(i, j); // 比较 boolean equals = obj1.equals(obj2); System.out.println(equals); //false System.out.println(" == " + (obj1 == obj2)); equals = obj1.equals(obj3); System.out.println(equals); System.out.println(" == " + (obj1 == obj3)); EqualsClass obj4 = obj1; equals = obj1.equals(obj4); System.out.println(equals); System.out.println(" == " + (obj1 == obj4)); } } class EqualsClass { int i; double j; public EqualsClass(int i, double j) { this.i = i; this.j = j; } @Override public boolean equals(Object obj) { if (this == obj) { // 考虑自反, 自己和自己相等 return true; } // 考虑null 和 不同类型对象比较的情况 if (obj == null || this.getClass() != obj.getClass()) { // 带比较对象为null,一定不等 // 如果带比较对象和当前对象不是同一个类的对象,也不等 return false; } // 比较同种类型,两对象成员变量的值 EqualsClass that = (EqualsClass) obj; if (this.i != that.i) { return false; } // 但是对于double类型的小数的比较,如果要比较精确的比较两个小数值 // 如果 Double.compare(double,double)返回值如果是0,代表两个double类型的小数相等,否则不等 int compare = Double.compare(this.j, that.j); return compare == 0; } }4.public int hashCode()
返回该对象的哈希码值。
hash函数定义: A hash function is any function that can be used to map data of arbitrary size onto data of fixed size. The values returned by a hash function are called hash values,hash codes or simply hashes.
hashCode 的常规协定是: 1.在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数, 前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
2.如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode方法都必须生成相同的整数结果。
3.如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode方法 不要求一定 生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
public class Demo4HashCode { public static void main(String[] args) { HashCodeClass obj = new HashCodeClass(10, 9.5); System.out.println(obj.hashCode()); // 1163157884 } } class HashCodeClass { int i; double j; public HashCodeClass(int i, double j) { this.i = i; this.j = j; } @Override public int hashCode() { int result; long temp; result = i; temp = Double.doubleToLongBits(j); result = 31 * result + (int) (temp ^ (temp >>> 32)); return result; } }5.protected Object clone()
创建并返回此对象的一个副本在复制对象的时候,遇到了两个问题: clone的权限问题 a. 首先clone方法具有protected访问权限,而且Object类定义在java.lang包下 b. Demo1 和 FirstLevel都继承了Object的方法,他们都可以在自己的类体中访问, 自己所继承的,来自Object类的clone方法(都属于跨包子类访问父类的protected成员) 比如:Demo1 和 FirstLevel 中的testProtectedAccess方法 c. 但是我们在Demo1类中,写了语句FirstLevel clone = (FirstLevel) firstLevel.clone()即我们要在Demo1类中,调用FirstLevel类继承自Object的clone方法。这不叫子类访问父类的方法,所以protected权限不允许CloneNotSupportedException,原因是如果要复制一个对象,该对象所属类,必须实现一个接口Cloneable接口 public interface Cloneable { }.类似于Cloneable这种空接口,我们也称之为标记接口,这种接口是用来做标记 public class Demo1 { public static void main(String[] args) throws CloneNotSupportedException { // 创建对象 int i = 10; double j = 6.7; FirstLevel firstLevel = new FirstLevel(i, j); // 利用object的clone方法复制当前对象 FirstLevel clone = (FirstLevel) firstLevel.clone(); //修改复制对象 clone.firstIntValue = 800; System.out.println(clone); //FirstLevel{firstIntValue=10, firstDoubleValue=6.7} System.out.println(firstLevel); } // 演示protected权限问题 public void testProtectedAccess() throws CloneNotSupportedException { // 直接在类体中调用继承自Object的clone this.clone(); Demo1 demo1 = new Demo1(); demo1.clone(); } } class FirstLevel implements Cloneable { int firstIntValue; double firstDoubleValue; public FirstLevel() { } public FirstLevel(int firstIntValue, double firstDoubleValue) { this.firstIntValue = firstIntValue; this.firstDoubleValue = firstDoubleValue; } // 之所以定义这个方法是因为权限问题 @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } // 演示protected权限问题 public void testProtectedAccess() throws CloneNotSupportedException { // 直接在类体中调用继承自Object的clone this.clone(); FirstLevel firstLevel = new FirstLevel(); firstLevel.clone(); } @Override public String toString() { return "FirstLevel{" + "firstIntValue=" + firstIntValue + ", firstDoubleValue=" + firstDoubleValue + '}'; } }6.protected void finalize() 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法
