一、Object类介绍 点击此处返回总目录 1. Object类在lang包中,lang包是java的核心包。使用这个包中的类时不需要import。 2. Object类是所有类的父类。他没有父类。所有类都是他的子类。 Object类有构造方法,构造方法是空参的,构造方法的第一行不是super()。其他类的构造方法的第一行都是super(),就它不是。 3. 问题:接口是不是也继承Object?接口中的方法都是抽象的,但是构造方法不能是抽象的,所以接口中没有构造方法。也就是说接口 中没有访问父类构造器的过程,所以接口不继承Object。 二、Object类的常用方法(参考API文档) 1 boolean equals(Object obj) //指示其他某个对象是否与此对象相等。参数是Object类型,说明任何对象都可以传。 2 String toString() //返回该对象的字符串表示 1. euqals()方法 注意:每一个类都继承了Object类中的equals方法。打开源码,可以看到Object类中的equals方法的实现如下: public boolean equals(Object obj){ return (this == obj); //对于引用数据类型,"=="比较的是对象的内存地址。所以equals()比较的是对象地址是否相同。 } 例子1:equals()的使用 //Person.java
package cn.itcast.demo01; public class Person { private String name; private int age; public Person(){} public Person(String name, int age) { 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; } } |
//Test.java
package cn.itcast.demo01; public class Test { public static void main(String[] args) { Person p1 = new Person("zhangsan",24); Person p2 = p1; p1.setAge(22); System.out.println(p2.getAge()); //22。说明p1和p2是指向的是同一个对象。因此P1、P2两个对象(同一对象)地址相同。 System.out.println(p1.equals(p2)); //true。在引用数据类型中,"=="比较的是对象的内存地址。equals()方法的内部实现就 是"==",所以比较的是p1和p2的内存地址。所以为true。 } } |
例2:equals()的使用 //Person.java
package cn.itcast.demo01; public class Person { private String name; private int age; public Person(){} public Person(String name, int age) { 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; } } |
//Test.java
package cn.itcast.demo01; public class Test { public static void main(String[] args) { Person p1 = new Person("zhangsan",24); Person p2 = p1; Person p3 = new Person("lisi",25); System.out.println(p1.equals(p3)); //false。p1、p3都是new出来的,内存地址肯定不同。 System.out.println(p1.equals(p2)); //true。根据上一个例子可知,p1、p2是同一个对象。 } } |
例3:重写equals()方法:比较变量,不再比较地址。 很多时候,比较地址意义不大,所以希望重写equals()方法,使两个对象按自己的定义来做比较。比如,Person类中,自己定义equals()方法,不再是比较地址,而是比较两个Person对象的年龄。 //Person.java
package cn.itcast.demo01; public class Person { private String name; private int age; public Person(){} public Person(String name, int age) { this.name = name; this.age = age; } public boolean equals(Object obj){ //重写equals方法。 Person p = (Person)obj; //obj向下转型。 if(this.age == p.age){ return true; }else{ return false; } } 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; } } |
//Test.java
package cn.itcast.demo01; public class Test { public static void main(String[] args) { Person p1 = new Person("zhangsan",24); Person p2 = p1; Person p3 = new Person("lisi",25); Person p4 = new Person("wangwu",24); System.out.println(p1.equals(p3)); //false。 System.out.println(p1.equals(p2)); //true。 System.out.println(p1.equals(p4)); //true。说明比较的是年龄。 } } |
改进:上面的例子中传入的参数是Object类,什么都可以往里传。传进去之后再通过 Person p = (Person)obj; 语句强转。但是这里有一个问题,就是,如果传进去的对象不能转成Person,那就出错了。比如传进去一个ArrayList,就转不成Person。 所以做如下改进:对方法进行健壮性判断。 //Person.java
package cn.itcast.demo01; public class Person { private String name; private int age; public Person(){ } public Person(String name, int age) { this.name = name; this.age = age; } public boolean equals(Object obj){ if(obj instanceof Person == false){ //先进行健壮性判断。如果obj是Person类型,才转 return false; } Person p = (Person)obj; //obj向下转型。 if(this.age == p.age){ return true; }else{ return false; } } 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; } } |
//Test.java
package cn.itcast.demo01; import java.util.ArrayList; public class Test { public static void main(String[] args) { Person p1 = new Person("zhangsan",24); ArrayList<String> arr = new ArrayList<>(); System.out.println(p1.equals(arr)); //false。说明可以比较了。 } } |
继续改进:虽然通过上面的改进,传进去的参数是一个其他的对象时,不会报错。但是也可能传进去null,这个时候就不需要判断了。 所以可以进行非空判断。另外,如果传进去的是自己,那也没有必要判断了。 //Person.java
package cn.itcast.demo01; public class Person { private String name; private int age; public Person(){ } public Person(String name, int age) { this.name = name; this.age = age; } public boolean equals(Object obj){ if(null == obj){ //可以不写,为了提高执行效率。 return false; } if(obj == this){ //可以不写,为了提高效率。自己跟自己不用比。 return true; } if(obj instanceof Person){ //先进行健壮性判断。如果obj是Person类型,才转 Person p = (Person)obj; //obj向下转型。 return this.age == p.age; }else{ return false; } } 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; } } |
//Test.java
package cn.itcast.demo01; import java.util.ArrayList; public class Test { public static void main(String[] args) { Person p1 = new Person("zhangsan",24); Person p2 = new Person("lisi",24); ArrayList<String> arr = new ArrayList<>(); System.out.println(p1.equals(p1)); //true。自己跟自己比,直接返回true。 System.out.println(p1.equals(null)); //false。跟空比,直接返回false。 System.out.println(p1.equals(arr)); //false。跟不是Person的队相比。直接返回false。 System.out.println(p1.equals(p2)); //true。比较年龄。 } } |
2. toString()方法 注意:1. toString()方法得到的是对象的内存地址。 2. System.out.println()的参数如果写的是一个对象的话,则默认会调用对象的toString()方法。即:System.out.println(p1); 等价 于System.out.println(p1.toString()); 例子1:toString()的使用 //Person.java
package cn.itcast.demo01; public class Person { private String name; private int age; public Person(){ } public Person(String name, int age) { 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; } } |
//Test.java
package cn.itcast.demo01; import java.util.ArrayList; public class Test { public static void main(String[] args) { Person p1 = new Person("zhangsan",24); String s = p1.toString(); System.out.println(p1); //cn.itcast.demo01.Person@19bb25a。 System.out.println(s); //cn.itcast.demo01.Person@19bb25a。不管运行多少次,两条语句的运行结果都是一样的。因为 输出语句(System.out.println())的参数如果写的是一个对象的话,则默认会调用对象toString() 方法。所以这两行结果相同。即:System.out.println(p1); 等价于System.out.println(p1.toString()); //p1.toString()的结果是内存地址。 } } |
例2:重写toString()方法。 因为toString()方法得到的是内存地址,所以没什么太多意义。所以希望重写toString()方法。 //Person.java
package cn.itcast.demo01; public class Person { private String name; private int age; public Person(){ } public Person(String name, int age) { this.name = name; this.age = age; } public String toString(){ //重写toString()方法。 return this.name + this.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; } } |
//Test.java
package cn.itcast.demo01; import java.util.ArrayList; public class Test { public static void main(String[] args) { Person p1 = new Person("zhangsan",24); String s = p1.toString(); System.out.println(p1); //zhangsan24。输出p1相当于输出p1.toString()。 System.out.println(p1.toString()); //zhangsan24 } } |
|