最近的開發,遇到一個調用其餘工程類方法的問題,用到一個簡單的方法--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
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
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));
}
}
|
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));
}
}
|
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中是單繼承,父類只有一個
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]);
}
}
}
|
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()只能獲取公共屬性
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.
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);
}
}
|
幾個方法都是有聯繫的,若是看不懂就先熟悉上面幾個例子
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
,
"你妹"
);
}
}
|
這裏演示了一個普通的有參方法和一個靜態方法
既然有參數的都寫出來了,那麼無參的就更簡單了,直接傳入一個對象便可
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