天天看點

JAVA反射中類的構造函數,成員變量,成員方法的使用前言:本文主要介紹反射的經常使用的構造函數,成員變量,成員方法的使用,從網絡上搜尋了一些資料,自己寫了列子,主要為閱讀者初級使用反射做指導。一、Class類的對象二、類中最重要的三個資訊三、使用舉例

前言:本文主要介紹反射的經常使用的構造函數,成員變量,成員方法的使用,從網絡上搜尋了一些資料,自己寫了列子,主要為閱讀者初級使用反射做指導。

一、Class類的對象

獲得Class對象的方法

下表列出了幾種得到Class類的方法,以供大家參考。

Class object 誕生管道 示例

運用getClass()

注:每個class 都有此函數

String str = "abc";

Class c1 = str.getClass();

運用

Class.getSuperclass()

Button b = new Button();

Class c1 = b.getClass();

Class c2 = c1.getSuperclass();

運用static method

Class.forName()

(最常被使用)

Class c1 = Class.forName ("java.lang.String");

Class c2 = Class.forName ("java.awt.Button");

Class c3 = Class.forName ("java.util.LinkedList$Entry");

Class c4 = Class.forName ("I");

Class c5 = Class.forName ("[I");

運用

.class 文法

Class c1 = String.class;

Class c2 = java.awt.Button.class;

Class c3 = Main.InnerClass.class;

Class c4 = int.class;

Class c5 = int[].class;

運用

primitive wrapper classes

的TYPE 文法

Class c1 = Boolean.TYPE;

Class c2 = Byte.TYPE;

Class c3 = Character.TYPE;

Class c4 = Short.TYPE;

Class c5 = Integer.TYPE;

Class c6 = Long.TYPE;

Class c7 = Float.TYPE;

Class c8 = Double.TYPE;

Class c9 = Void.TYPE;

擷取Class對象的一些基本資訊

如下表。

Java class 内部子產品 Java class 内部子產品說明 相應之Reflection API,多半為Class methods。 傳回值類型(return type)
package class隸屬哪個package getPackage() Package
import class導入哪些classes 無直接對應之API。可間接擷取。
modifier class(或methods, fields)的屬性

int getModifiers()

Modifier.toString(int)

Modifier.isInterface(int)

int

String

bool

class name or interface name class/interface 名稱getName() String
type parameters 參數化類型的名稱 getTypeParameters() TypeVariable <Class>[]
base class base class(隻可能一個) getSuperClass() Class
implemented interfaces 實作有哪些interfaces getInterfaces() Class[]
inner classes 内部classes getDeclaredClasses() Class[]
outer class 如果我們觀察的class 本身是inner classes,那麼相對它就會有個outer class。 getDeclaringClass() Class

上表中,列出了一些Java class内部資訊的擷取方式。所采用的方法幾乎都是調用Class對象的成員方法(由此你就可以了解到Class類的用處了吧)。

二、類中最重要的三個資訊

構造函數

擷取構造函數的方法有以下幾個:

ConstructorgetConstructor(Class[] params)

Constructor[]getConstructors()

ConstructorgetDeclaredConstructor(Class[] params)

Constructor[]getDeclaredConstructors()

Class[] params為目标類的構造函數參數類型數組,具體見以下的舉例

不帶Declared關鍵字的函數(如:getConstructor)隻能擷取到公有的構造函數,

帶Declared關鍵字的函數(如:getDeclaredConstructor)能擷取到飛共有的構造函數,即所有通路保護機制的構造函數。

成員函數

和擷取構造函數的方法類似,擷取成員函數的方法有以下一些:

MethodgetMethod(String name, Class[] params)

Method[]getMethods()

MethodgetDeclaredMethod(String name, Class[] params)

Method[]getDeclaredMethods()

其中需要注意,String name參數,需要寫入方法名。關于通路權限和确定性的問題,和構造函數基本一緻。

成員變量

擷取成員變量的方法與上面兩種方法類似,具體如下:

FieldgetField(String name)

Field[]getFields()

FieldgetDeclaredField(String name)

Field[]getDeclaredFields()

其中,String name參數,需要寫入變量名。關于通路權限和确定性的問題,與前面兩例基本一緻。

三、使用舉例

我們舉一個兩個數相加的列子

MathPlus類代碼:

package cn.cq.shenyun;

public class MathPlus {
	public int num1=0;
	public int num2=0;
	
	//預設構造函數
	public MathPlus(){
		
	}
	//帶兩個整形參數的構造函數
	public MathPlus(int nummber1,int nummber2){
		num1=nummber1;
		num2=nummber2;
	}
	//将對象内的兩個成員相繼傳回
	public int add1(){
		return num1+num2;
	}
	//将傳入的兩整形參數相加傳回
	public int add2(int nummber1,int nummber2){
		return nummber1+nummber2;
	}

}
           

MathMain類:該類是主函數所在類,利用反射操作MathPlus類

package cn.cq.shenyun;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class MathMain {

	public static void main(String[] args) {
		test1();
		test2();
		test3();
		test4();
	}
	//用無參構造函數構造對象,再調用無參方法add1
	public static void test1(){
			try {
				//擷取Class
	           Class<?> cls = Class.forName("cn.cq.shenyun.MathPlus");
	           
	           //用預設構造函數構造對象
	           Constructor<?> con=cls.getConstructor();
	           Object mathobj=con.newInstance();
	           //如果是用無參構造,可直接用Class的newInstance方法,都夠構造對象
	           //Object mathobj=cls.newInstance();
	           
	           //調用無參數對象方法add1
	           Method method=cls.getMethod("add1");//指定調用的方法 add1
	           int result=(Integer)method.invoke(mathobj);//調用mathobj1 的add1方法
	           
	           System.out.println("----test1 用無參構造函數構造對象,再調用無參方法add1----");
	           System.out.println("      test1 result="+result);	           
		}catch (Exception e) {
	
		}
	}
	//利用反射改變對象的成員變量
	public static void test2(){
		try{
			//擷取Class
			Class<?> cls = Class.forName("cn.cq.shenyun.MathPlus");
			//用預設構造函數構造對象
			Constructor<?> con=cls.getConstructor();
			Object mathobj=con.newInstance();
			
			//修改mathobj對象中num1的值
			Field field1=cls.getDeclaredField("num1");
			field1.setInt(mathobj, 2);
			//修改mathobj對象中num2的值
			Field field2=cls.getDeclaredField("num2");
			field2.setInt(mathobj, 3);
			
			//調用無參數對象方法add1
			Method method=cls.getMethod("add1");//指定調用的方法 add1
			int result=(Integer)method.invoke(mathobj);//調用mathobj1 的add1方法
   
			//System.out.println("test2 number1="+field1.getInt(mathobj));
			//System.out.println("test2 number2="+field2.getInt(mathobj));

			System.out.println("----test2 利用反射改變對象的成員變量----");
			System.out.println("       test2 result="+result+",number1="+field1.getInt(mathobj)+",number2="+field2.getInt(mathobj));
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	//調用有參構造函數
	public static void test3(){
		try{
			//擷取Class
			Class<?> cls = Class.forName("cn.cq.shenyun.MathPlus");		
			//設定構造函數的參數類型
			Class<?>[] parTypes=new Class<?>[2];
			parTypes[0]=int.class;
			parTypes[1]=int.class;
			//擷取構造器
			Constructor<?> con=cls.getConstructor(parTypes);//----------------重點注意,參數變化了
			
			//初始化構造參數
			Object[] pars=new Object[2];
			pars[0]=4;
			pars[1]=5;
			//構造對象
			Object mathobj=con.newInstance(pars);           //----------------重點注意,參數變化了
			
			//調用add1
			Method method=cls.getMethod("add1");//指定調用的方法 add1
			int result=(Integer)method.invoke(mathobj);//調用mathobj 的add1方法
			
			System.out.println("----test3 調用有參構造函數----");
			System.out.println("       test3 result="+result);
			
		}catch (Exception e) {
			
		}
	}
	//調用有參數的函數 add2
	public static void test4(){
		try{
			//擷取Class
			Class<?> cls = Class.forName("cn.cq.shenyun.MathPlus");
			//用預設構造函數構造對象
			Constructor<?> con=cls.getConstructor();
			Object mathobj=con.newInstance();
			
			//調用add2
			Class<?>[] parTypes=new Class<?>[2];
			parTypes[0]=int.class;
			parTypes[1]=int.class;
			Method method=cls.getMethod("add2",parTypes);//指定調用的方法 add2
			
			Object[] pars=new Object[2];
			pars[0]=6;
			pars[1]=7;
			int result=(Integer)method.invoke(mathobj,pars);//調用mathobj 的add2方法			
			
			System.out.println("----test4 調用有參數的函數 add2----");
			System.out.println("       test4 result="+result);
		}catch (Exception e) {

		}
	}
}
           

運作結果:

JAVA反射中類的構造函數,成員變量,成員方法的使用前言:本文主要介紹反射的經常使用的構造函數,成員變量,成員方法的使用,從網絡上搜尋了一些資料,自己寫了列子,主要為閱讀者初級使用反射做指導。一、Class類的對象二、類中最重要的三個資訊三、使用舉例

代碼下載下傳位址

百度網盤分享位址:http://pan.baidu.com/share/link?shareid=3185562225&uk=4093749335