一、反射
反射就是將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);
}
}