03.反射雜談

1.什麼是反射?
反射就是動態加載對象,並對對象進行剖析。在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法,這種動態獲取信息以及動態調用對象方法的功能成爲Java反射機制。
 
2.Java反射機制的做用
1). 在運行時判斷任意一個對象所屬的類
2). 在運行時構造任意一個類的對象
3). 在運行時判斷任意一個類所具備的成員變量和方法
4). 在運行時調用任意一個對象的方法
 
3.java反射機制提供了什麼功能?
1). 在運行時可以判斷任意一個對象所屬的類
2). 在運行時構造任意一個類的對象
3). 在運行時判斷任意一個類所具備的成員變量和方法
4). 在運行時調用任一對象的方法
5). 在運行時建立新類對象
 
4.哪裏用到反射機制?
各類框架用的最多的就是反射
加載驅動
讀取配置文件
 
5.運用反射的優缺點
優勢:
    反射提升了程序的靈活性和擴展性,下降耦合性,提升自適應能力。它容許程序建立和控制任何類的對象,無需提早硬編碼目標類
缺點:
   (1)性能問題:使用反射基本上是一種解釋操做,用於字段和方法接入時要遠慢於直接代碼。所以反射機制主要應用在對靈活性和擴展性要求很高的系統框架上,普通程序不建議使用。
   (2)使用反射會模糊程序內內部邏輯:程序員但願在源代碼中看到程序的邏輯,反射等繞過了源代碼的技術,於是會帶來維護問題。反射代碼比相應的直接代碼更復雜。
 
6.如何使用java的反射?
a. 經過一個全限類名建立一個對象
1)、Class.forName(「全限類名」); 例如:com.mysql.jdbc.Driver Driver類已經被加載到 jvm中,而且完成了類的初始化工做就好了
2)、類名.class; 獲取Class<?> clz 對象
3)、對象.getClass();
b. 獲取構造器對象,經過構造器new出一個對象
1). Class.getConstructor([String.class]);
2). Con.newInstance([參數]);
c. 經過class對象建立一個實例對象(就至關與new類名()無參構造器)
1). Class.newInstance();
d. 經過class對象得到一個屬性對象
1)、Field c=clz.getFields():得到某個類的全部的公共(public)的字段,包括父類中的字段。
2)、Field c=clz.getDeclaredFields():得到某個類的全部聲明的字段,即包括public、private和proteced,可是不包括父類的申明字段 e.
e、經過class對象得到一個方法對象
1). Class.getMethod(「方法名」,class……parameaType);(只能獲取公共的)
2). Class.getDeclareMethod(「方法名」);(獲取任意修飾的方法,不能執行私有)
3) M.setAccessible(true);(讓私有的方法能夠執行)
f. 讓方法執行
1). Method.invoke(obj實例對象,obj可變參數);-----(有返回值的)
 
7.反射重要藉助哪四個類?
1)、Class:類的對象;
2)、Constructor:類的構造方法
3)、Field:類中的屬性對象
4)、Method:類中的方法對象
 
8.得到一個類的類對象有哪些方式?
 
方法1:類型.class,例如:String.class
 
方法2:對象.getClass(),例如:"hello".getClass()
 
 方法3:Class.forName(),例如:Class.forName("java.lang.String")
 
9.如何經過反射建立對象?

方法1:經過類對象調用newInstance()方法,例如:String.class.newInstance()
 
方法2:經過類對象的getConstructor()或getDeclaredConstructor()方法得到構造器(Constructor)對象並調用其newInstance()方法建立對象,例如:String.class.getConstructor(String.class).newInstance("Hello");
 
10.如何經過反射獲取和設置對象私有字段的值?
能夠經過類對象的getDeclaredField()方法字段(Field)對象,而後再經過字段對象的setAccessible(true)將其設置爲能夠訪問,接下來就能夠經過get/set方法來獲取/設置字段的值了。
 
11.如何經過反射調用對象的方法?
import java.lang.reflect.Method;
class MethodInvokeTest {
    public static void main(String[] args) throws Exception {
        String str = "hello";
        Method m = str.getClass().getMethod("toUpperCase");
        System.out.println(m.invoke(str));  // HELLO
    }
}
 
12.反射中,Class.forName 和 ClassLoader 區別。
Class.forName(className)方法,其實調用的方法是Class.forName(className,true,classloader);注意看第2個boolean參數,它表示的意思,在loadClass後必須初始化。比較下咱們前面準備jvm加載類的知識,咱們能夠清晰的看到在執行過此方法後,目標對象的 static塊代碼已經被執行,static參數也已經被初始化。
 再看ClassLoader.loadClass(className)方法,其實他調用的方法是ClassLoader.loadClass(className,false);仍是注意看第2個 boolean參數,該參數表示目標對象被裝載後不進行連接,這就意味這不會去執行該類靜態塊中間的內容
 
13.如何獲取類的class對象
Class 類的實例表示正在運行的 Java 應用程序中的類和接口。
獲取類的Class對象有多種方式:
調用getClass

Boolean var1 = true;
Class<?> classType2 = var1.getClass();
System.out.println(classType2);
輸出:class java.lang.Boolean
 
運用.class 語法

Class<?> classType4 = Boolean.class;
System.out.println(classType4);
輸出:class java.lang.Boolean
 
運用static method Class.forName()

Class<?> classType5 = Class.forName("java.lang.Boolean");
System.out.println(classType5);
輸出:class java.lang.Boolean
 
運用primitive wrapper classes的TYPE 語法
這裏返回的是原生類型,和Boolean.class返回的不一樣
 
Class<?> classType3 = Boolean.TYPE;
System.out.println(classType3);   輸出:boolean
 
14.如何獲取類的fields
能夠經過反射機制獲得某個類的某個屬性,而後改變對應於這個類的某個實例的該屬性值。JAVA 的Class<T>類提供了幾個方法獲取類的屬性。

public FieldgetField(String name)
返回一個 Field 對象,它反映此 Class 對象所表示的類或接口的指定公共成員字段

public Field[]
 getFields()
返回一個包含某些 Field 對象的數組,這些對象反映此 Class 對象所表示的類或接口的全部可訪問公共字段

public FieldgetDeclaredField(Stringname)
返回一個 Field 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明字段

public Field[]
 getDeclaredFields()

返回 Field 對象的一個數組,這些對象反映此 Class 對象所表示的類或接口所聲明的全部字段
 
15.如何獲取類的constructor
經過反射機制獲得某個類的構造器,而後調用該構造器建立該類的一個實例
,Class<T>類提供了幾個方法獲取類的構造器。
public Constructor<T>
 getConstructor(Class<?>...
 parameterTypes)
返回一個 Constructor 對象,它反映此 Class 對象所表示的類的指定公共構造方法
public Constructor<?>[]
 getConstructors()
返回一個包含某些 Constructor 對象的數組,這些對象反映此 Class 對象所表示的類的全部公共構造方法
public Constructor<T>
 getDeclaredConstructor(Class<?>...
 parameterTypes)
返回一個 Constructor 對象,該對象反映此 Class 對象所表示的類或接口的指定構造方法
public Constructor<?>[]
 getDeclaredConstructors()
返回 Constructor 對象的一個數組,這些對象反映此 Class 對象表示的類聲明的全部構造方法。它們是公共、保護、默認(包)訪問和私有構造方法
相關文章
相關標籤/搜索