您的位置:首页 > 移动开发 > Objective-C

Object 的所有方法

2016-03-03 00:00 615 查看
摘要: Object所有方法的总结

public class Object {

private static native void registerNatives();
static {
registerNatives();
}
public final native Class<?> getClass();
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
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();
public final native void wait(long timeout) throws InterruptedException;
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);
}
public final void wait() throws InterruptedException {
wait(0);
}
protected void finalize() throws Throwable { }
}


其实很多时候我们都忽略了一个类就是Object类,甚至连源码都没有看过,但是它在java体系中却扮演着重要的角色。Object是一切类的父类。这句话就可以知道它的地位了,接下来介绍Object中每个方法的作用。

native void registerNatives()//方法


带有native的都是java 本地方法,java 的可移植性基本上都是他们的功劳。

public final native Class<?> getClass();


这个是返回运行时Object的类,以便程序通过反射获取实例具体例子是 Number n = 0; Class<? extends Number> c = n.getClass();

public native int hashCode();


哈希码,这个作用一般是是在HashMap中使用,当一个对象作为HashMap的key时必须要实现这个方法。因为很多时候我们会new 很多个相同的对象,但是这些对象在HashMap里面却不会覆盖,因为是直接继承父类Object的hashCode,equals所以每个原本该相等的对象却不会相等。不过在自己实现hashCode方法的时候一定要注意不同对象返回的int尽量不要相同这样可以提高HashMap的效率。不过问题也就来了,很多同学说我怎么知道怎么重写才能保证,相同对象一定相同,不同对象尽量不同呢?源码之下了无秘密:

/*
*这个是String 类重写的hashCode
*value的这个生成是比较关键的地方 我们现在值考虑比较简单bean类 我们只需要把每个字段的值转换成StringBuffer
*加起来然后转换成char [] value 再使用String 重写好的这个方法不就可以完美重写自己的hashCode了么,感兴趣的同
*学可以自己去实践一下
*/

public int hashCode() {
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;
}


public boolean equals(Object obj) {
return (this == obj);
}


这个方法就是专门比较地址空间是否相同的所有每个只要是new 出来的新对象,地址空间不会相同,尽管里面内容一样却不会相同,这个时候我们自己实现的类如果要判断是否相同的话也要自己重写 equals 才可以判断。其实如果我们实现了hashCode的话这个时候就可以使用这个来对比,但是用hashCode无法保证绝对是一样的,对准确性要求到完美的情况下是不能使用hashCode的,那么问题来了,这个时候我们应该怎么判断呢?还是假设只是简单的bean类,复合类有很多其他因素夹杂在一起,功力不能完全驾驭,不敢乱说。只有对每一个java 基础类型进行判断,这样才可以保证一定是对的,有朋友说那我们可不可以加起来,这样最后判一次就可以了啊,这个其实就是实现hashCode的原理这样是不可以的,不能保证绝对一致,为什么?该我问你哈。

protected native Object clone() throws CloneNotSupportedException;


clone这个方法也是容易忽略的方法,但它这个方法是设计模式里面的原型模式的基础。注意使用clone方法的时候一定要继承接口Cloneable,不然包报错,很多同学对此不解,其实我也不解为什么有了这个方法反而去继承一个什么都没有的接口。在查询一些资料的时候说,该接口是作为一个标志位,在本地方法实现的时候就会检测标志位,这是一个底层实现的原理问题。这个直说了注意事项:那clone方法的用法其实有两种,一种是浅拷贝,一种是深拷贝。两者之间的区别是什么呢?

浅拷贝是拷贝的对象的引用,引用与什么坏处呢?当克隆类操作引用属性的时候,原始类的属性会发生改变,这个就是浅拷贝的坏处,如果我们不提供修改的话这样在一定基础可以保证浅拷贝的安全,但如果用反射就没有办法保证了,这个时候我们应该怎么办呢?

深拷贝会拷贝所有对象,但java 的clone方法是浅拷贝,要实现深拷贝我们必须要自己实现。(时间不够就不具体讲解如何实现了)

public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
public final void wait() throws InterruptedException {


上面四个方法是多线程里面基础,在多线程设计模式系列文章里面有一些优雅的应用就不做过多的讲解了。

protected void finalize() throws Throwable { }


该方法在对垃圾回收时,必须先调用这个方法,很多时候可以做一个收尾工作。很多童鞋重写了这个方法new 了一个对象可是调用Syetem.gc()的时候会发现根本没有调用。那我上面这句话是不是在乱说呢?其实不是,主要是你之new 这个对象没有任何调用的话,编译器优化的时候直接就把你的那句话给 remove了,因为没有任何效果,所有要测试的时候一定要有一些引用,不然编译器层次上直接没了,自然就看不到结果咯。

最后总结一下:Object的每个方法都在某些部分扮演重要角色,越忽略的东西越容易扮演杀手,很多大公司想考这些基础就是因为他们也许淌过一些天坑,希望各位同学都无比重视自己的基础。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Object 所有方法