Java基礎之反射例項(例項化Account與修改屬性)
阿新 • • 發佈:2018-11-21
要求:
設計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路徑,基本資料型別不變。