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

【Java相关】Java的Object类

2015-11-14 15:52 417 查看

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 one
created Test named number two
finalized Test named number two

//取消后面 t1 = null 注释之后的结果:
created Test named number one
created Test named number two
finalized Test named number two
finalized 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 one
finalized 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 1
Consumed: Item number 1
队列已空!
Produced: Item number 2
Consumed: Item number 2
Produced: Item number 3
Produced: Item number 4
Consumed: Item number 3
Produced: Item number 5
Consumed: Item number 4
Produced: Item number 6
Consumed: Item number 5
Produced: Item number 7
Consumed: Item number 6
Produced: Item number 8
Produced: Item number 9
队列已满!
Consumed: Item number 7
Produced: Item number 10
队列已满!
Consumed: Item number 8
Produced: Item number 11
队列已满!
Produced: Item number 12
Consumed: Item number 9
Consumed: 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();

声明一个
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值是任意的。

对每一个对象中有意义的具体值(在
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()
;如果需要更复杂的比较,就计算这个值的“标准表示”来计算标准的哈希值;如果引用类型的值为
null
f = 0
.

2.7 对于一个数组类型的引用,将每一个元素视为单独的变量,对于每一个有意义的值,调用对应的方法计算其哈希值,最后如步骤2.2的描述那样将所有的哈希值合并。

计算
result = 37 * result + hc
,将所有的hc合并到哈希值中。乘法使哈希值取决于它的值的规则,当一个类中存在多种相似的值时,就增加了哈希表的离散性。

返回result。

完成
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 the
object is an instance, the at-sign character `{@code @}', and
the unsigned hexadecimal representation of the hash code of the
object.
'''


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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: