由 Object 类定义的 hoshCode 方法确实会针对不同的对象返回不同的整数
特点:
1.该值可以理解为地址值,但是本质是地址值的一个转换值,该值相同不能说明两个对象相等,但是可以作为参考,该值不相等那么两个对象肯定不一样
2.该值是对象的哈希玛值(后面讲解哈希算法和哈希表结构的时候详细讲解)
关于 == 比较基本数据类型和引用数据类型
比较基本数据类型
____ 比较的是数值是否相等
比较引用类型
____ 比较的是地址值是否相等
package com.sxt.objectdemo;
/*
* int hashCode() (重点掌握)
* 由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数
*
* 特点:
* 1.该值可以理解为地址值,但是本质是地址值的一个转换值,该值相同不能说明两个对象相等,但是可以作为参考,该值不相等那么肯定两个对象不一样
* 2.该值是对象的哈希码值 (后面讲解哈希算法和哈希表解构的时候详细讲解)
*
* 关于==比较基本数据类型和引用数据类型
* 比较基本数据类型
* 比较的是数值是否相等
* 比较引用类型
* 比较的是地址值是否相等
*/
public class ObjectDemo02 {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
Student s3 = s1;
System.out.println(s1.hashCode());
System.out.println(s3.hashCode());
System.out.println(s1 == s3);
}
}
Class getClass() (反射中详细讲解)
返回的是一个字节码文件对象
任何一个类编译会生成字节码文件对象
Student.java --> Student.class
这个Student.class文件就是class类
Java万事万物都是对象,那么我们可以理解为这个class文件在代码中就是class类
package com.sxt.objectdemo;
/*
* Class getClass() (反射中详细讲解)
* 返回的是一个字节码文件对象
*
* 任何一个类编译会生成字节码文件对象
* Student.java --> Student.class
* 这个Student.class文件就是Class类
* Java万事万物都是对象,那么我们可以理解为这个Class文件在代码中就是Class类
*/
public class ObjectDemo03 {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
System.out.println(s1 == s2); // false
Class c1 = s1.getClass();
Class c2 = s2.getClass();
System.out.println(c1 == c2);
String name = c1.getName();
String name2 = c2.getName();
System.out.println(name); // com.sxt.objectdemo.Student
System.out.println(name2);
String name3 = s1.getClass().getName();
System.out.println(name3);
}
}
String toString( )
观察toString的源码:public String toString() {
return getClass().getName() + “@” + Integer.toHexString(this.hashCode());
默认输出语句输出对象的时候输出的是对象的toString方法
观察toString的源码发现来自于Object的toString方法打印的类名全路径 + 地址值的转换值的十六进制
对我们毫无意义,Object类toString方法不能够满足子类Student的需求,所以需要方法重写
如何重写?
一般希望打印对象的 成员属性值
一般我们都不自己写,都自动生成
alt + shift + s再按S
package com.sxt.objectdemo;
/*
* String toString() (重点掌握)
*
* 观察toString的源码
* public String toString() {
return getClass().getName() + "@" + Integer.toHexString(this.hashCode());
}
*
* 默认输出语句输出对象的时候输出的是对象的toString方法
*
* 观察toString的源码发现来自于Object的toString方法打印的类名全路径 + 地址值的转换值的十六进制
* 对我们毫无意义,Object类toString方法不能够满足子类Student的需求,所以需要方法重写
*
* 如何重写?
* 一般希望打印对象的 成员属性值
*
* 一般我们都不自己写,都自动生成
* alt + shift + s再按S
* null
* System.out.println(s3);
* null
* public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
null
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
*/
public class ObjectDemo04 {
public static void main(String[] args) {
Student s1 = new Student("隔壁老孙", 33);
Student s2 = new Student("隔壁老邓", 30);
int hashCode = s1.hashCode();
System.out.println(hashCode);
System.out.println(s1.toString());
System.out.println(s2.toString());
System.out.println("---------------------------");
System.out.println(s1);
System.out.println(s2);
// Student s3 = null;
// System.out.println(s3);
// System.out.println(null);
}
}
通过观察String和Object的equals方法我们知道一般比较成员变量是否相等
一般都是自动生成
alt + shift + s 再按H
package com.sxt.objectdemo;
/*
* boolean equals(Object obj) (重点掌握)
*
* 观察equals的源码:
* s1.equals(s2)
* public boolean equals(Object obj) {
* // s1 == s3
return (this == obj);
}
再来观察String类equals方法
String str1 = "abc"; [a,b,c]
String str2 = "abd";
class String {
private final char value[];
public boolean equals(Object anObject) {
// 效率考虑
if (this == anObject) {
return true;
}
// 安全性考虑
if (anObject instanceof String) {
"abd"
String anotherString = (String)anObject;
int n = this.value.length; // 3
// 效率考虑
if (n == anotherString.value.length) {
char[] v1 = this.value; // 地址传递 [a,b,c]
char[] v2 = anotherString.value; [a,b,c]
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
}
通过观察String和Object的equals方法我们知道一般比较成员变量是否相等
一般都是自动生成
alt + shift + s 再按H
*/
public class ObjectDemo05 {
public static void main(String[] args) {
Student s1 = new Student("貂蝉", 18);
Student s2 = new Student("吕布", 19);
Student s3 = new Student("貂蝉", 18);
System.out.println(s1.equals(s2)); // false
System.out.println(s1.equals(s1)); // false
// String str1 = "铁良";
// String str2 = "铁坚";
// String str3 = "铁良";
//
// System.out.println(str1.equals(str2)); // false
// System.out.println(str1.equals(str3)); // true
//
// System.out.println(str1.equals(str1));
//
// System.out.println(str1.equals(new Student()));
}
package com.sxt.objectdemo;
/*
* protected Object clone() (了解)
* 克隆: 深拷贝和浅拷贝 查资料了解
*
* java.lang.CloneNotSupportedException
* CloneNotSupportedException: 克隆不支持异常
* 产生原因: 需要被clone的类没有实现Cloneable接口
* 解决办法: 实现Cloneable接口
*
* Cloneable: 该接口没有任何的抽象方法,这样的接口称为标记接口
* 该接口是否实现本身就是一种功能的体现
*
* 克隆和引用传递有何区别?
* 克隆是和原来空间中独立出来的一份
* 地址传递是多个引用指向同一个堆区的空间
*/
public class ObjectDemo06 {
public static void main(String[] args) throws CloneNotSupportedException {
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",20);
/*Object obj = s1.clone();
if (obj instanceof Student) {
Student s = (Student) obj;
System.out.println(s.getName() + "|" + s.getAge());
}*/
Object obj = s1.clone();
Student s3 = (Student) obj;
s3.setName("隔壁老张");
s3.setAge(40);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
Student s4 = s1;
s4.setName("隔壁老邓");
s4.setAge(50);
System.out.println("-------------");
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
}
}
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
package com.sxt.objectdemo;
/*
* protected void finalize()
* 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
*
* final finalize finally 三者区别
*/
public class ObjectDemo07 {
public static void main(String[] args) throws Throwable {
Student s = new Student();
s = new Student();
// s.finalize();
// 如果你希望自己来回收垃圾对象,按照如下步骤
// 1.启动垃圾回收期
System.gc();
// 2.调用系统运行垃圾回收期的回收方法
System.runFinalization();
}
}
Student测试类
package com.sxt.objectdemo;
public class Student implements Cloneable {
private String name;
private int age;
public Student() {}
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;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
/*@Override
public String toString() {
return "大家好,我叫做" + this.name + ",我今年" + this.age + "岁";
}*/
/*@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Student) {
Student s = (Student) obj;
if (this.age == s.getAge() && this.getName().equals(s.getName())) {
return true;
}
}
return false;
}*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.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;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
}
}
interface MyCloneable {
boolean isAgreeClone();
}