LinkinPark
当你的才华撑不起你野心时,那么请潜下心继续学习,心无旁骛,愿多年以后你们我都能成为自己想象的模样。
所有类的公共父类,一旦一个类没有显示地继承一个类则其直接父类一定是Object。一切数据类型都可用Object接收。class OOXX  extends Object{}等价于class ooXX {}
  • 常见方法:
public boolean equals(Object obj):对象比较。
public int hashCode():取得该对象的Hash码。
public String toString():对象描述。

  • toString方法:

Object类的 toString()方法:“对象的描述”。建议所有类都覆写此方法,直接打印输出对象时,会调用该对象的toString()方法。

打印对象的时候,实际调用的对象实际指向的类的自我描述;全限定类名+@+十六进制的hashCode值,等价于全限定类名+@+IntegertoHexString(该对象.hashCode) 。例如:

public class Linkin {
    private String name;
    
    //大部分的时候,重写tostring方法总是返回该对象的所有令人感兴趣的信息组成的字符串。
    @Override
    public String toString() {
        return "Linkin [name=" + name + "]";
    }

    public static void main(String[] args) {
        Linkin linkin = new Linkin();
        //以下2行代码其实完全一样
        System.out.println(linkin);
        System.out.println(linkin.toString());
    }
}

  • ==和equals方法:

==:用于判断两个变量是否相等。

基本类型:如果2个变量是基本数据类型,且都是数值类型,不一定要求数据类型严格相同,则只要2个变量的值相等,就可以放回true。
引用类型:必须指向同一个对象,才true。只能比较有父子或平级关系的两个对象,否则将出现编译错误。

equals:object类的equals方法也是判断是否指向同一个对象。没有实际意义,有必要可以重写。String 覆写了 Object的equals方法:只比较字符的序列是否相同,就会返回true。


以下是Object的equals源码和String的equals源码:

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

 public boolean equals(Object anObject) {
	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;
    }

以下是一般我们需要重写equals的代码:

public class Linkin {
    private String name;

    @Override
    //以下是Shift+alt+S自动生成的equals方法,虽然啰嗦了点,但是不用自己写了。。。
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        //这里还是跑下反射,不要使用instanceof:因为有可能存在继承,那样子也将返回true了。。。
        if (getClass() != obj.getClass())
            return false;
        Linkin other = (Linkin) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}

另外object还有一个方法,可垃圾回收机制有关。finalize方法:当一个对象被垃圾回收的时候调用的方法。

垃圾回收器要回收对象的时候,首先要调用这个类的finalize方法(你可以 写程序验证这个结论),一般的纯Java编写的Class不需要重新覆盖这个方法,因为Object已经实现了一个默认的,除非我们要实现特殊的功能(这 里面涉及到很多东西,比如对象空间树等内容)。 不过用Java以外的代码编写的Class(比如JNI,C++的new方法分配的内存),垃圾回收器并不能对这些部分进行正确的回收,这时就需要我们覆盖默认的方法来实现对这部分内存的正确释放和回收(比如C++需要delete)。 总之,finalize相当于析构函数,他是垃圾回收器回收一个对象的时候第一个要调用的方法。不过由于Java的垃圾回收机制能自动为我们做这些事情,所以我们在一般情况下是不需要自己来手工释放的

有时当撤消一个对象时,需要完成一些操作。例如,如果一个对象正在处理的是非Java 资源,如文件句柄或window 字符字体,这时你要确认在一个对象被撤消以前要保证这些资源被释放。为处理这样的状况,Java 提供了被称为收尾(finalization )的机制。使用该机制你可以定义一些特殊的操作,这些操作在一个对象将要被垃圾回收程序释放时执行。 

要给一个类增加收尾(finalizer ),你只要定义finalize ( ) 方法即可。Java 回收该类的一个对象时,就会调用这个方法。在finalize ( )方法中,你要指定在一个对象被撤消前必须执行的操作。垃圾回收周期性地运行,检查对象不再被运行状态引用或间接地通过其他对象引用。就在对象被释放之 前,Java 运行系统调用该对象的finalize( ) 方法。

  finalize()方法的通用格式如下:

  protected void finalize( )
{
// finalization code here
}

  其中,关键字protected是防止在该类之外定义的代码访问finalize()标识符。该标识符和其他标识符将在第7章中解

理解finalize( ) 正好在垃圾回收以前被调用非常重要。例如当一个对象超出了它的作用域时,finalize( ) 并不被调用。这意味着你不可能知道何时——甚至是否——finalize( ) 被调用。因此,你的程序应该提供其他的方法来释放由对象使用的系统资源,而不能依靠finalize( ) 来完成程序的正常操作。

  注意:如果你熟悉C++,那你知道C++允许你为一个类定义一个撤消函数(destructor ),它在对象正好出作用域之前被调用。Java不支持这个想法也不提供撤消函数。finalize() 方法只和撤消函数的功能接近。当你对Java 有丰富经验时,你将看到因为Java使用垃圾回收子系统,几乎没有必要使用撤消函数。

finalize的工作原理应该是这样的:一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存.所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作.

finalize()在什么时候被调用?
有三种情况:
1.所有对象被Garbage Collection时自动调用,比如运行System.gc()的时候.
2.程序退出时为每个对象调用一次finalize方法。
3.显式的调用finalize方法

除此以外,正常情况下,当某个对象被系统收集为无用信息的时候,finalize()将被自动调用,但是jvm不保证finalize()一定被调用,也就是说,finalize()的调用是不确定的,这也就是为什么sun不提倡使用finalize()的原因

有时当撤消一个对象时,需要完成一些操作。例如,如果一个对象正在处理的是非Java 资源,如文件句柄或window 字符字体,这时你要确认在一个对象被撤消以前要保证这些资源被释放。为处理这样的状况,Java 提供了被称为收尾(finalization )的机制。使用该机制你可以定义一些特殊的操作,这些操作在一个对象将要被垃圾回收程序释放时执行。

要给一个类增加收尾(finalizer ),你只要定义finalize ( ) 方法即可。Java 回收该类的一个对象时,就会调用这个方法。在finalize ( )方法中,你要指定在一个对象被撤消前必须执行的操作。垃圾回收周期性地运行,检查对象不再被运行状态引用或间接地通过其他对象引用。就在对象被释放之 前,Java 运行系统调用该对象的finalize( ) 方法。

finalize()方法的通用格式如下:

protected void finalize( )
{
// finalization code here
}

其中,关键字protected是防止在该类之外定义的代码访问finalize()标识符。该标识符和其他标识符将在第7章中解释。

理解finalize( ) 正好在垃圾回收以前被调用非常重要。例如当一个对象超出了它的作用域时,finalize( ) 并不被调用。这意味着你不可能知道何时——甚至是否——finalize( ) 被调用。因此,你的程序应该提供其他的方法来释放由对象使用的系统资源,而不能依靠finalize( ) 来完成程序的正常操作。

注意:如果你熟悉C++,那你知道C++允许你为一个类定义一个撤消函数(destructor ),它在对象正好出作用域之前被调用。Java不支持这个想法也不提供撤消函数。finalize() 方法只和撤消函数的功能接近。当你对Java 有丰富经验时,你将看到因为Java使用垃圾回收子系统,几乎没有必要使用撤消函数。

垃圾收集器在进行垃圾收集的时候会自动呼叫对象的finalize方法,用来进行一些用户自定义的非内存清理工作,因为垃圾收集器不会处理内存以外的东西。所以,有的时候用户需要定义一些清理的方法,比如说处理文件和端口之类的非内存资源。


java7开始出现的操作对象的工具类。java.util.Objects。但是我现在使用的jdk是1.6的,我检查过里面木有Objects这个包。这块工具类以后会和Google guava一起整理。这里关于Objects类多说几句:它提供了一些方法来操作对象,这些方法大多数都是“空指针”安全的。

值得指出的是:Java工具类的命名习惯是添加一个字母s,比如操作数组的工具类是Arrays,操作集合的工具类是Colletions。guava里面的集合工具类也是这样子。




posted on 2014-10-30 00:33  LinkinPark  阅读(217)  评论(0编辑  收藏  举报