目录
1、Object类
- Object类是所有Java类的根父类 (多层继承中的最高层的父类)
- 如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类
比如:public class Person{ } 等价于:public class Person extends Object{ }
method(Object obj){ } //表示该方法可以接收任何类作为其参数
(当我们想给某个方法设置一个形参参数,可以确定传递的实参一定会是一个类,但不确定会是一个什么类也就是形参的类型不确定,这时候就可以把形参设置为Object类型。)
2、Object类中的主要方法
2.1对象相等判断方法:equals()
该方法比较的是对象是否相等(其实就是比较堆内地址)
class Student
{
String name;
int age;
public Student(String name,int age)
{
this.name=name;
this.age=age;
}
}
public class Text{
public static void main(String[] args)
{
Student s1 = new Student("Mary",21);
Student s2 = new Student("Mary",21);
System.out.println(s1.equals(s2));//输出一个boolean值 false
}
}
输出false表示s1和s2指向的不是同一个对象即他们指向的堆内地址是不同的
(关于equals( )的详细说明在后面的“==”和equals的对比和使用中会具体阐述)
2.2 hashCode()方法
hashCode方法的作用:对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode。在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。
(在集合查找时,hashcode能大大降低对象比较次数,提高查找效率!)
1、hashCode返回的就是对象的存储地址吗?
这种看法是不全面的,确实有些JVM在实现时是直接返回对象的存储地址,但是大多时候并不是这样,只能说可能存储地址有一定关联
2、可以根据hashCode值判断两个对象是否相等吗?
肯定是不可以的,因为不同的对象可能会生成相同的hashcode值。虽然不能根据hashcode值判断两个对象是否相等,但是可以直接根据hashcode值判断两个对象不等,如果两个对象的hashcode值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,必须通过equals方法。也就是说对于两个对象:
- 如果调用equals方法得到的结果为true,则两个对象的hashcode值必定相等;
- 如果equals方法得到的结果为false,则两个对象的hashcode值不一定不同;
- 如果两个对象的hashcode值不等,则equals方法得到的结果必定为false;
- 如果两个对象的hashcode值相等,则equals方法得到的结果未知。
3、在有些情况下,在设计一个类的时候需要重写equals方法,但是千万要注意,在重写equals方法的同时也要重写hashCode方法。(比如在String类中就已经重写了这两个方法)
public class test01 {
public static void main(String[] args)
{
String s1 = new String("aaa");
String s2 = new String("aaa");
System.out.println(s1.equals(s2));
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
}
}
输出结果:
true
96321
96321
下面为一个实例:
import java.util.HashSet;
import java.util.Iterator;
class Student {
int num;
String name;
Student(int num, String name) {
this.num = num;
this.name = name;
}
public String toString() {
return num + ":" + name;
}
}
public class test01 {
public static void main(String[] args) {
HashSet<Student> hs = new HashSet();
hs.add(new Student(1, "zhangsan"));
hs.add(new Student(2, "lisi"));
hs.add(new Student(3, "wangwu"));
hs.add(new Student(1, "zhangsan"));
Iterator it = hs.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
运行结果:
3:wangwu
1:zhangsan
2:lisi
1:zhangsan
思考: 为什么hashset添加了相等的元素呢,这是不是和hashset的原则违背了呢?回答是:没有。因为在根据hashcode()对两次建立的new Student(1,“zhangsan”)对象进行比较时,生成的是不同的哈希码值,所以hashset把他当作不同的对象对待了,当然此时的equals()方法返回的值也不等。
为什么会生成不同的哈希码值呢?上面我们在比较s1和s2的时候不是生成了同样的哈希码吗?原因就在于我们自己写的Student类并没有重写自己的hashcode()和equals()方法,所以在比较时,是继承的object类中的hashcode()方法,而object类中的hashcode()方法是一个本地方法,比较的是对象的地址(引用地址),使用new方法创建对象,两次生成的当然是不同的对象了,造成的结果就是两个对象的hashcode()返回的值不一样,所以Hashset会把它们当作不同的对象对待。
解决途径:在Student类中重写hashCode()和equals方法——>
import java.util.HashSet;
import java.util.Iterator;
class Student {
int num;
String name;
Student(int num, String name) {
this.num = num;
this.name = name;
}
public int hashCode() {
return num * name.hashCode();
}
public boolean equals(Object o) {
Student s = (Student) o;
return num == s.num && name.equals(s.name);
}
public String toString() {
return num + ":" + name;
}
}
public class test01 {
public static void main(String[] args) {
HashSet<Student> hs = new HashSet();
hs.add(new Student(1, "zhangsan"));
hs.add(new Student(2, "lisi"));
hs.add(new Student(3, "wangwu"));
hs.add(new Student(1, "zhangsan"));
Iterator it = hs.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
运行结果:
3:wangwu
2:lisi
1:zhangsan
2.3取得对象信息的方法:toString()
该方法在打印对象时被调用,将对象信息变为字符串返回,默认输出对象地址。
package zhukun;
import java.util.HashSet;
import java.util.Iterator;
class Student {
int age=20;
String name = "zhukun";
}
public class test01 {
public static void main(String[] args) {
Student s = new Student();
System.out.println("姓名:"+s.name+"年龄:"+s.age);//输出对象属性
System.out.println(s);//直接输出对象信息
System.out.println(s.toString());//调用父类方法输出对象信息
}
}
运行结果:
姓名:zhukun年龄:20
zhukun.Student@15db9742
zhukun.Student@15db9742
上述结果看出编译器默认调用toString()方法输出对象,但输出的是对象的地址,我们并不能看懂它的意思。那么就要通过重写Object类的toString()方法来输出对象属性信息。
重写toString方法:
package zhukun;
import java.util.HashSet;
import java.util.Iterator;
class Student {
int age=20;
String name = "zhukun";
public String toString()
{
return "姓名:"+name+",年龄:"+age;
}
}
public class test01 {
public static void main(String[] args) {
Student s = new Student();
System.out.println("姓名:"+s.name+"年龄:"+s.age);//输出对象属性
System.out.println(s);//直接输出对象信息
System.out.println(s.toString());//调用父类方法输出对象信息
}
}
运行结果:
姓名:zhukun年龄:20
姓名:zhukun,年龄:20
姓名:zhukun,年龄:20
4、instanceof操作符
x instanceof A:检验x是否为类A的对象,返回值为boolean型
- 要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
- 如果x属于类A的子类B,x instanceof A 的值也为true。
(就是检验某个对象是不是类A的子类)