网站建设网址导航网,利用网盘 建网站,网站建设连接,针对餐饮公司推广做网站方法Object类是Java中其他所有类的祖先#xff0c;没有Object类Java面向对象无从谈起。作为其他所有类的基类#xff0c;Object具有哪些属性和行为#xff0c;是Java语言设计背后的思维体现。 Object类位于java.lang包中#xff0c;java.lang包包含着Java最基础和核心的类… Object类是Java中其他所有类的祖先没有Object类Java面向对象无从谈起。作为其他所有类的基类Object具有哪些属性和行为是Java语言设计背后的思维体现。 Object类位于java.lang包中java.lang包包含着Java最基础和核心的类在编译时会自动导入。Object类没有定义属性一共有13个方法:
1、类构造器public Object();
大部分情况下Java中通过形如 new A(args…)形式创建一个属于该类型的对象。其中A即是类名A(args…)即此类定义中相对应的构造函数。通过此种形式创建的对象都是通过类中的构造函数完成。为体现此特性Java中规定在类定义过程中对于未定义构造函数的类默认会有一个无参数的构造函数作为所有类的基类Object类自然要反映出此特性在源码中未给出Object类构造函数定义但实际上此构造函数是存在的。
当然并不是所有的类都是通过此种方式去构建也自然的并不是所有的类构造函数都是public。
2、private static native void registerNatives();
registerNatives函数前面有native关键字修饰Java中用native关键字修饰的函数表明该方法的实现并不是在Java中去完成而是由C/C去完成并被编译成了.dll由Java去调用。方法的具体实现体在dll文件中对于不同平台其具体实现应该有所不同。用native修饰即表示操作系统需要提供此方法Java本身需要使用。具体到registerNatives()方法本身其主要作用是将C/C中的方法映射到Java中的native方法实现方法命名的解耦。
既然如此可能有人会问registerNatives()修饰符为private且并没有执行作用何以达到其实在Java源码中此方法的声明后有紧接着一段静态代码块
1 private static native void registerNatives();
2 static {
3 registerNatives();
4 }3、protected native Object clone() throws CloneNotSupportedException;
clone()方法又是一个被声明为native的方法因此我们知道了clone()方法并不是Java的原生方法具体的实现是有C/C完成的。clone英文翻译为克隆其目的是创建并返回此对象的一个副本而克隆出来的副本与原来的对象没有任何关系的。Java术语表述为clone函数返回的是一个引用指向的是新的clone出来的对象此对象与原对象分别占用不同的堆空间。
4、public final native Class? getClass();
getClass()也是一个native方法返回的是此Object对象的类对象/运行时类对象Class?。效果与Object.class相同。
首先解释下类对象的概念在Java中类是是对具有一组相同特征或行为的实例的抽象并进行描述对象则是此类所描述的特征或行为的具体实例。作为概念层次的类其本身也具有某些共同的特性如都具有类名称、由类加载器去加载都具有包具有父类属性和方法等。于是Java中有专门定义了一个类Class去描述其他类所具有的这些特性因此从此角度去看类本身也都是属于Class类的对象。为与经常意义上的对象相区分在此称之为类对象。
5、public boolean equals(Object obj);
Object类中关于equals()方法的定义
1 public boolean equals(Object obj) {
2 return (this obj);
3 }由此可见Object原生的equals()方法内部调用的正是与具有相同的含义。既然如此为什么还要定义此equals()方法
equlas()方法的正确理解应该是判断两个对象是否相等。那么判断对象相等的标尺又是什么
如上在object类中此标尺即为。当然这个标尺不是固定的其他类中可以按照实际的需要对此标尺含义进行重定义。如String类中则是依据字符串内容是否相等来重定义了此标尺含义。如此可以增加类的功能型和实际编码的灵活性。当然了如果自定义的类没有重写equals()方法来重新定义此标尺那么默认的将是其父类的equals()直到object基类。
6、public native int hashCode();
hashCode()方法返回一个整形数值表示该对象的哈希码值。
hashCode()具有如下约定
1).在Java应用程序程序执行期间对于同一对象多次调用hashCode()方法时其返回的哈希码是相同的前提是将对象进行equals比较时所用的标尺信息未做修改。在Java应用程序的一次执行到另外一次执行同一对象的hashCode()返回的哈希码无须保持一致
2).如果两个对象相等依据调用equals()方法那么这两个对象调用hashCode()返回的哈希码也必须相等
3).反之两个对象调用hasCode()返回的哈希码相等这两个对象不一定相等。
即严格的数学逻辑表示为 两个对象相等 equals()相等 hashCode()相等。因此重写equlas()方法必须重写hashCode()方法以保证此逻辑严格成立同时可以推理出hasCode()不相等 equals不相等 两个对象不相等。
可能有人在此产生疑问既然比较两个对象是否相等的唯一条件也是冲要条件是equals那么为什么还要弄出一个hashCode()并且进行如此约定弄得这么麻烦
其实这主要体现在hashCode()方法的作用上其主要用于增强哈希表的性能。
以集合类中以Set为例当新加一个对象时需要判断现有集合中是否已经存在与此对象相等的对象如果没有hashCode()方法需要将Set进行一次遍历并逐一用equals()方法判断两个对象是否相等此种算法时间复杂度为o(n)。通过借助于hasCode方法先计算出即将新加入对象的哈希码然后根据哈希算法计算出此对象的位置直接判断此位置上是否已有对象即可。注Set的底层用的是Map的原理实现
在此需要纠正一个理解上的误区对象的hashCode()返回的不是对象所在的物理内存地址。甚至也不一定是对象的逻辑地址hashCode()相同的两个对象不一定相等换言之不相等的两个对象hashCode()返回的哈希码可能相同。
7、public String toString();
toString()方法返回该对象的字符串表示。先看一下Object中的具体方法体
1 public String toString() {
2 return getClass().getName() Integer.toHexString(hashCode());
3 }toString()方法我们会经常用到即使没有显式调用但当我们使用System.out.println(obj)时其内部也是通过toString()来实现的
toString()是由对象的类型和其哈希码唯一确定同一类型但不相等的两个对象分别调用toString()方法返回的结果可能相同。
8/9/10/11/12、wait(…) / notify() / notifyAll()
wait()、notify/notifyAll() 方法是Object的本地final方法无法被重写。这几个方法主要用于java多线程之间的协作.
wait()调用此方法所在的当前线程等待直到在其他线程上调用此方法的主调某一对象的notify()/notifyAll()方法。
notify/notifyAll() 的执行只是唤醒沉睡的线程而不会立即释放锁锁的释放要看代码块的具体执行情况。
wait(long timeout)/wait(long timeout, int nanos)调用此方法所在的当前线程等待直到在其他线程上调用此方法的主调某一对象的notisfy()/notisfyAll()方法或超过指定的超时时间量。
notify()/notifyAll()唤醒在此对象监视器上等待的单个线程/所有线程。
wait(…) / notify() | notifyAll()一般情况下都是配套使用。
13、protected void finalize();
finalize方法主要与Java垃圾回收机制有关。首先我们看一下finalized方法在Object中的具体定义
1 protected void finalize() throws Throwable { }我们发现Object类中finalize方法被定义成一个空方法为什么要如此定义呢finalize方法的调用时机是怎么样的呢
首先Object中定义finalize方法表明Java中每一个对象都将具有finalize这种行为其具体调用时机在JVM准备对此对形象所占用的内存空间进行垃圾回收前将被调用。由此可以看出此方法并不是由我们主动去调用的虽然可以主动去调用此时与其他自定义方法无异。