天天看點

(八)黑馬程式員——反射

------- <a href="http://www.itheima.com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="blank">android教育訓練</a>、

<a href="http://www.itheima.com" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="blank">java教育訓練</a>、期待與您交流! ----------

A.類的加載概述

當程式使用某個類時,如果該類還未被加載到記憶體中,則系統會通過加載,連結,初始化來實作對類的初始化。      * 加載 

        * 就是指将class檔案讀入記憶體,并為之建立一個Class對象。任何類被使用時系統都會建立一個Class對象。

   * 連接配接

        * 驗證 是否有正确的内部結構,并和其他類協調一緻

        * 準備 負責為類的靜态成員配置設定記憶體,并設定預設初始化值

        * 解析 将類的二進制資料中的符号引用替換為直接引用

   * 初始化  就是我們以前講過的初始化步驟

 B:加載時機

  * 建立類的執行個體

    * 通路類的靜态變量,或者為靜态變量指派

    * 調用類的靜态方法

    * 使用反射方式來強制建立某個類或接口對應的java.lang.Class對象

    * 初始化某個類的子類

    * 直接使用java.exe指令來運作某個主類

類加載器的概述和分類:

    A:類加載器的概述

            負責将。class檔案加載到記憶體中,并為之生成對應的Class對象。雖然我們不需要關心加載機制,但是了解這個我們能更好地了解和運作程式。

    B:類的加載分類

根類加載器:Bootstrap ClassLoader 擴充類加載器:Extension ClassLoader 系統類加載器:System ClassLoader

C:類加載器的作用

根類加載器:!1.引導類加載器,負責Java核心類的加載            擴充類加載器: 2.擴充類加載器,負責目錄中jar包的加載 系統類加載器:3.負責在jvm啟動時加載來自java指令的class檔案,以及classpath環境變量所指定的jar包和類路徑

反射概述

*Java反射機制是在運作狀态中,對于任意一個類,都能夠知道這個類的所有屬性和方法 *對于任意一個類對象,都能夠調用它的任意一個方法和屬性: 這種動态擷取的資訊以及動态調用的任意一個方法和屬性: 要想解剖一個類,必須先要擷取到該類的位元組碼檔案對象。 而解剖使用的就是class類中的方法,是以先要擷取到麼一個位元組碼對應的class類型的對象。

B:三種方式

*a:object類的 getClass()方法,判斷倆個對象是同一個位元組碼檔案 *b:靜态屬性class,鎖對象 *c:class類中的靜态方法forName(),讀取配置檔案

反射——通過反射擷取帶參構造方法并使用

Constructor

       class類中newInstance()方法是使用該類無參的構造函數建立對象,如果一個類沒有無參的構造函數,就不能這樣建立了,可以調用class類的getConstructor(String。          class,int.class)方法擷取一個指定的構造函數然後Constructor類的newInstance(“張三”,20)方法建立對象        反射——通過反射擷取成員變量并使用

Filed

        *class.getFIled(String)方法可以擷取類中的指定字段(可見的),如果是私有的可以用getDeclaedFiled("name")方法擷取,通過set(obj,“李四”)方法可以設定指定對象上         該字段的值,如果是私有的需要先調用setAccessible(true)設定通路權限,用擷取的指定的字段調用get(obj)可以擷取指定對象中該字段值       反射——通過反射擷取方法并使用

Method

         *class.getMethod(String,class....)方法可以擷取類中的指定方法,class.getDeclareMethod(String,class...)"方法擷取類中的指定方法如果調用的可以用invoke("name")       方法invoke(object,object.....)可以調用該方法,class.getMethod("eat") invoke(obj)Class.getMethod("eat",int.class) inhjvooke(obj,10) 反射——通過反射越過泛型檢查 ArraryList<Integer>的一個對象,在這個集合中添加字元串資料,如何實作呢?

package it.heima.text;
import java.lang.reflect.Method;
import java.util.ArrayList;


public class Text1 {
public static void main(String[] args) throws Exception {
//建立Arraylist集合
ArrayList<String> list = new ArrayList<String>();
//添加字元串
list.add("abc");
list.add("def");
//擷取位元組碼檔案
Class clazz=Class.forName("it.heima.text");
//擷取裡面的方法
Method m=clazz.getMethod("add", Object.class);
//執行
m.invoke("add", list);
System.out.println(list);
}
}
           

反射——通過反射寫一個通過某個對象屬性未指定得值

            * public void setProperty(Object obj, String propertyName, Object value){},此方法可将obj對象中名為propertyName的屬性的值設定為value 。

package it.heima.text;


public class Text3 {
/**
* * A:案例示範
* public void setProperty(Object obj, String propertyName, Object value){},
* 此方法可将obj對象中名為propertyName的屬性的值設定為value。
* @throws Exception 
*/
public static void main(String[] args) throws Exception {
Student s=new Student();
System.out.println(s);
Tool t=new Tool();
t.setProperty(s, "張三", 23);
System.out.println(s);
}
}
package it.heima.text;


public class Student {
private String name;
private int age;
public Student(){
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
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;
}


@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
package it.heima.text;


import java.lang.reflect.Field;


public class Tool {
public void setProperty(Object obj,String PropersyName,Object value) throws Exception{
//擷取位元組碼檔案
Class clazz=obj.getClass();
//暴力去反
Field f=clazz.getDeclaredField(PropersyName);
//去掉權限
f.setAccessible(true);
//設定值
f.set(obj, value);
}


}
           

反射_(練習)        * 已知一個類,定義如下: 

       * package cn.itcast.heima;

       *         public class DemoClass {

                public void run() {

                    System.out.println("welcome to heima!");

                }

            }

     * (1) 寫一個Properties格式的配置檔案,配置類的完整名稱。 

     * (2) 寫一個程式,讀取這個Properties配置檔案,獲得類的完整名稱并加載這個類,用反射的方式運作run方法。

package it.heima.text;


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;


/*思路
 * 1.通過建立輸入流關聯“xxx.properties”
 * 2.讀取這個配置檔案擷取這個類中的所有名稱并且加載這個類,通過反射來運作run方法
 * 
 * */

public class Text2 {
public static void main(String[] args) throws Exception {
// 1.通過建立輸入流關聯“xxx.properties”
BufferedReader br=new BufferedReader(new FileReader("xxx.propertise"));
//擷取“xxx.properties”的位元組碼
Class clazz=Class.forName(br.readLine());
//建立新執行個體
   DemoClass c=(DemoClass) clazz.newInstance();
   //運作run方法
c.run();
}
}
package it.heima.text;


public class DemoClass {
public void run() {

}
}
           

動态代理

package it.heima動态代理;


import java.lang.reflect.Proxy;


public class Demo {
public static void main(String[] args) {
Method methodimpl = new Methodimpl();
methodimpl.login();
methodimpl.submit();

System.out.println("---------");

MyInvocationHandler_Demo proxy = new MyInvocationHandler_Demo(methodimpl);
Method mProxy = (Method) Proxy.newProxyInstance(
methodimpl.getClass().getClassLoader() ,
methodimpl.getClass().getInterfaces(), 
proxy);
mProxy.login();
mProxy.submit();
}
}


package it.heima動态代理;


public interface Method1 {
public void login();
public void submit();


}


package it.heima動态代理;


public class Methodimpl implements Method {


@Override
public void login() {
System.out.println("實際:登陸");
}


@Override
public void submit() {
System.out.println("實際:送出");
}
}


package it.heima動态代理;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;


public class MyInvocationHandler_Demo implements InvocationHandler {
private Object target;


public MyInvocationHandler_Demo(Object target) {
this.target = target;
}


@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("代理前:權限校驗");
method.invoke(target, args);
System.out.println("代理後:日志記錄");
return null;
}
}
           
</pre><pre code_snippet_id="1608606" snippet_file_name="blog_20160313_6_2623684" name="code" class="java">
package it.heima動态代理;


public interface Method {
<span style="white-space: pre;"></span>
<span style="white-space: pre;"></span>public void login();
<span style="white-space: pre;"></span>
<span style="white-space: pre;"></span>public void submit();


}
           

package it.heima動态代理;

public interface Method {

public void login();

public void submit();

}