equals 方法
/*
* Object:是Java中提供的一个根类
* 所有类都直接或间接的继承了 Object
* 如果一个类没有显示继承父类,那么该类默认继承 Object
* Object 中的方法是所有类都有的功能
* Object xxx = new xxx; 可以发生多态
* 如果一个方法需要传递数据,却不能确定数据的类型的时候,可以写 Object
*
* 学习方法
* 1 该方法属于哪个类
* 2 是什么方法(静态/成员)
* 3 功能、入参、出参分别是?(能实现什么,需要什么,返回什么)
* 4 什么时候需要重写(需求不能满足时)
*
* Object中的equals方法
* 源码:public Boolean equals(Object obj) {return (this == obj)}
* 目的:比较两个对象是否相等
* 两个对象可以代表任意实体,不同对象内存地址肯定不同,因此equals方法
* 不是比较内存地址,这时将两个对象对应得equals方法进行重写,以满足需求
* 因此此时可以比较对象间的属性来判断是否相等
* 不同类的对象,没有可比性
*
* == :两边如果是基本类型,则比较值得大小,如果是引用类型,则比较内存地址
* Object中equals默认比较 内存地址 return (this == obj)
* String 的底层是Char数组
* */
public class _01_Equals {
public static void main(String[] args) {
_Equ_Student stu1 = new _Equ_Student(18,"小明");
_Equ_Student stu2 = new _Equ_Student(10,"小明");
System.out.println(stu1 == stu2); // 内存地址不相等
System.out.println(stu1.equals(stu2)); // 重写equals方法,自定义对象相等条件
}
}
class _Equ_Student{
private int age;
private String name;
public _Equ_Student() {
super(); // 默认存在,默认继承Object
}
public _Equ_Student(int age, String name) {
super(); // 默认存在,默认继承Object
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 需求 name与age相等就判断两个对象相等
// 转换成基本数据类型的比较
@Override
public boolean equals(Object obj) {
// 1 比较地址,地址相同 值一定相同,地址相同说明是同一个对象
if (this == obj) return true;
// 2 判断 对象类型 是否为当前类类型,否返回false,不同类没有可比性
if (obj instanceof _Equ_Student){
// 3 强制转换,比较想要比较的数据
_Equ_Student stu2 = (_Equ_Student) obj;
// name调用的是String类型的equals,是引用类型
return name.equals(stu2.name) && age == stu2.age;
}
return false;
}
}
/*
* 比较字符串是否相等
* 用equals 因为 == 比较的是内存地址
* 在string类中 已经重写了equals方法,重写后比较的是 值 不是地址
*
* 任何引用类型的比较,都必须转换成基本数据类型比较,除了比较地址是否一致
* 面向对象是哟中基本数据封装的形式,比较的时候最终要转换成基本数据类型比较,也就是比较相同属性是否具有相同的属性值
* */
public class _02_Equals {
public static void main(String[] args) {
String s1 = new String("a123");
String s2 = new String("a123");
String s3 = "a123";
String s4 = "a123";
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
System.out.println(s3 == s4);
System.out.println(s3 == s1);
System.out.println(s3.equals(s1));
}
}
toString 方法
/*
* toString
* 设计目的:返回该对象的字符串表示形式
*
* 输出一个引用类型的时候,会自动调用该对象的toString方法
* 输出语句中:如果对象所属类中没有重写toString方法时,默认打印对象内存地址
*
* Object中的toString方法
* public String toString(){
* return getClass().getName() + "@" + Integer.toHexString(hashCode());
* }
* */
public class _01_toString {
public static void main(String[] args) {
String s1 = new String("123a"); // String类里面重写了toString方法
_01_toString s2 = new _01_toString();
System.out.println(s1);
System.out.println(s2);
Person_toString xiaoming = new Person_toString(18, "小明");
System.out.println(xiaoming);
System.out.println("姓名:"+xiaoming.getName()+" ,年龄:"+xiaoming.getAge());
}
// 重写后自动调用当前对象的toString方法
@Override
public String toString() {
return "_01_toString方法测试";
}
}
class Person_toString{
private int age;
private String name;
public Person_toString(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
// 通过重写toString方法来对当前对象进行描述
return "姓名:"+name+" ,年龄:"+age;
}
}
hashCode 方法
/*
* hashCode设计目的:给每一个对象生成一个唯一的标识符
* 同一个对象多次生成的 hash值 一定是一样的
* 不同对象生成的 hash值 也可能相同,这又叫哈希冲突
* 存在哈希冲突情况,如何保证数据的唯一性?
* 1 先比较hash,如果hash不同,则对象不同
* 2 如果hash值相同,在比较对象属性(equals)
*
* 覆写hashCode的时候,还需考虑? equals
* 覆写equals的时候,还需考虑? hashCode
* 因为在Java中,可以通过equals和hashCode来表示对象的唯一性
*
* hash算法:一种安全的加密算法,把不定长的值改为定长的值,但 不能保证其唯一性(哈希冲突)
* */
public class _01_hashCode {
public static void main(String[] args) {
_01_hashCode hc = new _01_hashCode();
int hash = hc.hashCode(); // 460141958
// 1b6d3586
// Integer.toHexString(hash)将10进制转换成16进制
// 当前类中重写后输出为1
System.out.println(Integer.toHexString(hash));
// com.tianl.oop._15_Object._01_hashCode@1b6d3586
System.out.println(hc); // 默认打印内存地址
}
// 可根据需求重写hashCode()
// @Override
// public int hashCode() {
// return 1;
// }
}
finalize 方法
/*
* finalize 方法
* 垃圾被回收之前 自动调用该方法。属于Object
* 可覆写该方法实现定制化
*
* 1 finalize是每个对象都有的方法
* 2 不需要手动调用,有系统自动调用
* 3 Java中如果没有更多的引用指向这个对象,那么该对象被视为垃圾数据,等待被回收
* 被回收之前,自动调用finalize方法
* 4 finalize没有垃圾回收功能,只是用于被回收之前做一些操作,回收由JVM执行
* 所以就算手动调用,也只是一个普通的成员方法调用,和对象回收没有关系
* 5 一般用于对象回收之前做一些数据销毁操作
* */
public class _01_Finalize {
public static void main(String[] args) {
Animal_F animal_f = new Animal_F();
animal_f = null;
// 程序员只能建议 垃圾回收器回收
// System.gc();
// 如果垃圾过多,不用建议,自动回收
for (int i = 0; i < 999999; i++) {
new Animal_F();
}
}
}
class Animal_F{
@Override
protected void finalize() throws Throwable {
System.out.println(this + "马上就要被回收了");
}
}