Java程式設計思想-Class物件(附上課後題)
阿新 • • 發佈:2019-01-13
什麼是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));
}
}