[隨筆][Java][讀書筆記][thinking in java][第十四章 類型信息]
阿新 • • 發佈:2018-09-07
found 構造 att main 數組 test 第一個 eating urn
- 主要理解如何在運行時獲取類型信息。主要有兩種方式:一是RTTI,假定我們在編譯時已經知道了所有的類型;二是反射機制,允許在運行時發現和使用類的信息。
14.1 為什麽需要RTTI
- 一個多態的例子
import java.util.*; abstract class Shape { void draw() { System.out.println(this + ".draw()"); } abstract public String toString(); } class Circle extends Shape { public String toString() { return "Circle"; } } class Square extends Shape { public String toString() { return "Square"; } } class Trianle extends Shape { public String toString() { return "Trianle"; } } public class Shapes{ public static void main(String[] args) { List<Shape> shapeList = Arrays.asList(new Circle(), new Square(), new Trianle()); for(Shape shape : shapeList) { shape.draw(); } } }
- 當把創建的對象放入到List
- 當從數組中把元素取出來的時候,會自動的將對象轉型回Shape。這是RTTI在java中最基本的使用形式。java中的所有的類型轉化都是在運行時進行正確性檢查。
- List容器在存儲元素的時候,將所有的元素當作Object看待,在取出的時候向下轉型成為對應的類型。但是這種轉型並不徹底,並不能向下轉型成Circle等類型,因為在容器定義的時候,只知道List中存儲的是Shape類型。
14.2 Class對象
- Class對象---一種特殊的對象,用於在運行時表示類型信息,包含了與類有關的信息。
- 每個類都有一個Class對象,每當編寫並編譯一個新類,就會產生一個Class對象(被保存在一個同名的.class文件中)
- 類加載器首先檢查這個類的Class對象是否已經加載,按照類名查找.class文件,一旦某個類的Class對象文件被載入到內存,它就被用來創建這個類的所有對象。
class Candy { static { System.out.println("loading candy"); } } class Gum { static { System.out.println("loading gum"); } } class Cookie { static { System.out.println("loading 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("not fine gum"); } } } //結果 ![](https://images2018.cnblogs.com/blog/1034390/201808/1034390-20180831152652459-1698512495.png)
- 類中的static子句在類第一個次被加載時執行。
- Class.forName();這個是Class類的一個static方法,forName()可以獲取對應的Class對象的引用,返回值是一個Class對象的引用。
- 只要想在運行時獲得對象的類型信息,就必須首先獲得對應的Class對象的引用。或者在某個具體的對象上調用getClass()方法得到對應的Class對象的引用,這個方法屬於Object的一部分。
- 一個Class中各種方法的例子
interface HasBatteries {}
interface Waterproff {}
interface Shoots {}
class Toy {
Toy() {}
Toy(int i) {}
}
class FancyToy extends Toy implements HasBatteries, Waterproff, Shoots{
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("Simple name: " + cc.getSimpleName());
System.out.println("Canonical name: " + cc.getCanonicalName());
}
public static void main(String[] args) {
Class c = null;
try {
c = Class.forName("FancyToy");
} catch (ClassNotFoundException e) {
System.out.println("not find FancyToy");
System.exit(1);
}
printInfo(c);
for(Class face : c.getInterfaces()) {
printInfo(face);
}
Class up = c.getSuperclass();
Object obj = null;
try {
obj = up.newInstance();
} catch(InstantiationException e) {
System.out.println("not instanceiate");
System.exit(1);
} catch (IllegalAccessException e) {
System.out.println("not access");
System.exit(1);
}
printInfo(obj.getClass());
}
}
//輸出
D:\workspace\java>java ToyTest
Class name: FancyToy is interface? false
Simple name: FancyToy
Canonical name: FancyToy
Class name: HasBatteries is interface? true
Simple name: HasBatteries
Canonical name: HasBatteries
Class name: Waterproff is interface? true
Simple name: Waterproff
Canonical name: Waterproff
Class name: Shoots is interface? true
Simple name: Shoots
Canonical name: Shoots
Class name: Toy is interface? false
Simple name: Toy
Canonical name: Toy
D:\workspace\java>
![](https://images2018.cnblogs.com/blog/1034390/201808/1034390-20180831162939449-263513627.png)
- 傳遞給forName()的字符串中,必須使用權限頂名(包含包名)。
- Class.getInterfaces()方法返回的是Class對象,表示對象中所包含的接口。
- newInstance()方法實現“虛擬構造器”的一種途徑,我不知道確切的類型,無論無何要正確的創建你自己?????
Class的對象代表的是一個類,可以使用newInstance()方法創建一個對象。
- 類字面量:FancyToy.class;生成對Class對象的引用。在編譯的時候受到檢查,不需要放置到try語句中。如果使用forName(),必須放到try語句中。否則報錯
D:\workspace\java>javac ToyTest.java
ToyTest.java:24: 錯誤: 未報告的異常錯誤ClassNotFoundException; 必須對其進行捕獲或聲明以便拋出
c = Class.forName("FancyToy");
^
1 個錯誤
D:\workspace\java>
- 使用".class"來創建對Class對象的引用時,不會自動的初始化該Class對象,為了使用類需要包含三個步驟:加載,鏈接,初始化。
[隨筆][Java][讀書筆記][thinking in java][第十四章 類型信息]