★★★★★★
类 Object 是类层次结构的根类。每个类都使用 Object 作为超类(都直接或间接继承此类)。所有对象(包括数组)都实现这个类的所有方法。
★★★★★★
* Class <code>Object</code> is the root of the class hierarchy.
* Every class has <code>Object</code> as a superclass. All objects,
* including arrays, implement the methods of this class.
★★★★★★
hashCode 的常规协定是:
1.在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
2.如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
3.如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
★★★★★★
equals 与 ==
==号,它比较的是一个对象在内存中的地址值, 比如2个字符串对象 String s1 = new String("str"); String s2 = new String("str"); 如果用==号比较,会返回false,因为创建了两个对象,他们在内存中地址的位置是不一样的。 equals的情况比较复杂,它是java.lang.Object类中的一个方法。因为java中所有的类都默认继承于Object,所以所有的类都有这个方法。 在Object类源码中是这样写的。 public boolean equals(Object obj) { return (this == obj); } 他同样使用==号进行内存地址的比较。但是许多java类中都重写了这个方法,比如String。 public boolean equals(Object anObject) { if (this == anObject) { //先比较内存地址是否相同,相同返回true return true; } if (anObject instanceof String) { //传进来的Obj 是 String类型 String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { //两个串的长度比较 char v1[] = value; char v2[] = anotherString.value; int i = offset; //offset 此处是0 int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) //每个字符再进行比较 这里用的是 != 进行比较 (== !=比较的是地址 有点不理解??) return false; } return true; } } return false; } String里的方法,如果==号比较不相等,还会进行一下值的比较,值相等返回true。 所以equals方法具体的作用要看当前的那个类是如何实现重写父类中该方法的。如果没有重写该方法,那么他和==号等价。★ ★★★★★
equals 与 hashcode
规范1:若重写equals(Object obj)方法,有必要重写hashcode()方法,确保通过equals(Object obj)方法判断结果为true的两个对象具备相等的hashcode()返回值。说得简单点就是:“如果两个对象相同,那么他们的hashcode应该 相等”。不过请注意:这个只是规范,如果你非要写一个类让equals(Object obj)返回true而hashcode()返回两个不相等的值,编译和运行都是不会报错的。不过这样违反了Java规范,程序也就埋下了BUG。
规范2:如果equals(Object obj)返回false,即两个对象“不相同”,并不要求对这两个对象调用hashcode()方法得到两个不相同的数。说的简单点就是:“如果两个对象不相同,他们的hashcode可能相同”。
根据这两个规范,可以得到如下推论:(有点绕 理解理解)
1、如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。
2、如果两个对象不equals,他们的hashcode有可能相等。
3、如果两个对象hashcode相等,他们不一定equals。
4、如果两个对象hashcode不相等,他们一定不equals。
(这是规范 你玩java在人家的地盘玩得遵守别人的 规范 ,不遵守规范程序可能存在不可预知的 Bug)
★★★★★★http://jingyan.baidu.com/article/fedf0737700b3335ac8977ca.html
★★★★★★重写和重载
1) 方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。重载是一个类中多态性的一种表现。
2) Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性。
3) 重载的时候,
方法名要一样,但是参数类型和个数不一样,
返回值类型可以相同也可以不相同。 无法以返回型别作为重载函数的区分标准。
一句话总结重载--- 不能以返回值区分重载方法,而只能以“参数类型和个数”和“方法名”来区分
1)父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。
在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
2) 若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。
3) 子类函数的访问修饰权限不能少于父类的;!!!!!!
★★★★★★
有次参加面试的题目 写出Object类中的至少五个方法。
equals hashcode toString getClass clone
线程相关 wait三个重载的方法 notify notifyAll 垃圾回收 finalize
protected native Object clone() throws CloneNotSupportedException; 创建并返回此对象的一个副本。 public boolean equals(Object obj) 指示其他某个对象是否与此对象“相等”。 protected void finalize() throws Throwable { } 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。 public final native Class<?> getClass(); 返回此 Object 的运行时类。public native int hashCode(); 返回该对象的哈希码值。 public final native void notify(); 唤醒在此对象监视器上等待的单个线程。 public final native void notifyAll(); 唤醒在此对象监视器上等待的所有线程。 public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } 返回该对象的字符串表示。 wait() 在其他线程调用此对象的 notify() 方法或notifyAll() 方法前,导致当前线程等待wait(long timeout) 在其他线程调用此对象的 notify() 方法或notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。wait(long timeout, int nanos) 在其他线程调用此对象的 notify() 方法或notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。 |
---|
★★★★★★
- package java.lang;
- public class Object {
- /* 一个本地方法,具体是用C(C++)在DLL中实现的,然后通过JNI调用。*/
- private static native void registerNatives();
- /* 对象初始化时自动调用此方法*/
- static {
- registerNatives();
- }
- /* 返回此 Object 的运行时类。*/
- public final native Class<?> getClass();
- /*
- hashCode 的常规协定是:
- 1.在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
- 2.如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
- 3.如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
- */
- public native int hashCode();
- public boolean equals(Object obj) {
- return (this == obj);
- }
- /*本地CLONE方法,用于对象的复制。*/
- protected native Object clone() throws CloneNotSupportedException;
- /*返回该对象的字符串表示。非常重要的方法*/
- public String toString() {
- return getClass().getName() + "@" + Integer.toHexString(hashCode());
- }
- /*唤醒在此对象监视器上等待的单个线程。*/
- public final native void notify();
- /*唤醒在此对象监视器上等待的所有线程。*/
- public final native void notifyAll();
- /*在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。
- 当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。*/
- public final void wait() throws InterruptedException {
- wait(0);
- }
- /*在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。*/
- public final native void wait(long timeout) throws InterruptedException;
- /* 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。*/
- public final void wait(long timeout, int nanos) throws InterruptedException {
- if (timeout < 0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
- if (nanos < 0 || nanos > 999999) {
- throw new IllegalArgumentException(
- "nanosecond timeout value out of range");
- }
- if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
- timeout++;
- }
- wait(timeout);
- }
- /*当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。*/
- protected void finalize() throws Throwable { }
- }
return (this == obj);
}
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}