@[toc]
Object类
Object类 即 java.lang.Object类 是所有类的直接或间接父类
- Object类是所有Java类的根父类。
- 如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object。
- Object类中的功能(方法)具有通用性(属性无)。原因:Object类是所有类的直接或间接父类。
方法:equals() / toString() / getClass() / hashCode() / clone() / finalize() / wait() / notify() / notifyAll()
- Object类只声明了一个空参的构造器。
Object类中的equals()方法
回顾 == 的使用
== :运算符
- 可以使用在
基本数据类型
和引用数据类型
变量中。(范围问题) - 如果比较的是
基本数据类型
变量:比较两个变量保存的数据是否相等。(数据类型不用必须相同,只要不是布尔类型,其他七大类型都能比较)
如果比较的是引用数据类型
变量:比较两个对象的地址值
是否相同。即两个引用是否指向同一个对象实体。
补充:== 符号使用时,必须保证符号左右两边的变量类型一致,如果不一致编译都报错(对于基本数据类型,变量类型一致指:不带布尔类型的其他七大类型。对于引用类型,类型一致:类相同。举例:String和Date就不能\=\=比较,因为类型不一致)。
equals()方法的使用
- 是一个方法,而非运算符(所以基本数据类型变量不能用,总不能 int i = 10;int j = 20;i.equals(j)吧,这太离谱了,只有对象才能用方法!)。
- 只能适用于引用数据类型(就是上面说的)。
- Object类中equals()的定义:
public boolean equals ( Object obj ) {
return (this == obj) ;
}
说明:Object类中定义的 equals() 和 == 的作用是相同的,即对于引用数据类型,比较两个对象的地址值是否相同(两个引用是否指向同一个对象实体)。
- 像String、Date、File、包装类等都
重写
了Object类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的属性是否相同。(属性就是创建对象时给构造器传的参数) - 通常情况下,我们自定义的类如果想使用equals()的话,目标通常也是比较两个对象的属性是否相同。那么,我们就需要对Object类中的equals()进行重写。
重写的原则:比较两个对象的属性是否相同。
练习
import java.sql.Date;
public class EqualsTest {
public static void main(String[] args) {
//基本数据类型
int i = 10;
int j = 10;
double d = 10.0;
System.out.println(i == j); // true int和int比属于,相等返回true很正常
System.out.println(i == d); // true int和double比,会自动类型提升
// 只要是除布尔外的其他七大数据类型,都能比较
// boolean b =true;
// System.out.println(i == b);这里编译都会出错,因为比较基本数据类型时,不能把布尔类型
// 和其他类型比
char c = 10; // 把ASCII码为10的字符赋值给了c,c字符的ASCII码就是10
System.out.println(i == c); //true比较时,c先进行了类型转换,字符转了ASCII码再和i比较
// 有点像一斤棉花和一斤铁谁重的问题
char c1 = 'A';
char c2 = 65;
System.out.println(c1 == c2); // true 跟上面一样,字符和ASCII码会自动转换
//引用数据类型
Customer cust1 = new Customer("Tom" ,21);
Customer cust2 = new Customer("Tom" ,21);
System.out.println(cust1 == cust2); // false ==比的是地址,new了两次肯定是不同的地址
String str1 = new String("BAT");
String str2 = new String("BAT");
System.out.println(str1 == str2); // false 地址不同
// false 自定义类没重写equals()前,equals()和 == 一样( equals()就是== )
System.out.println(cust1.equals(cust2));
//true String类在源码中已经重写好了equals()方法,比较的就是对象的属性是否相等
System.out.println(str1.equals(str2));
Date date1 = new Date(23432525324L);
Date date2 = new Date(23432525324L);
System.out.println(date1.equals(date2)); //true 对象属性相同
}
}
面试题:==和equals()的区别
- == 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址。
- equals() 属于java.lang.Object类里面的方法,如果该方法没有被重写过,则默认也是 == ;
String、Date等类的equals()方法已经被重写在源码里了,所以我们不用重写就直接能用来比较值。
- ==和equals()的执行结果,具体要看自定义类里有没有重写Object的equals()方法来判断。
- 通常情况下,重写equals()方法的目的是比较类中的相应属性是否都相等。
重写equals()方法的原则
- 对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
- 自反性:x.equals(x)必须返回是“true”。
- 传递性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。
- 一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管重复x.equals(y)多少次,返回都是“true”。
- 任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。
Object类中的toString()方法
- toString方法在
Object类
中定义,其返回值是String类型,返回类名和它的引用地址。
返回值:包名.类名.地址
例:封装继承多态.面向对象中最后一点内容.GeometricObject@5cad8086
- 在进行String与其他类型数据的连接时,自动调用toString()方法
Date now = new Date();
System.out.println("now="+now); // 相当于下面
System.out.println("now="+now.toString());
- 可以根据需要在用户自定义类型中重写toString()方法
如String类的源码重写了toString()方法,返回字符串的值。
s1 = "hello";
System.out.println(s1); // 相当于System.out.println(s1.toString()); 都是输出"hello"
- 基本类型数据转换为String类型时,调用了对应包装类的toString()方法
int a = 10;
System.out.println("a="+a);
toString()方法的使用
- 当我们输出一个对象的引用时,实际上就是调用当前对象的toString()方法。
- Object类中toString()的定义:
public String toString () {
return getClass().getName() + "@" + Integer.toHexString(hashCode()) ;
}
- 像String、Date、File、包装类等都重写了Object类中的toString()方法。
使得在调用对象的toString()时,返回属性信息。
- 自定义类也可以重写toString()方法,当调用此方法时,返回对象的属性。
总结:
当我们想 System.out.println(自定义类的对象);输出的是属性值而非地址时,就需要重写toString()方法。
包装类(Wrapper)的使用
- 针对八种基本数据类型定义相应的引用类型——包装类
- 有了类的特点,就可以调用类中的方法
基本类型、包装类与String类间的转换
基本类型和包装类之间的转换
只用记住自动装箱和自动拆箱
//自动装箱:基本数据类型 --> 包装类
int num1 = 10;
Integer in1 = num1; // int --> Integer
boolean b1 = true;
Boolean b2 = b1; // boolean --> Boolean
//自动拆箱:包装类 --> 基本数据类型
int num2 = in1; // Integer --> int
基本数据类型、包装类转换到String类型
无论是基本数据类型还是包装类,都调用String类重载的valueOf(Xxx xxx)方法,即String.valueOf(Xxx xxx)
float f1 = 12.3f;
String str1 = String.valueOf(f1); // "12.3" float --> String
Double d1 = new Double(12.4);
String str2 = String.valueOf(d1); // "12.4" Double --> String
String类型转换到基本数据类型、包装类
调用相应的包装类的parseXxx(String)
静态方法
String str1 = "123";
// String str1 = "123a"; 这样是无论如何都转不成功的
//错误的情况,会报错,不能String直接强制类型转换为基本类型或包装类
// int num1 = (int)str1;
// Integer in1 = (Integer)str1;
int num2 = Integer.parseInt(str1); // 转为int类型,就Integer.parseInt()
System.out.println(num2 + 1); // 124 转换成功
String str2 = "true";
Boolean b1 = Boolean.parseBoolean(str2); // 转为Boolean包装类,就Boolean.parseBoolean()
System.out.println(b1); // true