2017 - 10 -32 新特性

1 GUI
(1)用戶圖形界面
GUI:圖形用戶接口 用圖形的方式,來顯示計算機操作的界面,這樣更爲直觀
CLI:命令行用戶接口 就是常見的Dos命令操作 需要記憶一些常見的命令,操作不直觀
(2)兩個包
awt和swing包的概述
java.awt:Abstract Window ToolKit (抽象窗口工具包),需要調用本地系統方法實現功能。屬重量級控件。
javax.swing:在AWT的基礎上,建立的一套圖形界面系統,其中提供了更多的組件,而且完全由Java實現。增強了移植性,屬輕量級控件。
(3)事件監聽機制
A:事件源    事件發生的地方
B:事件      就是要發生的事情
C:事件處理  就是針對發生的事情做出的處理方案
D:事件監聽  就是把事件源和事件關聯起來

舉例:人受傷事件

   事件源:人(具體的對象)
     Person p1 = new Person("張三");
     Person p2 = new Person(李四);
   事件:受傷
     interface 受傷接口{
          一拳();
          一腳();
          一板磚();
    }
   事件處理:
       受傷處理類 implements 受傷接口{
       一拳(){ System.out.println("鼻子流血了,送到衛生間洗洗");
       一腳(){ System.out.println("暈倒了,送到通風處");
       一板磚(){System.out.println("頭破血流,送到太平間");
}      
   事件監聽:
      p1.註冊監聽(受傷接口)

(4)適配器
問題:接口(方法比較多) -- 實現類(僅僅適用一個,也得把其他的實現給提供了,哪怕是空實現)  太麻煩了
解決方案:接口(方法比較多) -- 適配器類(實現接口,僅僅實現) -- 實現類(問哪個重寫哪個)

2 類加載器
   當程序要使用某個類時,如果該類還未被加載到內存中,則系統會通過加載,連接,初始化三步來實現對這個類進行初始化。

加載 
   就是指將class文件讀入內存,併爲之創建一個Class對象。
   任何類被使用時系統都會建立一個Class對象。

連接
   驗證    是否有正確的內部結構,並和其他類協調一致
   準備    負責爲類的靜態成員分配內存,並設置默認初始化值
   解析    將類的二進制數據中的符號引用替換爲直接引用
   初始化  就是我們以前講過的初始化步驟

類初始化時機
創建類的實例
訪問類的靜態變量,或者爲靜態變量賦值
調用類的靜態方法
使用反射方式來強制創建某個類或接口對應的java.lang.Class對象
初始化某個類的子類
直接使用java.exe命令來運行某個主類

類加載器
負責將.class文件加載到內在中,併爲之生成對應的Class對象。
雖然我們不需要關心類加載機制,但是瞭解這個機制我們就能更好的理解程序的運行。

類加載器的組成
Bootstrap ClassLoader 根類加載器
Extension ClassLoader 擴展類加載器
Sysetm ClassLoader    系統類加載器

3 反射
    JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。

反射:就是通過class文件對象,去使用該文件中的成員變量,構造方法,成員方法。

Person p = new Person();
p.使用

要想這樣使用,首先你必須得到class文件對象,其實也就是得到Class類的對象。
Class類:
        成員變量        Field
        構造方法        Constructor
        成員方法        Method

獲取class文件對象的方式:
 A:Object類的getClass()方法
 B:數據類型的靜態屬性class
 C:Class類中的靜態方法
     public static Class forName(String className)

一般我們到底使用誰呢?
   A:自己玩        任選一種,第二種比較方便
   B:開發          第三種
   爲什麼呢?因爲第三種是一個字符串,而不是一個具體的類名。這樣我們就可以把這樣的字符串配置到配置文件中。
-----------------------------------------------------
public class Person {
        private String name;
        int age;
        public String address;


        public Person() {
       }

        ....

         @Override
        public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address+ "]";
        }
}

public class ReflectDemo {
             public static void main(String[] args) throws ClassNotFoundException {
              // 方式1
              Person p = new Person();
              Class c = p.getClass();

              Person p2 = new Person();
              Class c2 = p2.getClass();

              System.out.println(p == p2);// false
              System.out.println(c == c2);// true

              // 方式2
              Class c3 = Person.class;
              // int.class;
              // String.class;
              System.out.println(c == c3);

              // 方式3
              // ClassNotFoundException
              Class c4 = Class.forName("cn.itcast_01.Person");//必須全路徑,否則找不到
              System.out.println(c == c4);
        }
}

4 通過反射獲取構造方法
(1)通過反射獲取無參構造方法

public class ReflectDemo {
        public static void main(String[] args) throws Exception {
                // 獲取字節碼文件對象
                Class c = Class.forName("cn.itcast_01.Person");

                // 獲取構造方法
                // public Constructor[] getConstructors():所有公共構造方法
                // public Constructor[] getDeclaredConstructors():所有構造方法
                // Constructor[] cons = c.getDeclaredConstructors();
                // for (Constructor con : cons) {
                // System.out.println(con);
                // }

                // 獲取單個構造方法
                // public Constructor<T> getConstructor(Class<?>... parameterTypes)
                // 參數表示的是:你要獲取的構造方法的構造參數個數及數據類型的class字節碼文件對象
                Constructor con = c.getConstructor();// 返回的是構造方法對象

                // Person p = new Person();
                // System.out.println(p);
                // public T newInstance(Object... initargs)
                // 使用此 Constructor 對象表示的構造方法來創建該構造方法的聲明類的新實例,並用指定的初始化參數初始化該實例。
                Object obj = con.newInstance();
                System.out.println(obj);

                // Person p = (Person)obj;
                // p.show();
}
}

(2)通過反射獲取帶參構造方法並使用
需求:通過反射去獲取該構造方法並使用:
public Person(String name, int age, String address)
Person p = new Person("林青霞",27,"北京");
System.out.println(p);

public class ReflectDemo2 {
         public static void main(String[] args) throws Exception {
                // 獲取字節碼文件對象
                Class c = Class.forName("cn.itcast_01.Person");

                // 獲取帶參構造方法對象
                // public Constructor<T> getConstructor(Class<?>... parameterTypes)
                Constructor con = c.getConstructor(String.class, int.class,String.class);

                // 通過帶參構造方法對象創建對象
                // public T newInstance(Object... initargs)
                Object obj = con.newInstance("林青霞", 27, "北京");

                System.out.println(obj);
                //輸出:Person[name=林青霞,age=27,address=北京]
}
}

(3)通過反射獲取私有構造方法並使用
private Person(String name){}
Person p = new Person("風清揚");
System.out.println(p);

public class ReflectDemo3 {
      public static void main(String[] args) throws Exception {
                // 獲取字節碼文件對象
                Class c = Class.forName("cn.itcast_01.Person");

                // 獲取私有構造方法對象
                // NoSuchMethodException:每個這個方法異常
                // 原因是一開始我們使用的方法只能獲取公共的,下面這種方式就可以了。
                Constructor con = c.getDeclaredConstructor(String.class);

                // 用該私有構造方法創建對象
                // IllegalAccessException:非法的訪問異常。
                // 暴力訪問
                con.setAccessible(true);// 值爲true則指示反射的對象在使用時應該取消Java語言訪問檢查。
                Object obj = con.newInstance("風清揚");

                System.out.println(obj);
}
}
 
5 通過反射獲取成員變量
public class ReflectDemo {
        public static void main(String[] args) throws Exception {
                // 獲取字節碼文件對象
                Class c = Class.forName("cn.itcast_01.Person");

                // 獲取所有的成員變量
                // Field[] fields = c.getFields();
                // Field[] fields = c.getDeclaredFields();
                // for (Field field : fields) {
                // System.out.println(field);
                // }

                /*
                * Person p = new Person(); p.address = "北京"; System.out.println(p);
                 */

                // 通過無參構造方法創建對象
                Constructor con = c.getConstructor();
                Object obj = con.newInstance();
                System.out.println(obj);

                // 獲取單個的成員變量
                // 獲取address並對其賦值
                Field addressField = c.getField("address");
                // public void set(Object obj,Object value)
                // 將指定對象變量上此 Field 對象表示的字段設置爲指定的新值。
                addressField.set(obj, "北京"); // 給obj對象的addressField字段設置值爲"北京"
                System.out.println(obj);

                // 獲取name並對其賦值
                // NoSuchFieldException
                Field nameField = c.getDeclaredField("name");
                // IllegalAccessException
                nameField.setAccessible(true);
                nameField.set(obj, "林青霞");
                System.out.println(obj);

                // 獲取age並對其賦值
                Field ageField = c.getDeclaredField("age");
                ageField.setAccessible(true);
                ageField.set(obj, 27);
                System.out.println(obj);
     }
}

6 通過反射獲取成員方法
public class ReflectDemo {
      public static void main(String[] args) throws Exception {
                // 獲取字節碼文件對象
                Class c = Class.forName("cn.itcast_01.Person");

                // 獲取所有的方法
                // Method[] methods = c.getMethods(); // 獲取自己的包括父親的公共方法
                // Method[] methods = c.getDeclaredMethods(); // 獲取自己的所有的方法
                // for (Method method : methods) {
                // System.out.println(method);
                // }

                Constructor con = c.getConstructor();
                Object obj = con.newInstance();

                /*
                 * Person p = new Person(); p.show();
                */

                // 獲取單個方法並使用
                // public void show()
                // public Method getMethod(String name,Class<?>... parameterTypes)
                // 第一個參數表示的方法名,第二個參數表示的是方法的參數的class類型
                Method m1 = c.getMethod("show");
                // obj.m1(); // 錯誤
                // public Object invoke(Object obj,Object... args)
                // 返回值是Object接收,第一個參數表示對象是誰,第二參數表示調用該方法的實際參數
                m1.invoke(obj); // 調用obj對象的m1方法

                System.out.println("----------");
                // public void method(String s)
                Method m2 = c.getMethod("method", String.class);
                m2.invoke(obj, "hello");
                System.out.println("----------");

                // public String getString(String s, int i)
                Method m3 = c.getMethod("getString", String.class, int.class);
                Object objString = m3.invoke(obj, "hello", 100);
                System.out.println(objString);
                // String s = (String)m3.invoke(obj, "hello",100);
                // System.out.println(s);
                System.out.println("----------");

                // private void function()
                Method m4 = c.getDeclaredMethod("function");
                m4.setAccessible(true);
                m4.invoke(obj);
       }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章