Object类是所有类的始祖,在java中每个类都是由它扩展得到的,但是并不需要这样写
public class Employee extdens Object
在新建一个类时我们可以看到
如果没有明确地指出超类,Object就会被认为是这个类的超类,可以使用Object类型的变量引用任何类型的对象:
Object obj = new Employee("小明",2000);
Object类型的变量只能用于作为各种值的通用持有者,想要对其进行具体操作,还需要知道对象的原始数据类型,并进行相应的类型转换:
Employee e = (Employee)obj;
在java中,只有基本类型不是对象,例如数值,字符,布尔类型。而所有的数组类型,对象数组,基本类型数组都扩展了Object类:
Employee[] staff = new Employee[10];
obj = staff
obj = new int[10];
Object类中的equals方法用于检测一个对象是否等于另外一个对象。在Object类中,这个方法将判断俩个对象是否具有相同的引用,如果俩个对象具有相同的引用,他们一定是相等的。下面是Object类中equals方法源码:
* @param obj the reference object with which to compare.
* @return {@code true} if this object is the same as the obj
* argument; {@code false} otherwise.
* @see #hashCode()
* @see java.util.HashMap
*/
public boolean equals(Object obj) {
return (this == obj);
}
Object类里的equals方法直接判断equals对象与obj所引用的对象是否相同,来一波操作(这里的equals方法已被String类重写了),看看equals方法与“ == ”运算符的区别:
int n=1,m=1;
String a = new String("小明");
String b = new String("小明");
String c = "小马";
String d = "小马";
System.out.println(n==m); //true
System.out.println(n.equals(m));//错误
System.out.println(a==b); //false
System.out.println(a.equals(b));//true
System.out.println(c==d); //true
System.out.println(c.equals(d)) //true
n与m的比较可知,equals不能用于基本类型,为什么a,b的比较结果和c,d的比较结果不一样?我们来看一下java内存划分:
栈区:每调用一个方法会创建一个栈帧,存放局部变量,堆区:存放new出来的对象,此对象由垃圾收集器收集。还有个方法区包含类的所有信息。
//n与m比较的是值
System.out.println(n==m); //true
System.out.println(n.equals(m));//错误
//a与b的地址不一样
System.out.println(a==b); //false
//a与b的对象引用一样
System.out.println(a.equals(b));//true
//c与d的地址相同
System.out.println(c==d); //true
//c与d的地址相同
System.out.println(c.equals(d)) //true
散列码是由对象导出的一个整型数值,散列码是没有规律的,如果a和b是不同的两个对象,那么a.hashCode()和b.hashCode()基本不会相同。下面是String类使用的hashCode方法:
int hash=0;
for(int i=0; i<length ;i++)
hash =31*hash+charAt(i);
hashCode方法定义在Object类中,因此每个对象都有一个默认的散列码,其值为对象的储存地址,看个例子:
String s = "OK";
StringBuilder sa = new StringBuilder(s);
System.out.println(s.hashCode()+" "sa.hashCode);
String t = new String("OK");
StringBuilder ta = new StringBuilder(t);
System.out.println(s.hashCode()+" "sa.hashCode);
输出:2556 20526976
2556 20527411
s与t是String类的对象,散列码由字符串的内容导出的,所以相同。而sa与ta的散列码不同,是因为StringBuilder类里没有定义hashCode()方法,其散列码由Object类默认hashCode()方法导出的对象地址。
如果重新定义equals方法,就必须重新定义hashCode方法,以便用户将对象插入到散列表中。还有如果x.equals(y)返回true,那么x.hashCode()就必须和y.hashCode具有相同的值,反过来,如果x和y的散列码一样,x.equals(y)不一定返回true.
也是Object类里比较重要的类,用于返回对象值的字符串,绝大部分类的 toString 类遵循这样的格式:类的名字,随后就是一对方括号括起来的预值。
public String toString(){
return "Student[name="+name+"]";
}
如果x是任意对象,直接打印x,println方法会自动调用x.toString方法得到字符串。
Student x = new Student("小明");
System.out.println("x")
//输出
//Student[小明]
数组也继承了Object类的toString方法,在调用x.toString()的地方可以用 “”+x 替代,这里的x就是x.toString()
int[] a ={1,2,3};
String s = ""+a;
String s = Arrays.toString(a);
//将生成字符串 [1,2,3]