說到反射,相信有過編程經驗的人都不會陌生。反射機制讓Java變得更加的靈活。反射機制在Java的衆多特性中是很是重要的一個。下面就讓咱們一點一點了解它是怎麼一回事。
什麼是反射
在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。
反射有什麼用
1,在運行時判斷任意一個對象所屬的類;
2,在運行時構造任意一個類的對象;
3,在運行時判斷任意一個類所具備的成員變量和方法;
4,在運行時調用任意一個對象的方法;
5,生成動態代理。
反射的API
學習一門語言,一種比較好的方式就是看它的API文檔,由於它的API是最權威的,最準確的。下面咱們一塊兒看看JDK的API對於反射是如何描述的吧!
與反射有關的全部接口以及類都在java.lang.reflect包裏。
接口
接口摘要
AnnotatedElement
表示目前正在此 VM 中運行的程序的一個已註釋元素。
GenericArrayType
GenericArrayType 表示一種數組類型,其組件類型爲參數化類型或類型變量。
GenericDeclaration
聲明類型變量的全部實體的公共接口。
InvocationHandler
InvocationHandler 是代理實例的調用處理程序 實現的接口。
Member
成員是一種接口,反映有關單個成員(字段或方法)或構造方法的標識信息。
ParameterizedType
ParameterizedType 表示參數化類型,如 Collection<String>。
Type
Type 是 Java 編程語言中全部類型的公共高級接口。
TypeVariable<D extends GenericDeclaration>
TypeVariable 是各類類型變量的公共高級接口。
WildcardType
WildcardType 表示一個通配符類型表達式,如 ?、? extends Number 或 ? super Integer。
類
類摘要
AccessibleObject
AccessibleObject 類是 Field、Method 和 Constructor 對象的基類。
Array
Array 類提供了動態建立和訪問 Java 數組的方法。
Constructor<T>
Constructor 提供關於類的單個構造方法的信息以及對它的訪問權限。
Field
Field 提供有關類或接口的單個字段的信息,以及對它的動態訪問權限。
Method
Method 提供關於類或接口上單獨某個方法(以及如何訪問該方法)的信息。
Modifier
Modifier 類提供了 static 方法和常量,對類和成員訪問修飾符進行解碼。
Proxy
Proxy 提供用於建立動態代理類和實例的靜態方法,它仍是由這些方法建立的全部動態代理類的超類。
ReflectPermission
反射操做的 Permission 類。
下面給你們寫了一個小實例:
[java] view plaincopy在CODE上查看代碼片派生到個人代碼片
package reflection;
public class UserInfo {
private Integer id;
private String userName;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString(){
return this.getClass().getName();
}
}
[java] view plaincopy在CODE上查看代碼片派生到個人代碼片
package reflection;
public class GetClass {
public boolean ClassCheck(){
try {
System.out.println("第一種,經過類自己得到對象");
Class UserClass = this.getClass();
System.out.println("第一種方式成功!類名:"+UserClass.toString()+"\n");
System.out.println("第二種,經過子類實例獲取父類");
UserInfo ui = new UserInfo();
UserClass = ui.getClass();
Class SubUserClass = UserClass.getSuperclass();
System.out.println("第二種方式成功!類名:"+SubUserClass.toString()+"\n");
System.out.println("第三種,經過類名加.class得到對象");
Class ForClass = reflection.UserInfo.class;
System.out.println("第三種方式成功!類名:"+ForClass.toString()+"\n");
System.out.println("第四種,經過類名的字符串得到對象");
Class ForName = Class.forName("reflection.UserInfo");
System.out.println("第四種方式成功!類名:"+ForName.toString()+"\n");
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
public String toString(){
return this.getClass().getName();
}
public static void main(String[] args) {
GetClass gc = new GetClass();
gc.ClassCheck();
if (gc.ClassCheck()) {
System.out.println("全部反射所有成功!");
}
else {
System.out.println("反射有問題,請檢查!");
}
}
}
向你們介紹了什麼是Java的反射機制,以及Java的反射機制有什麼用。上一篇比較偏重理論,理論的東西給人講出來總感受虛無縹緲,仍是結合一些實例比較形象具體。那麼今天就結合更多的實例具體說說。
實例一:得到完整的類名
[java] view plaincopy在CODE上查看代碼片派生到個人代碼片
package reflection.getclassname;
//得到完整的類名
public class GetClassName {
public String getNameByClass() {
String name = "";
System.out.println("經過類自己得到對象");
Class UserClass = this.getClass();
System.out.println("得到對象成功!\n");
System.out.println("經過類對象得到類名");
name = UserClass.getName();
System.out.println("得到類名成功!");
return name;
}
public static void main(String[] args) {
GetClassName gcn = new GetClassName();
System.out.println("類名爲:"+gcn.getNameByClass());
}
}
運行結果:
經過類自己得到對象
得到對象成功!
經過類對象得到類名
得到類名成功!
類名爲:reflection.getclassname.GetClass Name
實例二:得到類的屬性
[java] view plaincopy在CODE上查看代碼片派生到個人代碼片
package reflection.getfields;
import java.lang.reflect.Field;
//得到類的屬性
public class GetFields {
public static void getFieldNames(String className) {
try {
//得到類名
Class c = Class.forName(className);
//得到全部屬性
Field[] fds = c.getFields();
for (int i=0; i<fds.length; i++)
{
String fn = fds[i].getName();
Class tc = fds[i].getType();
String ft = tc.getName();
System.out.println("該屬性的名字爲:"+fn+",該屬性的類型爲:"+ft);
}
}catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
GetFields.getFieldNames("reflection.getfields.FieldInfo");
}
}
運行結果:
該屬性的名字爲:id,該屬性的類型爲:java.lang.String
該屬性的名字爲:username,該屬性的類型爲:java.lang.String
實例三:得到類實現的接口
[java] view plaincopy在CODE上查看代碼片派生到個人代碼片
package reflection.getinterfaces;
//得到類實現的接口
public class GetInterfaces {
public static void getInterfaces(String className) {
try {
//取得類
Class cl = Class.forName(className);
Class[] ifs = cl.getInterfaces();
for (int i = 0; i<ifs.length;i++)
{
String IName = ifs[i].getName();
System.out.println("該類實現的接口名字爲:"+IName);
}
}catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
GetInterfaces.getInterfaces("reflection.getinterfaces.Student");
}
}
運行結果:
該類實現的接口名字爲:reflection.getinterfaces.Person
實例四:得到類及其屬性的修飾符
[java] view plaincopy在CODE上查看代碼片派生到個人代碼片
package reflection.getmodifiers;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import reflection.UserInfo;
//得到類及其屬性的修飾符
public class GetModifiers {
private String username = "liu shui jing";
float f = Float.parseFloat("1.000");
public static final int i = 37;
//得到類的修飾符
public static String useModifiers(UserInfo ui) {
Class uiClass = ui.getClass();
int m = uiClass.getModifiers();
return Modifier.toString(m);
}
//得到本類屬性的修飾符
public void checkThisClassModifiers() {
Class tc = this.getClass();
Field fl[] = tc.getDeclaredFields();
for(int i=0;i<fl.length;i++)
{
System.out.println("第"+(i+1)+"個屬性的修飾符爲:"+Modifier.toString(fl[i].getModifiers()));
}
}
public static void main(String[] args) {
//得到類的修飾符
UserInfo ui =new UserInfo();
System.out.println("得到這個類的修飾符:"+GetModifiers.useModifiers(ui)+"\n");
//得到本類屬性的修飾符
GetModifiers gm = new GetModifiers();
gm.checkThisClassModifiers();
}
}
運行結果:
得到這個類的修飾符:public
第1個屬性的修飾符爲:private
第2個屬性的修飾符爲:
第3個屬性的修飾符爲:public static final
實例五:得到類的構造函數
[java] view plaincopy在CODE上查看代碼片派生到個人代碼片
package reflection.getconstructor;
import java.lang.reflect.Constructor;
//得到類的構造函數
public class GetConstructor {
//構造函數一
GetConstructor(int a) {
}
//構造函數二
GetConstructor(int a, String b) {
}
public static void getConstructorInfo(String className) {
try {
//得到類的對象
Class cl =Class.forName(className);
System.out.println("得到類"+className+"全部的構造函數");
Constructor ctorlist[] = cl.getDeclaredConstructors();
System.out.println("遍歷構造函數\n");
for(int i =0 ; i<ctorlist.length; i++)
{
Constructor con = ctorlist[i];
System.out.println("這個構造函數的名字爲:"+con.getName());
System.out.println("經過構造函數得到這個類的名字爲:"+con.getDeclaringClass());
Class cp[] = con.getParameterTypes();
for (int j=0; j<cp.length; j++)
{
System.out.println("參數 "+j+" 爲 "+cp[j]+"\n");
}
}
}catch (Exception e) {
System.err.println(e);
}
}
public static void main(String[] args) {
GetConstructor.getConstructorInfo("reflection.getconstructor.GetConstructor");
}
}
運行結果:
得到類reflection.getconstructor.GetConstructor全部的構造函數
遍歷構造函數
這個構造函數的名字爲:reflection.getconstructor.GetConstructor
經過構造函數得到這個類的名字爲:class reflection.getconstructor.GetConstructor
參數 0 爲 int
這個構造函數的名字爲:reflection.getconstructor.GetConstructor
經過構造函數得到這個類的名字爲:class reflection.getconstructor.GetConstructor
參數 0 爲 int
參數 1 爲 class java.lang.String
實例六:得到父類
[java] view plaincopy在CODE上查看代碼片派生到個人代碼片
package reflection.getparentclass;
//得到父類
public class GetParentClass {
public static String getParentClass(UserInfoMore uim) {
//得到父類
Class uimc = uim.getClass().getSuperclass();
System.out.println("得到父類的名字爲:"+uimc.getName());
return uimc.getName();
}
public static void searchParentClass() {
}
public static void main(String[] args) {
UserInfoMore uim = new UserInfoMore();
System.out.println("成功得到UserInfoMore的父類:"+GetParentClass.getParentClass(uim));
}
}
運行結果:
得到父類的名字爲:reflection.UserInfo
成功得到UserInfoMore的父類:reflection.UserInfo
實例七:得到類的方法
[java] view plaincopy在CODE上查看代碼片派生到個人代碼片
package reflection.getmethod;
import java.lang.reflect.Method;
//得到類的方法
public class GetMethod {
public static void getMethods(String className) {
try {
System.out.println("開始遍歷類"+className+".class");
//得到類名
Class cls = Class.forName(className);
//利用方法得到全部該類的方法
System.out.println("利用類的getDeclaredMethods得到類的全部方法");
Method ml[] =cls.getDeclaredMethods();
System.out.println("遍歷得到的方法數組\n");
for (int i = 0 ;i<ml.length;i++)
{
System.out.println("開始遍歷第"+(i+1)+"個方法");
Method m = ml[i];
System.out.println("開始獲取方法的變量類型");
Class ptype[] = m.getParameterTypes();
for (int j=0; j<ptype.length; j++)
{
System.out.println("方法參數"+j+"類型爲"+ptype[j]);
}
Class gEx[] = m.getExceptionTypes();
for (int j=0 ; j<gEx.length; j++)
{
System.out.println("異常"+j+"爲"+ gEx[j]);
}
System.out.println("該方法的返回值類型爲:"+m.getReturnType()+"\n");
}
}catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
GetMethod.getMethods("reflection.UserInfo");
}
}
運行結果:
開始遍歷類reflection.UserInfo.class
利用類的getDeclaredMethods得到類的全部方法
遍歷得到的方法數組
開始遍歷第1個方法
開始獲取方法的變量類型
該方法的返回值類型爲:class java.lang.String
開始遍歷第2個方法
開始獲取方法的變量類型
該方法的返回值類型爲:class java.lang.Integer
開始遍歷第3個方法
開始獲取方法的變量類型
方法參數0類型爲class java.lang.String
該方法的返回值類型爲:void
開始遍歷第4個方法
開始獲取方法的變量類型
該方法的返回值類型爲:class java.lang.String
開始遍歷第5個方法
開始獲取方法的變量類型
方法參數0類型爲class java.lang.Integer
該方法的返回值類型爲:void
開始遍歷第6個方法
開始獲取方法的變量類型
該方法的返回值類型爲:class java.lang.String
開始遍歷第7個方法
開始獲取方法的變量類型
方法參數0類型爲class java.lang.String
該方法的返回值類型爲:void
java