java 反射機製
今天和同事一起開發一個Android App的時候,第一次接觸到了反射機製這樣一個東西,於是上網查了很多資料,看了一些文檔。現在終於有了一點了解,故將其寫下,大牛勿噴。
首先,我們所學的編程語言大致可以分為兩種,第一種為靜態語言:C、C++、java ,這些語言的的變量類型一旦確定將不可更改;還有一類為動態語言:Perl、Python 這些語言的變量類型是可以更改的。但是java又區別於一般的靜態語言,因為其具有動態機製,所以java可以加載一個在運行時才確定的Class,得知其完整的構造,獲得具體的屬性以及運行其成員方法。
所謂的java反射機製指的是:對於任意一個類,都能夠知道它的完成結構,對於任意一個對象都能夠調用它的方法,這種動態獲取對象的信息以及動態調用對象方法的機製成為java反射機製。
這樣的定義並不好理解,最好的方法還是動手coding:首先我們寫一個很簡單的類:
Java代碼
- public class Person {
- public String name;
- public int age;
- public String getName() {
- return name;
- }
- public Person()
- {
- name="liyahou";
- age=10;
- }
- public Person(String name)
- {
- this.name=name;
- this.age=23;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String display()
- {
- return this.name+" "+this.age;
- }
- }
現在我們用這個類為白老鼠,進行試驗:
example1:獲取屬性值
Java代碼
- /**
- * @param owner 傳入的實例
- * @param filedName 要獲取的成員名
- * @利用反射機製獲取類成員
- */
- public void getProperty(Object owner,String filedName)
- {
- Class instance=owner.getClass();
- try {
- Field filed=instance.getField(filedName);
- Object property=filed.get(owner);
- System.out.println(property.toString());
- } catch (NoSuchFieldException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (SecurityException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public static void main(String[] args)
- {
- Person person=new Person();
- person.setName("liyazhou");
- ReflectDemo demo=new ReflectDemo();
- demo.getProperty(person,"name");
- }
結果:liyazhou
代碼解析:
Class instance=owner.getClass(); 獲取該對象的class
Field filed=instance.getField(filedName); 通過傳入的屬性名得到該屬性
Object property=filed.get(owner); 通過對象去獲取其屬性的值
example2:利用反射機製執行一個類的方法
Java代碼
- /**
- * @param owner
- * @param methoadName
- * @param args
- * @throws NoSuchMethodException
- * @throws SecurityException
- * @throws IllegalAccessException
- * @throws IllegalArgumentException
- * @throws InvocationTargetException
- * @利用反射機製執行類的方法
- */
- public void invokeClassMethod(Object owner,String methoadName,Object[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
- {
- Class instance=owner.getClass();//得到該類的class
- Class[] Args=new Class[args.length];
- for(int i=0;i<Args.length;i++)
- {
- Args[i]=args[i].getClass();
- }//構造該函數的參數類型
- Method method=instance.getMethod(methoadName, Args);//構造該方法
- System.out.println(method.invoke(owner, args)+"");//運行
- }
example 3:構造實例
Java代碼
- public Object getNewInstance(String className, Object[] args)
- {
- try {
- Class instance=Class.forName(className);//得到該類的Class
- Class[] arg=new Class[args.length];
- for(int i=0;i<args.length;i++)
- {
- arg[i]=args[i].getClass();
- }//構造方法所需的參數類型
- Constructor con=instance.getConstructor(arg);//構造構造器
- return con.newInstance(args);//構造實例
- } catch (ClassNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (SecurityException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (InstantiationException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
將java反射機製應用到工廠模式中:
- package Reflect;
- interface fruit{
- public abstract void eat();
- }
- class Apple implements fruit{
- public void eat(){
- System.out.println("Apple");
- }
- }
- class Orange implements fruit{
- public void eat(){
- System.out.println("Orange");
- }
- }
- class Factory{
- public static fruit getInstance(String ClassName){
- fruit f=null;
- try{
- f=(fruit)Class.forName(ClassName).newInstance();
- }catch (Exception e) {
- e.printStackTrace();
- }
- return f;
- }
- }
- class hello{
- public static void main(String[] a){
- fruit f=Factory.getInstance("Reflect.Apple");
- if(f!=null){
- f.eat();
- }
- }
- }
現在就算我們添加任意多個子類的時候,工廠類就不需要修改。
最後更新:2017-04-03 18:51:50