java反射調用方法

最近的開發,遇到一個調用其餘工程類方法的問題,用到一個簡單的方法--java反射。利用反射機制,獲取類實例,再獲取相應方法,最後執行,獲得結果。html

具體應用爲:java

Class<?> CIRWindowsAPI = Class.forName("com.fujitsu.ci.runtime.common.CIRWindowsAPI");        
Method isUNCPath = CIRWindowsAPI.getDeclaredMethod("isUNCPath", String.class);
Object result = isUNCPath.invoke(null, f.getPath());
return Boolean.valueOf(result.toString());數組

關於java反射還不瞭解,因而上網搜索相關內容,整理以下:安全

1.Class類學習

在java中,Object類是全部類的父類,一樣,全部類的實例化對象也都是Class類的實例。this

因爲Class類沒有構造方法,因此實例化Class類的方式有點特殊,有三種方式:spa

  • 對象.getClass( )
  • 類.Class
  • forName( )
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Test {
   
}
 
public class Demo {
    public static void main(String[] args) {
        //方式一:
        Test t = new Test();
        Class<? extends Test> c1 = t.getClass();
        System.out.println(c1);
       
        //方式二:
        //爲了不特殊性,這裏不用Test類,而用java庫中的String類
        Class<String> c2 = String. class ;
        System.out.println(c2);
       
        //方式三:
        //forName()方法會拋出異常
        Class<?> c3 = null ;
        try {
            c3 = Class.forName( "Test" );
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println(c3);
    }
}

其中,forName( )方法須要重點掌握,由於它能夠在類不肯定的狀況下實例化Class,更具靈活性code

2.Class類的應用htm

獲取類的結構對象

要經過反射獲取類的結構咱們這裏要導入一個新的包java.lang.reflect

實例a:取得類的構造方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.lang.reflect.Constructor;
import java.util.Arrays;
 
public class Demo {
    //下面的幾個方法拋出來的異常太多,爲了代碼的緊湊性,這裏就直接拋給虛擬機了
    public static void main(String[] args) throws Exception {
        Class<?> c = null ;
        try {
            c = Class.forName( "java.lang.Boolean" );
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //這裏的getConstructors()方法返回的是一個Constructor數組
        Constructor<?>[] cons = c.getConstructors();
        //打印的方式你能夠本身寫,爲了方便我用Arrays.toString(),湊合着看
        System.out.println(Arrays.toString(cons));
    }
}

實例b:取得類所實現的接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.Arrays;
 
public class Demo {
    public static void main(String[] args) throws Exception {
        Class<?> c = null ;
        try {
            c = Class.forName( "java.lang.Boolean" );
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Class<?>[] in = c.getInterfaces();
        System.out.println(Arrays.toString(in));
    }
}

實例c:取得父類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Demo {
    public static void main(String[] args) throws Exception {
        Class<?> c = null ;
        try {
            c = Class.forName( "java.lang.Boolean" );
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //注意了,這裏不會是數組,why?
        Class<?> su = c.getSuperclass();
        System.out.println(su);
    }
}

別忘了,java中是單繼承,父類只有一個

實例d:取得類的所有方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.lang.reflect.Method;
 
public class Demo {
    public static void main(String[] args) throws Exception {
        Class<?> c = null ;
        try {
            c = Class.forName( "java.lang.Boolean" );
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Method[] m = c.getMethods();
        //好吧,此次我就大發慈悲的寫個打印列表出來
        for ( int i = 0 ; i < m.length; i++) {
            System.out.println(m[i]);
        }
    }
}

實例e:取得本類的所有屬性

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.lang.reflect.Field;
 
class Person {
    private String name;
    private int age;
}
 
public class Demo {
    public static void main(String[] args) throws Exception {
        Class<?> c = null ;
        try {
            c = Class.forName( "Person" );
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Field[] f = c.getDeclaredFields();
        for ( int i = 0 ; i < f.length; i++) {
            System.out.println(f[i]);
        }
    }
}

getDeclaredFielsd()方法能夠獲取所有屬性,getFields()只能獲取公共屬性

實例f:獲取本類中屬性的值

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.lang.reflect.Field;
 
class Person {
    public String name;
    private int age;
   
    public Person(String name, int age) {
        this .name = name;
        this .age = age;
    }
}
 
public class Demo {
    public static void main(String[] args) throws Exception {
        Person p = new Person( "zhangsan" , 12 );
 
        Class<?> c = p.getClass();
       
        //獲取公共屬性的值
        Field f1 = c.getField( "name" );
        //get(p)代表要獲取是哪一個對象的值
        String str = (String) f1.get(p);
        System.out.println( "姓名: " + str);
       
        //獲取私有屬性的值
        Field f2 = c.getDeclaredField( "age" );
        //age是私有屬性,因此要設置安全檢查爲true
        f2.setAccessible( true );
        int age = ( int ) f2.get(p);
        System.out.println( "年齡: " + age);
    }
}

要注意的是:setAccessible()方法能夠設置是否訪問和修改私有屬性

3.

反射的應用

實例g:經過反射修改屬性

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.lang.reflect.Field;
 
class Person {
    private String name;
   
    public Person(String name) {
        this .name = name;
    }
   
    public String toString() {
        return "姓名: " + this .name;
    }
}
 
public class Demo {
    public static void main(String[] args) throws Exception {
        Person p = new Person( "王二狗" );
        System.out.println(p);
        Class<?> c = p.getClass();
   
        //定義要修改的屬性
        Field f = c.getDeclaredField( "name" );
        f.setAccessible( true );
        //修改屬性,傳入要設置的對象和值
        f.set(p, "張二蛋" );
        System.out.println(p);
    }
}

幾個方法都是有聯繫的,若是看不懂就先熟悉上面幾個例子

 

實例h:經過反射調用方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.lang.reflect.Method;
 
class Person {
    public void print( int i) {
        System.out.println( "我在寫數字: " + i);
    }
   
    public static void say(String str) {
        System.out.println( "我在說: " + str);
    }
}
 
public class Demo {
    public static void main(String[] args) throws Exception {
        Person p = new Person();
        Class<?> c = p.getClass();
   
        //getMethod()方法須要傳入方法名,和參數類型
        Method m1 = c.getMethod( "print" , int . class );
        //invoke()表示調用的意思,須要傳入對象和參數
        m1.invoke(p, 10 );
       
        Method m2 = c.getMethod( "say" , String. class );
        //這裏的null表示不禁對象調用,也就是靜態方法
        m2.invoke( null , "你妹" );
    }
}

這裏演示了一個普通的有參方法和一個靜態方法

既然有參數的都寫出來了,那麼無參的就更簡單了,直接傳入一個對象便可

 

實例i:經過反射操做數組

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.lang.reflect.Array;
 
public class Demo {
    public static void main(String[] args) throws Exception {
        int [] arr = { 1 , 2 , 3 , 4 , 5 };
        Class<?> c = arr.getClass().getComponentType();
       
        System.out.println( "數組類型: " + c.getName());
        int len = Array.getLength(arr);
        System.out.println( "數組長度: " + len);
        System.out.print( "遍歷數組: " );
        for ( int i = 0 ; i < len; i++) {
            System.out.print(Array.get(arr, i) + " " );
        }
        System.out.println();
        //修改數組
        System.out.println( "修改前的第一個元素: " + Array.get(arr, 0 ));
        Array.set(arr, 0 , 3 );
        System.out.println( "修改後的第一個元素: " + Array.get(arr, 0 ));
    }
}

這裏要注意一點,getComponentType( )返回的是數組元素的Class。

以上是初級的理解,更多用法還需繼續學習。

原文請參考:http://www.cnblogs.com/nerxious/archive/2012/12/24/2829446.html

相關文章
相關標籤/搜索