JDK原始碼學習-基礎類
一、概述
1、Java,是一套語言規範,例如規定了變數如何定義、控制語句如何寫等,提供基本的語法規範。JDK是java自帶的一套呼叫元件,是對基本java語法規範的進一步封裝,jdk中都是使用java基本的語法來寫的,使用JDK能夠更好的使用java。當然,自己也可以寫一套JDK。自己在專案中也可以不使用自帶的JDK,而使用原生的基本語法。
2、在整個JDK API中,大約包含1200個包,包名主要有三種:java、javax和org。其中以java開頭的包名是JDK的基礎語言包,以javax開頭的屬於JDK擴充套件包(其中x是extend的簡寫),而以org開頭的則是第三方組織提供的功能包(org是organization的簡寫)。而在JDK API中還包含了一些以com.sun開頭的包名,這些是SUN公司提供的一些功能包,由於這些包中的類隨著JDK版本的更改變化很大,不具備相容性,所以未在標準的JDK API文件中進行公開。
3、rt.jar檔案是java執行時類庫,是我們用到最多的基礎類庫,包括java.lang,java.io,java.net,java.util等。
java.lang
:Java語言包,這個包下的檔案不需要顯式import。包括:Object類,資料型別相關的類(String,Long,Byte),Class類,執行緒相關類Thread,異常類Throwable,等。
java.io
:I/O操作相關的類。包括:檔案類File,FileReader,FileWriter,輸入輸出流InputStream/OutputStream,等。
java.net
:網路相關類。包括:http連線類HttpURLConnection,socket類,等。
java.util
:工具類。包括:資料結構相關的類ArrayList、Hashmap,日期類Date,隨機數類Random,等。
7、每個陣列屬於被對映為 Class 物件的一個類,所有具有相同元素型別和維數的陣列都共享該 Class 物件。 8、使用Class.forName(),載入一個類到記憶體中,使用newInstance()建立類。newInstance()方法呼叫預設構造器(無引數構造器)初始化新建物件。 9、java裡面任何類都要裝載在虛擬機器上才能執行。forName就是裝載類用的(new是根據載入到記憶體中的類建立一個例項,要分清楚)。 至於什麼時候用,可以考慮一下這個問題,給你一個字串變數,它代表一個類的包名和類名,你怎麼例項化它? A a = (A)Class.forName("pacage.A").newInstance();這和A a = new A();是一樣的效果。 10、jvm在裝載類時會執行類的靜態程式碼段,要記住靜態程式碼是和類繫結的,類裝載成功就表示執行了你的靜態程式碼了,而且以後不會再執行這段靜態程式碼了。 11、Class.forName(xxx.xx.xx)的作用是要求JVM查詢並載入指定的類,即查詢對應的.class檔案,也就是說JVM會執行該類的靜態程式碼段。
12、動態載入和建立Class物件,比如想根據使用者輸入的字串來建立物件
String str = 使用者輸入的字串
Class t = Class.forName(str);
t.newInstance();
13、在初始化一個類,生成一個例項的時候,newInstance()方法和new關鍵字除了一個是方法,一個是關鍵字外,它們的區別在於建立物件的方式不一樣,前者是使用類載入機制,後者是建立一個新類。這主要考慮到軟體的可伸縮、可擴充套件和可重用等軟體設計思想,才有這兩種建立方式。Java中工廠模式經常使用newInstance()方法來建立物件,因此從為什麼要使用工廠模式上可以找到具體答案。例如:
Class c = Class.forName(“Example”);
factory = (ExampleInterface)c.newInstance();
其中ExampleInterface是Example的介面,可以寫成如下形式:
String className = "Example";
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();
進一步可以寫成如下形式:
String className = readfromXMlConfig;//從xml 配置檔案中獲得字串
class c = Class.forName(className);
factory = (ExampleInterface)c.newInstance();
上面程式碼已經不存在Example的類名稱,它的優點是,無論Example類怎麼變化,上述程式碼不變,甚至可以更換Example的兄弟類Example2 , Example3 , Example4……,只要他們繼承ExampleInterface就可以。
14、從JVM的角度看,我們使用關鍵字new建立一個類的時候,這個類可以沒有被載入。但是使用newInstance()方法的時候,就必須保證:這個類已經載入和這個類已經連線了。而完成上面兩個步驟的正是Class的靜態方法forName()所完成的,這個靜態方法呼叫了啟動類載入器,即載入 java API的那個載入器。現在可以看出,newInstance()實際上是把new這個方式分解為兩步,即首先呼叫Class載入方法載入某個類,然後例項化。這樣分步的好處是顯而易見的。我們可以在呼叫類的靜態載入方法forName時獲得更好的靈活性,提供給了一種降耦的手段。
15、用最簡單的描述來區分new關鍵字和newInstance()方法的區別:
newInstance: 弱型別。低效率。只能呼叫無參構造。
new: 強型別。相對高效。能呼叫任何public構造。 簡單例項如下:
public class People { private String name; private int age; private String gender; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public void say() { System.out.println("Hello world!"); } public String showInfo() { return "My name is " + this.name; } } public class ClassTest { public static void main(String[] args) { try { //先載入類,再建立例項,等同於People tim = new People(); People tim = (People) Class.forName("com.tim.People").newInstance(); tim.say(); // 獲取tim這個物件的類描述資訊, // 可以獲取:類的構造方法,已經宣告的欄位、方法,獲取類或者方法的註解,獲取類的包名、父類,以及判斷類是否是陣列、是否是列舉、是否是介面 // 主要針對不清楚類的內部資訊時,使用該方法獲取 Class peopleClass = tim.getClass(); Field[] peopleField = peopleClass.getDeclaredFields();//獲取類的欄位 for (Field field : peopleField) { System.out.println(field.getName()); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }