Java類反射再次升級

YX_blog發表於2015-09-02

     在這之前,已經見過了基本的類反射應用,如何解剖Class 物件,要是您沒有看,請點選這裡點選開啟連結

這篇文章寫的是如何將Class 物件用起來,呼叫函式,構造方法以及如何設定變數的值。

類的呼叫(呼叫類中的成員)

 構造類物件:使用構造器新建物件。根據指定的引數型別找到相應的建構函式,傳入相應引數呼叫執行,以建立一個新的物件例項。程式碼演示:‘

其實是這樣訪問的

       1,訪問構造方法,必須去接一個

<span style="white-space:pre">		</span>Constructor con2=c.getConstructor(par2);需要一個建構函式裡面的引數型別和數值
<span style="white-space:pre">	</span>如 Person p =new Person("Jack",20);這裡面就是需要String 型別和int型別,同樣的在<span style="font-family: Arial, Helvetica, sans-serif;">getConstructor中也需要Class陣列,<span style="color:#ff0000;">注意:在Class 引數型別中,不帶用自動拆裝箱功能。但是可以使用 如  Integer.class,可以寫成Integer.Type</span></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="color: rgb(255, 0, 0); white-space: pre;">		</span>2,獲得這個建構函式之後我們就需要</span><span style="font-family: Arial, Helvetica, sans-serif;">con2.newInstance(obj2);造出一個例項,這時候就需要把具體的實參傳進去,這時候有需要一個object陣列,然後就這樣就可以呼叫帶引數的構造方法</span>
<span style="font-family:Arial, Helvetica, sans-serif;">下面介紹空參和帶引數的演示(簡單易懂)</span>

	//操作類的構造方法
		private static void operationConstrontor(String name) throws Exception{
			Class c=Class.forName(name);
			
	//1,操作無參構造方法
			Constructor con=c.getConstructor(null);//無引數 所以可以直接獲得
	
			Object obj=con.newInstance();
			System.out.println(obj+"不帶引數");
			
	//2,帶引數的構造方法
			//首先 通過Class 物件獲得Constructor;裡面需要帶引數(形參),引數型別都是CLass 型別
			//先確定需要引數型別
			Class par2[]=new Class[4];
			par2[0]=String.class;
			par2[1]=String.class;
			par2[2]=int.class;
			par2[3]=String.class;
			Constructor con2=c.getConstructor(par2);//需要形引數組
			//引數確定之後,就可以傳進去引數進行傳參了
			Object obj2[]=new Object[4];
			obj2[0]="jack";
			obj2[1]="tom";
			obj2[2]=4;
			obj2[3]="Rose";
			Object ret =con2.newInstance(obj2);
			System.out.println(ret+"帶引數的構造方法");
		}

呼叫方法:

根據方法名稱執行方法。根據方法名與引數型別匹配指定的方法,傳入相應引數與物件進行呼叫執行。若是靜態方法,則不需傳入具體物件。

程式碼演示:

1,首先需要c.getMethod("methodname", 引數型別),首先必須填寫方法名,和引數有哪些型別,如int,String等,需要一個Class物件陣列menthodname,

c.getMethod(methodname, parameterTypes) parameterTypes

<span style="font-size:14px;">				//parameterTypes需要引數的引數(有的類含有過載,方法名一樣,引數型別不一樣,所以必須規定引數名)
				
			</span><span style="font-size:18px;">	//定義引數型別  Class 陣列
				Class param[]=new Class[1];
				param[0]=String.class;</span>

<span style="font-size: 14px; white-space: pre;">			</span><span style="font-size:24px;">// 獲得method物件 Method method2=c.getMethod(methodname, param);</span>
<pre name="code" class="java"><span style="font-size:24px;"><span style="white-space:pre">		</span>method2.invoke(obj2, args),物件obj2,還需要傳進去的引數args</span>
<span style="font-size:24px; white-space: pre;">	</span><span style="font-size:24px;">obj2通過 </span><span style="font-size:18px;">c.new<span style="font-family: Arial, Helvetica, sans-serif;">Instance()獲得,但是引數是傳進需要用的引數,也即是放在一個物件陣列裡面,</span></span>
<span style="font-size:18px;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="white-space:pre">	</span>3,靜態方法不需要引數</span></span>


<span style="font-size:14px;">private static void operationMethod(String name) throws Exception {
			///傳進來的字串,類反射得到Class 物件
			
			Class c =Class.forName(NAME);//異常丟擲去便於理解
			
	//1,操作空參方法
				Method methods=c.getMethod("toString", null);//toString 沒有引數,所以給null
				//獲得Class 物件的例項化
				Object obj=c.newInstance();
				//進行操作
				Object res=methods.invoke(obj, null);
				System.out.println(res);//{null,null,0,null}//傳進來的就是空參,所以全部為初始值
				
				
				
	//2,操作有擦數的方法
				String methodname= "setName";//這是方法名,可以通過遍歷得到
//				c.getMethod(methodname, parameterTypes) parameterTypes
				//parameterTypes需要引數的引數(有的類含有過載,方法名一樣,引數型別不一樣,所以必須規定引數名)
				
				//定義引數型別  Class 陣列
				Class param[]=new Class[1];
				param[0]=String.class;
				
				// 獲得method物件
				Method method2=c.getMethod(methodname, param);
				
				//需要物件呼叫,所以要例項化newInstance();
				Object obj2=c.newInstance();
				//method2.invoke(obj2, args),物件obj2,還需要傳進去的引數
				Object args[]=new Object[1];
				args[0]="TOM JAck";
				 
				Object ret=method2.invoke(obj2, args);//ret為返回值
				System.out.println(ret+"帶引數");
	
				
	//3,呼叫靜態方法
			 Method method3=c.getDeclaredMethod("ret", null);
			 Object obj3= method3.invoke(null, null);
			System.out.println(obj3+".....static.......");//靜態的,所以許可權必須是public
				</span>


獲取與設定屬性值 :

根據屬性名稱讀取與修改屬性的值,訪問非靜態屬性需傳入物件為引數。

		<span style="font-size:18px;">//對類裡面的變數進行操作
		private static void operationFeild(String name2) throws Exception{
			 Class c=Class.forName(name2);
			 Field field= c.getDeclaredField("pwd");// 由於name 是private 許可權,可以獲得但是不能訪問
//<span style="white-space:pre">		<span style="background-color: rgb(255, 0, 0);">	</span></span><span style="background-color: rgb(255, 0, 0);">field.setAccessible(true); //傳說中的暴力破解就只是新增這一句就可以了,設定可以編輯的</span>
			 Object obj3=c.newInstance();
			 field.set(obj3, "Tom");//許可權私有,不能訪問,必須改成public  或者暴力破解
			 System.out.println(field.get(obj3));
		}</span>


相關文章