1. 程式人生 > >Java基礎之反射例項(例項化Account與修改屬性)

Java基礎之反射例項(例項化Account與修改屬性)

要求:

   設計Account類,並且新增屬性id、name、balance,新增get和set方法與存取錢的方法。

   設計ReflectAccountTest類,例項化Account物件,存如100元,與取1000元的結果顯示。

 

相關資料:參考之前的反射應用(如何獲取物件的構造方法、屬性、普通方法)博文。

設計如下:

Account類:


package com.briup.ch25;

public class Account
{
	protected int id;
	public String name;
	private double balance;
	
	///構造方法
	public Account(int id,String name,double balance)
	{
		this.id = id;
		this.name = name;
		this.balance = balance;
	}

	public Account(){
	    this.id = 0;
	    this.name = null;
	    this.balance = 0.0;
	}

   ///新增get和set方法
   public void setId(int id){
      this.id = id;
   }

   public int getId(){
     return this.id;
   }

   public void setName(String name){
      this.name = name;
   }
   public String getName(){
       return this.name;
   }

   public void setBalance(double balance){
       this.balance = balance;
   }

   public double getBalance(){
       return this.balance;
   }

   ///提供存錢的方法和取錢的方法
   public double addMoney(int amount){
       if(amount <= 0)
	 return balance;
       balance+=amount;
       return balance;
   }
   public double needMoney(int amount){
       if(amount <= 0 || balance<amount)
 		return balance;
       balance-=amount;
       return balance;
   }

}  

設計ReflectAccountTest類如下:


package com.briup.ch25;

import java.lang.reflect.*;
/*
1.呼叫set,get方法為id賦值1000,name賦值為briup,balance賦值為10000

2.呼叫存錢和取錢的方法。分別存入100,取出1000之後,列印結果顯示
*/
class  ReflectAccountTest 
{
	public static void main(String[] args) throws Exception {
	   ///獲取類映象
	   Class clz = Class.forName("com.briup.ch25.Account");
	    /**
	      已經知道到了Account的構造方法存在這個,具體怎麼知道的,通過輸出貢棗方法的種類可查詢
	      參考程式碼:ch25中的ReflectTest.java
           */
           ///建立一個該物件
	   Constructor con=clz.getDeclaredConstructor(int.class,String.class,double.class);
	   Account account=(Account)con.newInstance(1000 , "briup"  , 10000);
	   ///列印結果顯示
	   printResult(clz , account);
	   ///print Property
	   Property(clz);
	   /*
	    *呼叫存錢和取錢的方法。分別存入100,取出1000之後,列印結果顯示
	   */
          //第一個引數代表方法名,第二個引數代表引數列表型別,如果有引數列表則寫成引數型別.class 例如

String.class,int.class
	   System.out.println("implementation changes me Money:");
	   ModifytheMoney( clz , account , "addMoney" , 100);
           ModifytheMoney( clz , account , "needMoney" , 1000);
	   System.out.println("changes over!");
	   ///Modify(修改) the Properties
           ModifytheProperties( clz , account , "name" , "ModifyBriup");
	   ///列印結果顯示
	   printResult(clz , account);
	}

	public static void ModifytheMoney(Class clz,Account account , String operationMothod , int Num) 

throws Exception{
           /*
	     Num One:Modify the Properties
	     Method mt1=clz.getDeclaredMethod("test",null);
	     //mt1.invoke(stu,null);
	     //直接傳類映象
	     mt1.invoke(clz,null);
	   */
	   ///存取錢
           Method mt=clz.getDeclaredMethod(operationMothod,int.class);
           //第一個引數代表例項化物件,第二個引數代表引數列表的實參,下面相當於String name=stu.getName();
           double balance=(double)mt.invoke( account , Num);
	   ///輸出修改的結果
           System.out.println("operation result:"+balance);
	}

	public static void ModifytheProperties(Class clz , Account account , String property , String 

ModifyValue) throws Exception{
	    Field field=clz.getDeclaredField( property );
	    //該屬性設定為可操作
	    field.setAccessible(true);
	    //第一個引數是例項化後的物件,第二個引數是要傳的值
	    field.set(account , ModifyValue);
	}

	public static void printResult(Class clz ,Account account ) throws Exception{
	   Method mt1=clz.getDeclaredMethod("getName",null);
	   Method mt2=clz.getDeclaredMethod("getId",null);
	   Method mt3=clz.getDeclaredMethod("getBalance",null);
	   //第一個引數代表例項化物件,第二個引數代表引數列表的實參,下面相當於String name=stu.getName();
       String name=(String)mt1.invoke(account,null);
       int id=(int)mt2.invoke(account,null);
	   double balance=(double)mt3.invoke(account,null);
	   System.out.println("\n\n---------------輸出該物件存在的所有屬性值:---------------");
       System.out.println("print result:name:"+name+" id:"+id+" :balance:"+balance);
	   System.out.println("-------------------列印結果結束!--------------------------\n\n");
	}


	public static void Property(Class clz) throws Exception{
	   ///列印存在的屬性結果
	  System.out.println("\n\n---------------輸出該物件存在的所有屬性:---------------");
	  Field[] f = clz.getDeclaredFields();
	  for(Field temp : f){
	    //獲取屬性的資料型別
		Class c=temp.getType();
		//獲取屬性的名字
		String name=temp.getName();
		//獲取屬性修飾符
		int m=temp.getModifiers();
		///輸出
		System.out.println("型別:"+m+" 名字:"+c+" 修飾符:"+name);
	  }
	  System.out.println("-------------------列印結果結束!-------------------------\n\n");
	}
}

結果顯示如下:

 

注:public型別為1,private型別為2,protected型別為4。泛型名字為class路徑,基本資料型別不變。