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()
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法