是所有类的父类,java中的顶级父类,所有类默认继承object类。
这个时候可能会又一个问题
class c{ } class B extends c{ }
java类与类之间是单继承的,而所有类默认继承Object ,那么上面 B就是又继承Object也继承C,那不就不满足java类与类之间的单继承机制?
答:java支持多级继承,如果不显示继承如C那么它就默认继承Object,如果显示继承如B那么其父类C也是默认继承Object 从而B就构成了多级继承Object。
1.clone()----返回的是拷贝了原空间所有信息的堆内存新空间 在进行克隆对象之前,需要让对象对应的类实现Cloneable接口,这个接口
仅仅只是用于可以做克隆操作的标记
public class ObjectDemo implements Cloneable{ int i=1; public static void main(String[] args) throws CloneNotSupportedException { ObjectDemo o1=new ObjectDemo();//相当于向上造型 // java.lang.CloneNotSupportedException ------克隆不支持异常 //对象对应的类需要实现Clonezble接口才能支持克隆 //Cloneable接口仅仅只是提供了一个标记,实现这个接口就能支持克隆 ObjectDemo o2=(ObjectDemo)o1.clone(); //向下造型 //克隆对象调用属性 System.out.println(o2.i); } }
system.out.println(o1==o2);//false 比较地址值发现不等
所以克隆对象是开辟一块新空间,这个空间复制了原空间的所有信息,而不是新创建了一个对象同时指向同一块区域。
2.finalize()---当垃圾收集确定没有对对象的引用时,由对象上的垃圾收集器调用。 及通知GC回收堆内存,这个方法的效果个System.gc()一致,两者的区别是finalize()是对象调用的,而System.gc()是类调用的
3.getclass()--获取的是Object运行时类及返回的是对象的实际创建类
public static void main(String[] args) { //创建对象 Cart c1=new Cart(); System.out.println(c1.getClass());//class cn.java.Api.Cart Object c2=new Cart();//向上转型 System.out.println(c2.getClass());//class cn.java.Api.Cart //两者是一样的所以getclass 获取的是对象的实际创建类 }
4.hashCode --------返回一个对象的哈希代码值(十进制) int 数据类型修饰的
//返回的是十进制的值,而在地址中存储的是十六进制的值 System.out.println(new Object().hashCode()); //十进制转成16进制 System.out.println(Integer.toHexString(new Object().hashCode()));
哈希码值没有负数,最大的取值范围是int的正数范围的两倍,取值范围很广
哈希码值是散列分布的,就是40个数随机得到的哈希码值
由于哈希码值范围广,散列,所有数据重复的概率基本为0 所以哈希码值一般是唯一的,地址值也是唯一的,所以把哈希码值当成一部分地址值
5.tostring() 返回的是一个字符串 默认是进行拼接对象地址值 开发中常用的是类中重写Object中的toString方法进行数据拼接
-
此方法返回一个等于值的字符串:
getClass().getName() + '@' + Integer.toHexString(hashCode())
System.out.println(new Object().toString());//java.lang.Object@7852e922 返回的是object引用类型的地址值 System.out.println(new Object() //这个也是输出地址java.lang.Object@7f690630
那么为什么这两句话都是输出的是对象地址值?问题主要出现在println身上,我们转到println的源码
首先是
System.out.println(new Object().toString()); 这句代码的println转到方法是
这个只是打印和换行
System.out.println(new Object();这句代码的println转到方法是
valueof在转进去就会发现
底层如果是引用类型且不为null 那么println方法会让od对象调用object里的toString方法
我们一般让类重写toString()方法 来把属性拼接起来,从而方便我们查看对象的传值
我们可以采用java提供的tostring 重写方法 sourse--> tostring()
6.equal 指示是否有其他对象"等于"这个
默认的比较就是地址值的比较,地址值相等就是true,地址值不等就是false
public static void main(String[] args) { Person p1=new Person(); Person P2=new Person(); //判断两个对象是否相等-----其实是判断地址值是否相等 System.out.println(p1.equals(P2)); //false } } class Person{ String nameString; int age; char gender; }
那么问题来了,如果地址值不等就是false,那么如果我两个对象的属性值都相等的话我想这两个对象也是相等的,所以这个时候就要重写默认equals方法
equals() 是Object类里的方法用于判断两个对象是否相等(地址值是否相等) 重写equals方法(1.判断地址值是否相等
2.判断参数是否为null 3.判断对象类型是否一致 4.比较参数是否相等
class Person{ String name; int age; char gender; @Override public boolean equals(Object obj) { //1.比较两个对象的地址值是否相等 if(this==obj) { //p1==p2 return true; } //2.判断对象是否为null if(obj==null) { return false; } //3.判断是否比较的都是Person类的对象,两个比较的对象类型一致 if(this.getClass()!=obj.getClass()) { return false; } //把object参数类型强制转换到Person类型才能调用到Person属性 Person p=(Person)obj; //4.判断两个对象的属性是否相等 if(this.age!=p.age||this.gender!=p.gender) { return false; } //name是string类型,所以要判断name的地址值是否相等 //this.name.equals(p.name)中的this.name是String类型,调用的equals是String类重写的 //这个equals方法先去比较地址是否相等再去比较字符串内容是否一致
//this.name为null ,再this.name.equals(p.name) ,空的对象点个东西就会报空指针异常
//为啥要多比较地址值是否为null 是为了防止this.name=null和p.name=null的现象,这个现象的答案应该是true ||和&&一起,||会短路掉&&
if(this.name==p.name||this.name!=null&&this.name.equals(p.name)) //引用类型的==比较就是比较地址值 { return true; } //地址值属性值都不相等 return false; } }
this.name.equals(p.name)这个equals方法先去比较地址是否相等再去比较字符串内容是否一致,调用的是String的equals重写方法
//String重写Object equals方法
public boolean equals(Object anObject) { if (this == anObject) { //调用对象与比较对象地址值是否相等,如果相等那么两个对象指向的String内存空间是一样的,就是同一个字符串 return true; } if (anObject instanceof String) { //首先看比较对象是不是String的实例,如果不是的话就是不同类型对象的比较那么字符串一定不等同 String anotherString = (String)anObject; //强制类型转换方便调用String的方法比较 int n = value.length; //value是一个char[]数组的属性 if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) //两个char[]依次逐个比较,不等返回false return false; i++; } return true; } } return false; }