【Java相关】Java的Object类

来源:互联网 发布:linux c udp socket 编辑:程序博客网 时间:2024/06/08 10:37

Overview

Object类是Java类层次结构中的根节点。

 1. private static native void registerNatives(); 2. public final native Class<?> getClass(); 3. public native int hashCode(); 4. public boolean equals(Object obj); 5. protected native Object clone(); 6. public String toString(); 7. public final native void notify(); 8. public final native void notifyAll(); 9. public final native void wait(long timeout); 10. public final void wait(long timeout, int nanos); 11. public final void wait(); 12. protected void finalize();

总体来看,有四大部分值得看一看。第一部分,native修饰符;第二部分,finalize()方法;第三部分,notify()wait()方法;第四部分,其他。

native修饰符

Java Native Interface(JNI)

JNI是一种本地的编程接口。它允许java代码在Java虚拟机(Virtual Machine)运行,来与其他编程语言(比如C, C++和assembly)编写的应用或者library进行互操作。

使用JNI最重要的好处就是它对于底层Java虚拟机的实现没有施加任何限制。因此,Java虚拟机的厂商可以为JNI添加支持而不影响JVM的其他部分。程序员们也可以尝试写一个本地的的应用或者library,并且让其运行在支持JNI的Java虚拟机上。

当你可以完全使用Java语言来编写一个应用程序的时候,总是会存在一些仅有Java无法满足你应用程序需求的情况。当一个应用程序无法来仅使用Java来编写的时候,程序员们可以使用JNI来编写Java本地方法(Java native methods)来处理这些问题。

下面这些例子描述了你何时需要使用Java本地方法的时候:
1. The standard Java class library does not support the platform-dependent features needed by the application.
2. You already have a library written in another language, and wish to make it accessible to Java code through the JNI.
3. You want to implement a small portion of time-critical code in a lower-level language such as assembly.
通过JNI编程,你能够使用本地方法来干这些事情:
1. Create, inspect, and update Java objects (including arrays and strings).
2. Call Java methods.
3. Catch and throw exceptions.
4. Load classes and obtain class information.
5. Perform runtime type checking.

finalize()方法

对象的销毁过程

来看看对象的状态转换图。

对象的状态转换图

test case number 1

class Test{    public static int created = 0;    public static int finalized = 0;    public static boolean isProceed = true;    public Test() {        // TODO Auto-generated constructor stub        created++;    }    @Override    protected void finalize() throws Throwable {        // TODO Auto-generated method stub        super.finalize();        isProceed = false;        finalized++;    }}public class FinalizeTest {    public static void main(String[] args) {        // TODO Auto-generated method stub        while(Test.isProceed){            new Test();        }        System.gc();        System.out.format("\nyou've created %d objects of Test and finalized %d objects of Test.\n\n",Test.created,Test.finalized);    }}

输出结果:

you've created 276968 objects of Test and finalized 511 objects of Test.

test case number 2

class Test2{    private String name;    public Test2(String name) {        // TODO Auto-generated constructor stub        this.name = name;        System.out.println("created Test named "+this.name);    }    @Override    protected void finalize() throws Throwable {        // TODO Auto-generated method stub        super.finalize();        System.out.println("finalized Test named "+this.name);    }}public class FinalizeTest2 {    public static void main(String[] args) {        // TODO Auto-generated method stub        Test2 t1 = new Test2("number one");        new Test2("number two");//        t1 = null;        System.gc();    }}

输出结果:

created Test named number onecreated Test named number twofinalized Test named number two//取消后面 t1 = null 注释之后的结果:created Test named number onecreated Test named number twofinalized Test named number twofinalized Test named number one

test case number 3

class Test3{    private String name;    public Test3(String name) {        // TODO Auto-generated constructor stub        this.name = name;        System.out.println("created Test named "+this.name);    }    @Override    protected void finalize() throws Throwable {        // TODO Auto-generated method stub        super.finalize();        System.out.println("finalized Test named "+this.name);    }}public class FinalizeTest3 {    public static void main(String[] args) {        // TODO Auto-generated method stub        int i = 1;        if (i == 1) {            Test3 t1 = new Test3("number one");        }        System.gc();    }}

输出结果:

created Test named number onefinalized Test named number one

notify()wait()方法

MyQueue.java

import java.util.LinkedList;class MyItem{    public String name;    public MyItem(int number) {        // TODO Auto-generated constructor stub        this.name = "Item number "+number;    }    @Override    public String toString() {        return this.name;    }}public class MyQueue {    public int maxSize = 5;    public static int allowed = 100;    public MyQueue(int maxSize) {        // TODO Auto-generated constructor stub        this.maxSize = maxSize;    }    public MyQueue() {        // TODO Auto-generated constructor stub    }    private static LinkedList<MyItem> queue =new LinkedList<MyItem>();    public synchronized void produce (MyItem myItem) {        while(queue.size()==maxSize){            System.err.println("队列已满!");            try {                this.wait();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        queue.add(myItem);        this.notify();    }    public synchronized MyItem consume(){        while(queue.isEmpty()){            System.err.println("队列已空!");            try {                this.wait();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        MyItem myItem = queue.poll();        this.notify();        return myItem;    }}

MyProducer.java

public class Producer implements Runnable {    private MyQueue myQueue;    public Producer(MyQueue myQueue) {        // TODO Auto-generated constructor stub        this.myQueue = myQueue;    }    public void run() {        // TODO Auto-generated method stub        for(int i=0;i<MyQueue.allowed;i++){            MyItem myItem = new MyItem(i+1);            myQueue.produce(myItem);            System.out.println("Produced: "+myItem);            try {                Thread.sleep((long) (1000*Math.random()));            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}

MyConsumer.java

public class Consumer implements Runnable {    private MyQueue myQueue;    public Consumer(MyQueue myQueue) {        // TODO Auto-generated constructor stub        this.myQueue = myQueue;    }    public void run() {        // TODO Auto-generated method stub        for (int i = 0; i < MyQueue.allowed; i++) {            MyItem myItem = myQueue.consume();            System.out.println("Consumed: "+myItem);            try {                Thread.sleep((long) (1200*Math.random()));            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}

Main.java

public class Main {    public static void main(String[] args) {        // TODO Auto-generated method stub        MyQueue myQueue = new MyQueue(3);        Thread thread1 = new Thread(new Producer(myQueue));        Thread thread2 = new Thread(new Consumer(myQueue));        thread1.start();        thread2.start();    }}

输出结果:

Produced: Item number 1Consumed: Item number 1队列已空!Produced: Item number 2Consumed: Item number 2Produced: Item number 3Produced: Item number 4Consumed: Item number 3Produced: Item number 5Consumed: Item number 4Produced: Item number 6Consumed: Item number 5Produced: Item number 7Consumed: Item number 6Produced: Item number 8Produced: Item number 9队列已满!Consumed: Item number 7Produced: Item number 10队列已满!Consumed: Item number 8Produced: Item number 11队列已满!Produced: Item number 12Consumed: Item number 9Consumed: Item number 10

其他

clone()方法

浅克隆

class Capital{    private String name;    private int population;    public Capital(String name, int population) {        super();        this.name = name;        this.population = population;    }    @Override    public String toString() {        return "Capital [name=" + name + ", population=" + population + "]";    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getPopulation() {        return population;    }    public void setPopulation(int population) {        this.population = population;    }}class Country implements Cloneable{    private String name;    private Capital capital;    public Country(String name, Capital capital) {        // TODO Auto-generated constructor stub        this.name = name;        this.capital = capital;    }    @Override    protected Object clone() throws CloneNotSupportedException {        return super.clone();    };    @Override    public String toString() {        return "Country [name=" + name + ", capital=" + capital + "]";    }    public String getName() {        return name;    }    public Capital getCapital() {        return capital;    }}public class CloneTest {    public static void main(String[] args) throws CloneNotSupportedException {        // TODO Auto-generated method stub        Country country = new Country("CHN", new Capital("Peking", 2000));        System.out.println(country);        Country country2 = (Country) country.clone();        System.out.println(country2);        country.getCapital().setName("Tokyo");        country.getCapital().setPopulation(3800);        System.out.println(country);        System.out.println(country2);    }}

输出结果:

Country [name=CHN, capital=Capital [name=Peking, population=2000]]Country [name=CHN, capital=Capital [name=Peking, population=2000]]Country [name=CHN, capital=Capital [name=Tokyo, population=3800]]Country [name=CHN, capital=Capital [name=Tokyo, population=3800]]

深克隆

class Capital2{    private String name;    private int population;    public Capital2(String name, int population) {        super();        this.name = name;        this.population = population;    }    @Override    protected Object clone() throws CloneNotSupportedException {        return new Capital2(getName(), getPopulation());    };    @Override    public String toString() {        return "Capital [name=" + name + ", population=" + population + "]";    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getPopulation() {        return population;    }    public void setPopulation(int population) {        this.population = population;    }}class Country2 implements Cloneable{    private String name;    private Capital2 capital;    public Country2(String name, Capital2 capital) {        // TODO Auto-generated constructor stub        this.name = name;        this.capital = capital;    }    @Override    protected Object clone() throws CloneNotSupportedException {        Country2 country =  (Country2) super.clone();        country.capital = (Capital2) capital.clone();        return country;    };    @Override    public String toString() {        return "Country [name=" + name + ", capital=" + capital + "]";    }    public String getName() {        return name;    }    public Capital2 getCapital() {        return capital;    }}public class CloneTest2 {    public static void main(String[] args) throws CloneNotSupportedException {        // TODO Auto-generated method stub        Country2 country = new Country2("CHN", new Capital2("Peking", 2000));        System.out.println(country);        Country2 country2 = (Country2) country.clone();        System.out.println(country2);        country.getCapital().setName("Tokyo");        country.getCapital().setPopulation(3800);        System.out.println(country);        System.out.println(country2);    }}

输出结果:

Country [name=CHN, capital=Capital [name=Peking, population=2000]]Country [name=CHN, capital=Capital [name=Peking, population=2000]]Country [name=CHN, capital=Capital [name=Tokyo, population=3800]]Country [name=CHN, capital=Capital [name=Peking, population=2000]]

hashCode();

  1. 声明一个int型的变量,命名为result(或者其他你喜欢的名字),然后初始化为一个不为零的常量(比如31)。使用一个不为零的常量会影响到所有的初始的哈希值(步骤2.1的结果)为零的值。【A nonzero value is used so that it will be affected by any initial fields whose hash value (computed in Step 2.1) is zero. 】如果初始的result为0的话,最后的哈希值不会被它影响到,所以冲突的几率会增加。这个非零result值是任意的。
  2. 对每一个对象中有意义的具体值(在equals()中所涉及的值)f,进行以下步骤的处理:
    按照以下步骤计算f的基于int型的哈希值hc
    2.1 对于一个boolean型变量,hc = f ? 0 : 1
    2.2 对于一个byte, char, short或者int型变量,hc = (int) f
    2.3 对于一个long型变量,hc = (int)(f^(f>>>32))。这个表达式是将long型变量作为32位(long型最多有32位)来计算的;
    2.4 对于一个float型变量,hc = Float.floatToIntBits(f)
    2.5 对于一个double型变量,long l = Double.doubleToLongBits(f); hc = (int)(l^(l>>>32))
    2.6 对于引用类型的变量,如果类中的equals()方法递归的调用equals()类比较成员变量,那么就递归调用hashCode();如果需要更复杂的比较,就计算这个值的“标准表示”来计算标准的哈希值;如果引用类型的值为nullf = 0.
    2.7 对于一个数组类型的引用,将每一个元素视为单独的变量,对于每一个有意义的值,调用对应的方法计算其哈希值,最后如步骤2.2的描述那样将所有的哈希值合并。
  3. 计算result = 37 * result + hc,将所有的hc合并到哈希值中。乘法使哈希值取决于它的值的规则,当一个类中存在多种相似的值时,就增加了哈希表的离散性。
  4. 返回result。
  5. 完成hashCode()之后,要确保相同的对象调用hashCode()得到相同的哈希值。
import java.util.HashSet;import java.util.Set;class Destroyer {    private String name;    private int number;    public Destroyer(String name, int number) {        super();        this.name = name;        this.number = number;    }    @Override    public int hashCode() {        // TODO Auto-generated method stub        int hash = 23;        hash = 37 * hash + name.hashCode();        hash = 37 * hash + number;        return hash;    }    @Override    public boolean equals(Object obj) {        // TODO Auto-generated method stub        if(! (obj instanceof Destroyer)){            return false;        }        Destroyer destroyer = (Destroyer)(obj);        return destroyer.getName().equals(name) && destroyer.getNumber() == number;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getNumber() {        return number;    }    public void setNumber(int number) {        this.number = number;    }}public class HashCodeTest {    public static void main(String[] args) {        Set<Destroyer> setOfDestroyer = new HashSet<Destroyer>();        setOfDestroyer.add(new Destroyer("昆明", 172));        setOfDestroyer.add(new Destroyer("长沙", 173));        System.out.println(setOfDestroyer.contains(new Destroyer("昆明", 172)));    }}

输出结果:

true

toString();

'''The {@code toString} method for class {@code Object}returns a string consisting of the name of the class of which theobject is an instance, the at-sign character `{@code @}', andthe unsigned hexadecimal representation of the hash code of theobject. '''
    public String toString() {        return getClass().getName() + "@" + Integer.toHexString(hashCode());    }
class AirCraft {    private String name;    private int number;    public AirCraft(String name, int number) {        super();        this.name = name;        this.number = number;    }}public class ToStringTest {    public static void main(String[] args) {        // TODO Auto-generated method stub        System.out.println(new AirCraft("辽宁", 16));    }}

输出结果:

AirCraft@2a139a55

References

Java问答:终极父类
关于JAVA中的Garbage Collection和finalize()
深入理解java的finalize


0 0
原创粉丝点击