初識Java反射機制

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的反射機制會破壞單例模式……

相關文章
相關標籤/搜索