1.ClassLoader的類加載機制:並不是一次性加載,而是須要的時候加載(運行期間動態加載)(Class文件加載到內存的代碼段),static語句塊在加載後執行一次。dynamic語句塊(就是一個語句塊,用大括號括起來)每次new新的對象都會執行,等同於構造方法中的語句,只不過加載到構造方法以前,用的較少。html
注意參數的大小寫,也不要多加空格。java
看下面這個例子:mysql
1 public class Dynamic { 2 3 public static void main(String[] args) { 4 new A();//不是一次性加載,從結果看出這個分割線的位置 5 System.out.println("___________________"); 6 new B(); 7 8 new C(); 9 new C(); 10 11 new D(); 12 new D(); 13 } 14 15 } 16 17 class A { 18 19 } 20 21 class B { 22 23 } 24 25 class C { 26 static { 27 System.out.println("——————————————靜態類加載——————————————"); 28 } 29 } 30 31 class D { 32 { 33 System.out.println("************動態類加載***********"); 34 } 35 }
下面是未加-verbose:class的結果:sql
___________________ ——————————————靜態類加載—————————————— ************動態類加載*********** ************動態類加載***********
下面是加參數後的結果:編程
2.verbose:冗長的詳細的bootstrap
3.JDK裏的類加載器不少。
4.bootstrap:啓動節點,引導節點。ide
1 public class TestJDKClassLoader { 2 3 public static void main(String[] args) { 4 System.out.println(String.class.getClassLoader()); 5 //System.out.println(com.sum.crypto.provider.DESKeyFactory.class.getClassLoader().getClass().getName()); 6 System.out.println(TestJDKClassLoader.class.getClassLoader()); 7 System.out.println(ClassLoader.getSystemClassLoader()); 8 } 9 10 }
null sun.misc.Launcher$AppClassLoader@45a1472d sun.misc.Launcher$AppClassLoader@45a1472d
5.ClassLoader類在java.lang包裏函數
1 public class TestJDKClassLoader { 2 3 //getClass能夠獲取一個類的定義信息,而後使用反射去訪問其所有信息(包括函數和字段) 4 public static void main(String[] args) { 5 ClassLoader c = TestJDKClassLoader.class.getClassLoader(); 6 while(null!=c) { 7 System.out.println(c.getClass().getName()); 8 //雖然叫parent但並非繼承 9 c = c.getParent(); 10 } 11 } 12 13 }
sun.misc.Launcher$AppClassLoader sun.misc.Launcher$ExtClassLoader
6.對象.getClass至關於類名.class。學習
7.properties文件測試
參考資料:http://blog.csdn.net/netwarning/article/details/1569900
properties文件顧名思義就是屬性文件,能夠在它裏面定義一些字段,這將不須要咱們在代碼中書寫,這些信息從代碼中分離出來了。看下面的例子:
注意在文件裏面就不須要加分號。
1 //文件名爲myProperties.properties 2 3 String driver = "com.mysql.jdbc.Driver" 4 String url = "jdbc:mysql://localhost/myDB"; 5 String name = "root" 6 String password = "123" 7 8 //*************************** 9 Class.forName(driver); 10 Connection con = DriverManager.getConnection(url,name,password); 11 12 //************************** 13 String driver; 14 String url; 15 String name; 16 String password; 17 18 FileInputStream fis = new FileInputStream(myProperties.properties); 19 Properties properties = new Properties(); 20 properties.load(fis); //從輸入流中讀取屬性文件的內容 21 fis.close(); 22 //從屬性文件中讀取相應字段的信息 23 driver = properties.getProperty(driver); 24 url = properties.getProperty(url); 25 name = properties.getProperty(name); 26 password = properties.getProperty(password); 27 28 Class.forName(driver); 29 Connection con = DriverManager.getConnection(url,name,password); 30 31 /* 32 咱們看到數值和代碼已經分離,這樣很方便咱們修改數值! 33 再有必定要注意properties文件中的字段的寫法,不要再多添「」不然會出現問題! 34 由於getProperty()方法返回的是一個字符串! 35 36 我想應該再對這個文件作一下加密處理會更好一些是吧? 37 */
8.Java語言不夠動態,真正動態的語言是JS、Ruby和Python。
9.java的反射機制很重要,是學習SSH的基礎以及面向切面編程Aspect Oriented Programming(AOP)。
10.RC就是Release Candidate(候選版本)的簡稱。從微軟的慣例來看OS的開發步驟是這樣的:內部測試->alpha公測->beta公測->RC版->正式版上市。
11.下面是反射機制的例子:
1 package a; 2 3 import java.lang.reflect.Method; 4 5 /* 6 * properties文件裏只有class=T,注意沒有問號 7 * 實現了代碼和數據的分離,這樣沒必要寫死 8 * 問題:知道類名字,而後new出來一個 9 */ 10 11 //學習SSH時類的名字不少時候都是在配置文件裏的 12 public class TestReflection { 13 14 public static void main(String[] args) throws Exception { 15 /* 16 * 使用new建立一個類的時候,這個類能夠沒有被加載。 17 * 可是使用newInstance()方法的時候, 18 * 就必須保證這個類已加載且類已經鏈接了。 19 */ 20 String str = "a.T";//到時候這個換成從文件裏讀取,靠,必須寫完整路徑 21 22 Class c = Class.forName(str);//加載類 23 /* 24 * newInstance和new的區別在於一個方法一個關鍵字 25 * 且前者要求類已經加載了纔可實例化 26 */ 27 Object obj = c.newInstance(); 28 Method[] methods = c.getMethods(); 29 for(Method m: methods) { 30 //System.out.println(m.getName()); 31 if(m.getName().equals("myMehtod")) { 32 //不能是c或者T.class,由於方法 33 /* 34 * invoke方法是可變參數的方法,傳遞0個或者多個參數 35 * 主要是由於不知道傳遞幾個參數 36 */ 37 m.invoke(obj,2);//必須是obj,不能是c,方法的調用是對象 38 for(Class paramType : m.getParameterTypes()) { 39 System.out.println(paramType.getName()); 40 } 41 } 42 43 if(m.getName().equals("getS")) { 44 Class returnType = m.getReturnType(); 45 System.out.println(returnType.getName()); 46 } 47 } 48 49 } 50 51 } 52 53 class T { 54 //static塊的用法http://www.cnblogs.com/hxsyl/archive/2013/04/16/3024953.html 55 static {//類加載時執行 56 System.out.println("T loaded");//就是爲了證實類已經加載 57 } 58 59 public T() { 60 System.out.println("T constructed"); 61 } 62 63 int i; 64 String s; 65 66 public void myMehtod(int i) { 67 this.i = i; 68 System.out.println("方法調用"); 69 } 70 71 public String getS() { 72 return s; 73 } 74 }
12.理解invoke方法
1 package a; 2 3 /* 4 * 下面這個是網上的代碼,找了很久還就這一個 5 * 看了也仍是沒明白invoke方法 6 */ 7 import java.lang.reflect.Method; 8 9 public class InvokeTester { 10 11 public int add(int param1, int param2) { 12 return param1 + param2; 13 } 14 15 public String echo(String msg) { 16 return "echo:" + msg; 17 } 18 19 public static void main(String[] args) throws Exception { 20 Class classType = InvokeTester.class; 21 Object invokertester = classType.newInstance(); 22 23 Method addMethod = classType.getMethod("add", new Class[] { int.class, 24 int.class }); 25 // Method類的invoke(Object obj,Object args[])方法接收的參數必須爲對象, 26 // 若是參數爲基本類型數據,必須轉換爲相應的包裝類型的對象。invoke()方法的返回值老是對象, 27 // 若是實際被調用的方法的返回類型是基本類型數據,那麼invoke()方法會把它轉換爲相應的包裝類型的對象, 28 // 再將其返回 29 Object result = addMethod.invoke(invokertester, new Object[] { 30 new Integer(100), new Integer(200) }); 31 // 在jdk5.0中有了裝箱 拆箱機制 new Integer(100)能夠用100來代替,系統會自動在int 和integer之間轉換 32 System.out.println(result); 33 34 Method echoMethod = classType.getMethod("echo", 35 new Class[] { String.class }); 36 result = echoMethod.invoke(invokertester, new Object[] { "hello" }); 37 System.out.println(result); 38 } 39 }
13.java的反射機制會破壞單例模式……