目录


1、Object类

  1. Object类是所有Java类的根父类  (多层继承中的最高层的父类)
  2. 如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类

比如:public class Person{        } 等价于:public class Person extends Object{   }

method(Object obj){   }   //表示该方法可以接收任何类作为其参数

(当我们想给某个方法设置一个形参参数,可以确定传递的实参一定会是一个类,但不确定会是一个什么类也就是形参的类型不确定,这时候就可以把形参设置为Object类型。)

2、Object类中的主要方法

Java学习-详谈最高层父类-Object类-LMLPHP

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的子类

08-31 12:23