1. 程式人生 > >Java程式設計思想-Class物件(附上課後題)

Java程式設計思想-Class物件(附上課後題)

什麼是Class物件?

首先Class物件是用來建立類的所有的“常規”物件,Java使用Class物件來執行RTTI。

每個類都有一個Class物件,該物件由JVM建立和載入。當程式建立第一個(注意是第一個喲)對類的靜態成員的引用時,就會載入這個類。這一點說明了構造器也是類的靜態方法,即使在構造器之前並沒有使用static關鍵字。

類的載入過程

類載入器首先會檢查這個類的Class物件是否已經載入,如果尚未載入,預設的類載入器就會根據類名查詢.class檔案。一旦這個類的Class物件被載入僅記憶體,就會被用來建立這個類的所有物件。

package thinking.java.chapter13;
class Candy{
	static {
		System.out.println("load candy");
	}
}
class Gum{
	static {
		System.out.println("load gum");
	}
}
class Cookie{
	static {
		System.out.println("load cookie");
	}
}
public class SweetShop {

	public static void main(String[] args) {
		System.out.println("inside main");
		new Candy();
		System.out.println("after creating candy");
		try {
			Class.forName("Gum");
		} catch (ClassNotFoundException e) {
			System.out.println("couldn't find gum");
		}
		System.out.println("after Class.forName(\"Gum\")");
		new Cookie();
		System.out.println("after creating cookie");
	}

}

由上面的例子可以得到:Class物件僅在需要的時候才被載入,static初始化在類載入時就進行了。

其中forName()是取得Class物件的引用的一種方法,返回的是一個Class物件的引用。如果在Class.forName()中找不到你要載入的類,那麼就會丟擲ClassNotFoundException

無論何時如果你想在執行時使用型別資訊,就必須首先獲得對恰當的Class物件的引用,如使用Class.forName().

練習1

package thinking.java.chapter13;

interface HasBatteries{}
interface WaterProof{}
interface Shoot{}
class Toy{
//	註釋掉預設構造器後無法例項化該類
//	因為使用newInstance()來建立的類,必須帶有預設的構造器
//	Toy(){}
	Toy(int i){}
}
class FancyToy extends Toy
implements HasBatteries,WaterProof,Shoot{
	FancyToy(){
		super(1);
	}
}
public class ToyTest {
static void printInfo(Class cc) {
	System.out.println("Class name:"+cc.getName()+
			" is interface?["+cc.isInterface()+"]");
	System.out.println("Smple name: "+cc.getSimpleName());
	System.out.println("canonical name: "+cc.getCanonicalName());
}
	public static void main(String[] args) {
		Class x = null;
		try {
			x = Class.forName("thinking.java.chapter13.FancyToy");
		} catch (ClassNotFoundException e) {
			System.out.println("can't find fancytoy");
			System.exit(1);
		}
		printInfo(x);
		for(Class face:x.getInterfaces())
			printInfo(face);
		Class up = x.getSuperclass();
		Object obj = null;
		try {
			obj = up.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		printInfo(obj.getClass());
	}

}

練習2

package thinking.java.chapter13;

interface HasBatteries{}
interface WaterProof{}
interface Shoot{}
interface Files{}
class Toy{
//	註釋掉預設構造器後無法例項化該類
//	因為使用newInstance()來建立的類,必須帶有預設的構造器
	Toy(){}
	Toy(int i){}
}
class FancyToy extends Toy
implements HasBatteries,WaterProof,Shoot,Files{
	FancyToy(){
		super(1);
	}
}
public class ToyTest {
static void printInfo(Class cc) {
	System.out.println("Class name:"+cc.getName()+
			" is interface?["+cc.isInterface()+"]");
	System.out.println("Smple name: "+cc.getSimpleName());
	System.out.println("canonical name: "+cc.getCanonicalName());
}
	public static void main(String[] args) {
		Class x = null;
		try {
			x = Class.forName("thinking.java.chapter13.FancyToy");
		} catch (ClassNotFoundException e) {
			System.out.println("can't find fancytoy");
			System.exit(1);
		}
		printInfo(x);
		for(Class face:x.getInterfaces())
			printInfo(face);
		Class up = x.getSuperclass();
		Object obj = null;
		try {
			obj = up.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		printInfo(obj.getClass());
	}

}

練習3:

package thinking.java.chapter13;

import java.util.Arrays;
import java.util.List;

abstract class Shape{
	void draw() {
		System.out.println(this+".draw()");
	}
abstract public String toString();
}
class Circle extends Shape{

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Circle";
	}
	
}
class Square extends Shape{

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Square";
	}
	
}
class Triangle extends Shape{
	public String toString() {
		return "Trangle";
	}
}
class Rhomboid extends Shape{
	public String toString() {
		return "Rhomboid";
	}
}
public class Shape3 {

	public static void main(String[] args) {
		List<Shape> shapeList = Arrays.asList(new Circle(),new Square(),new Triangle(),new Rhomboid());
		for(Shape s:shapeList) {
			s.draw();
		}
		Rhomboid r = new Rhomboid();
		((Shape)r).draw();
//		無法轉換的型別
//		((Circle)r).draw();
		
	}

}

練習7

package thinking.java.chapter13;
class Candy{
	static {
		System.out.println("load candy");
	}
}
class Gum{
	static {
		System.out.println("load gum");
	}
}
class Cookie{
	static {
		System.out.println("load cookie");
	}
}
public class SweetShop {

	public static void main(String[] args) {
		if(args.length<1) {
			System.out.println("usage:sweetname");
			System.exit(0);
		}
		Class c = null;
		try {
			c = Class.forName(args[0]);
			System.out.println("enjoy:"+args[0]);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

練習8:

package thinking.java.chapter13;
class A{}
class B extends A{}
class C extends B{}

public class Demo08 {
public static void printSuperClass(Object o) {
	if(o.getClass().getSuperclass()!=null) {
		System.out.println(o.getClass()+" is a subclass of "+o.getClass().getSuperclass());
	}
	try {
		printSuperClass(o.getClass().getSuperclass().newInstance());
	} catch(InstantiationException e) {
		System.out.println("Unable to instantiate obj");
	} catch(IllegalAccessException e) {
		System.out.println("Unable to access");
	}
}
	public static void main(String[] args) {
		printSuperClass(new C());
	}

}

練習10:

package thinking.java.chapter13;

public class Exe10 {

	public static void main(String[] args) {
//char陣列是一個物件
		char[] c = new char[10];
		System.out.println("superClass:"+c.getClass().getSuperclass());
		System.out.println("c instaneof object:"+(c instanceof Object));
	}

}