欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > Java的Object类

Java的Object类

2024/10/24 12:28:45 来源:https://blog.csdn.net/m0_73966521/article/details/140109844  浏览:    关键词:Java的Object类

概述:所有类的根类(父类),所有的类都会直接或者间接继承Object类

Object中的toString()方法:

如果不重写这个toString方法:默认形式是:

 return getClass().getName() + "@" + Integer.toHexString(hashCode());

这个我们可以进到Object里面去看

 


a.如果没有重写Object中的toString方法,直接输出对象名会默认调用Object中的toString方法,直接输出地址值 

这两行代码生成的结果是一样的

 b.如果重写了Object中的toString方法,再输出地址值,重写没有意义,所以重写完toString之后,应该返回对象的内容 

然后我们按住ctrl 鼠标点击list的toString方法追踪一下

可以得出这里重写了这个toString()方法。

对这个JavaBean对象重写toString方法之后也是一样

Object的equals方法:

这部分的介绍我直接通过代码的案例来讲:

第一个案例:

class A {String name;int age;@Overridepublic String toString() {return "A{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class Test {public static void main(String[] args) {A a1 = new A();A a2 = new A();System.out.println(a1==a2);System.out.println(a1.equals(a2));}
}

第一段代码:我创建了一个A对象,我并没有重写equals方法,所以我们也可以知道,如果我在主函数中调用,那应该调用Object的默认equals方法

输出结果:

false
false

这是应该Object的默认equals方法比较得是地址值

第二个案例:

public class Test {public static void main(String[] args) {A a1 = new A();A a2 = new A();System.out.println(a1==a2);System.out.println(a1.equals(a2));System.out.println("========================");String a = "abc";String b = "abc";System.out.println(a==b);System.out.println(a.equals(b));}
}class A {String name;int age;@Overridepublic String toString() {return "A{" +"name='" + name + '\'' +", age=" + age +'}';}
}

 这一段代码我又创建了两个String变量:值都是"abc"

输出结果:

true

true

a==b 最后能输出true的原因是:

在Java中,当你声明两个字符串变量 ab 并初始化为相同的值 "abc" 时,System.out.println(a==b) 会输出 true。这是因为在Java中,字符串常量池(String Pool)的概念起了作用。

字符串常量池是一个特殊的内存区域,用于存储所有创建的字符串实例。当你创建一个新字符串 "abc" 时,实际上系统会在字符串常量池中查找是否有相同内容的字符串,如果找到了,就直接引用那个已经在池中的对象,而不是新建一个新的对象。所以,"abc""abc" 实际上指向的是同一个内存地址,因此 == 运算符比较它们的时候返回 true,表示它们是相等的。

 a.equals(b)最后能输出true的原因是:String重写了equals方法,在重写的方法中比较了两个字符串的序列


所以我们可以先做一个小总结:

  a.如果没有重写Object中的equals方法,那么就会调用Object中的equals方法,比较对象的地址值
  b.如果重写了Object中的equals方法,那么就会调用重写后的equals方法,应该比较对象的内容

接着我们再从idea自动给我们重写的equals方法的几行代码中分析一下逻辑:

 

    @Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;A a = (A) o;return age == a.age && Objects.equals(name, a.name);}

这一段是编辑器自动帮我们写的equals方法

首先先说明一下,这里面的this是什么,在Java面向对象的特性中有一个this

Java面向对象特性-CSDN博客

这里的this是指当前对象,也就是调用这个方法的对象:

比如:a.equals(b),那这里的a就是当前对象,也就是这个this,b就是Object o 的o 

this == o 这个的作用是判断如果比较的对象和当前对象一致的话,就不需要再比了,直接返回true

o == null 这个的作用是判断传入的对象是否为空,为空直接短路后面的判断,直接返回false

getClass() != o.getClass()这个就比较复制,需要展开来说了

看这一段代码,我试图去将A的属性中的age和name和当前对象进行比较,结果发现直接爆红

这是为什么?

因为age和name是子类(这里的子类相对的父类就是Object),父类不能调用子类私有属性

OK,写道这里肯定会有人说,向下转型就行了。

结果肯定是可以的

不过我们再来看:

 如果我们在外面传了一个list集合,那这样还能判断出来嘛

答案肯定是不能,应该是会报转换类型错误的报错java.lang.ClassCastException

解决办法是什么呢?

就是在向下转型的时候用instanceof关键字判断一下。

所以等我们把上面这些判断都明白了,自然就明白了代码自动给我们生成的getClass() != o.getClass()这段代码。

最后,我们再来说一下 "==" 和 equals的区别

在Java中,==.equals()是两个用于比较的对象运算符,但它们在用途和用法上有所不同:

  1. == 运算符:

    • 用于比较基本数据类型(如int、char等)或引用类型的变量是否指向同一内存地址。
    • 当比较对象时,它检查的是两个对象的引用是否完全相同,即它们在内存中的位置是否一样。
    • 对于字符串和数组,如果两个对象的引用相等,则==返回true,即使它们的内容相同。
  2. .equals() 方法:

    • 这是一个方法,通常由Object类定义,并在所有类中继承,包括String、Integer等引用类型。
    • 对于自定义类的对象,.equals()方法可以根据类的设计意图来判断两个对象的内容是否相等。
    • 在String类中,.equals()默认比较的是字符串的实际内容;而在其他可变类型如ArrayList,通常重写为比较元素内容而非引用。

总结来说,==主要用于直接比较对象的地址,而.equals()则是用来比较对象的内容是否相等。如果你想要比较两个对象的数据值而不是它们的引用,应该使用.equals(),除非你知道你在比较的是不可变类型(比如基本类型或String),在这种情况下,==就足够了。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com