Java基礎—反射

一、反射
  反射就是將java類中的成分映射成相應的java類。比如:構造函數——Constructor,成員變量——Field,成員函數——Method,包——Package等。反射比較消耗內存,性能低。反射的作用是實現框架功能。
二、反射的基石——Class類
  java中的類是用於描述事物的(事物的屬性、事物的行爲),Class類是用於描述java中的類,比如:java類的類名、包名、父類、成員、夠咱函數等信息。內存中的每份字節碼文件都是Class的一個實例對象。
  獲得Class類實例的三種方式:1、類名.class;2、對象.getClass();3、Class.forName(“類名”);
  9個預定義的Class實例對象:8個基本的數據類+void;
  boolean isPrimitive():是否是預定義的Class對象;
  boolean isArray():是否是數組類型。
三、反射相關的類及操作
  1、Constructor類:描述構造函數的類
    獲取某個類的所有構造方法:Constructor[] getConstructors();
    獲取某個類的某一構造函數:Constructor getConstructor(Class… parameterTypes),根據參數列表獲取相應的構造函數;
    通過獲取的構造函數創建對象:T newInstance(Object…initargs).
代碼如下:

/*
用反射的方式創建一個String對象。

步驟:
     1、獲取String的構造函數;
     2、用構造函數創建String對象
*/
import java.lang.reflect.*;
class ConstructorTest
{
    public static void main(String[] args) throws Exception
    {
        //用Class類中的getConstructor方法獲取String類中參數列表爲:StringBuffer sb的構造函數
        Constructor cons = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
        //調用Constructor中的newInstance方法創建對象
        String s = (String)cons.newInstance(new StringBuffer("1234567"));
        System.out.println(s);
    }
}

  2、Field類——描述成員變量的類
    獲取某類中的公有變量:Field getField(String name);
    獲取公有變量值:Object get(Object obj)
    獲取某類中私有的變量:Field getDeclaredField(String name);
    獲取某類中私有變量的值:setAccess(true);Object get(Object obj);
代碼如下:

/*
Field類,描述成員變量的類
步驟:
     1、先定義一個類;
     2、獲取該類的字節碼文件;
     3、獲取該類的構造函數;
     4、建立該類的對象;
     5、獲取該類的成員變量;
     6、獲取該類成員變量的值。

用到的類及方法:Class(getConstructor、getDeclaredConstructor、getFielde、)
                Constructor(newInstance)
                Field(setAccessible、get)
其他說明:getConstructor只能獲取公有的構造函數,要獲取被私有的成員變量,需先對你進行
          用setAccessible處理,才能獲取該成員變量的值。
*/
import java.lang.reflect.*;
class Num
{
    private int x;
    public int y;
    Num(int x,int y)
    {
        this.x = x;
        this.y = y;
    }
}
class FieldTest
{
    public static void main(String[] args)  throws Exception
    {
        //獲取類的字節碼文件
        Class cnum = Num.class;
        //根據字節碼文件獲取該類的構造函數
        Constructor cons = cnum.getDeclaredConstructor(int.class,int.class);
        //創建該類對象
        Num num = (Num)cons.newInstance(7,8);
        //獲取該類中的公有成員變量
        Field fy = cnum.getField("y");
        //獲取該類中的私有成員變量
        Field fx = cnum.getDeclaredField("x");
        //獲取該成員變量的值
        System.out.println(fy.get(num));
        //獲取私有成員變量的值
        fx.setAccessible(true);
        System.out.println(fx.get(num));
    }
}

  4、Method——成員方法
    獲取某類中的方法:Method getMethod(String methodName,Class… parameterTypes);
    調用方法:Object invoke(Object obj,Object…args)
代碼如下:

/*
Method類:描述成員方法的類。
步驟:
     1、獲取類字節碼文件;
     2、獲取該類的構造函數;
     3、建立該類對象;
     4、獲取該類中的替換方法;
     5、用正則表達式將疊詞去除。

用到的類:Class(forName、getConstructor、getMethod)
          Constructor(newInstance)
          Method(invoke)
*/
import java.lang.reflect.*;
class MethodTest
{
    public static void main(String[] args) throws Exception
    {
        //獲取該類字節碼文件
        Class c = Class.forName("java.lang.String");
        //System.out.println(c);
        //獲取該類的構造函數
        Constructor cons = c.getConstructor(String.class);
        //建立該類的對象
        String s = (String)cons.newInstance("hellokkjava!mmhelloffffffworld!");
        System.out.println("原字符串:"+s);
        //獲取該類的替換方法
        Method m = c.getMethod("replaceAll",String.class,String.class);
        //調用替換方法
        s = (String)m.invoke(s,"(.)\\1+","");
        System.out.println("去除疊詞後的字符串:"+s);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章