做過J2EE的工程師會經常進行單元測試工作,一般我們會使用一些開源組件進行,比如JUnit,DBUnit等等,使用他們使開發人員很容易進行測試,非常強大,究其原因,是因為他們都用到了強大的反射機制。
最近使用p-unit進行測試工作,它相對于JUnit最大的好處是除了測試案例的正確性之外,它有比較強大的性能測試功能,可以
對測試結果生成性能測試數據
p-unit包下載 https://sourceforge.net/project/showfiles.php?group_id=195736
p-unit源碼下載 http://p-unit.svn.sourceforge.net/svnroot/p-unit
通過其源碼探究了反射機制的一些使用方式,我重點摘取其如何判斷類中方法的代碼
功能:
1、方法是公共但不不是satic
2、方法以test為開頭
3、方法中不能帶入參數
1
/** *//**
2
* Judges whether this method is a test method.
3
*
4
* @return returns true if the test modifier, name, and parameter conform to
5
* the convention of a test method.
6
*/
7
public boolean isTestMethod(Method method)
{
8
return isModifierValid(method) && isNameValid(method)
9
&& isParamValid(method);
10
}
11
12
/** *//**
13
* Judges whether the modifier of is method conforms to the convention of a
14
* test method.
15
*
16
* @param method
17
* to be judged
18
* @return returns true if this method is public and non static.
19
*/
20
protected boolean isModifierValid(Method method)
{
21
return ReflectionUtil.isPublic(method)
22
&& !ReflectionUtil.isStatic(method);
23
}
24
25
/** *//**
26
* Judges whether the name of is method conforms to the convention of a test
27
* method.
28
*
29
* @param method
30
* to be judged
31
* @return returns true if the name of this method starts with "test", or
32
* the name is in the list of test interfaces which are added by
33
* <code>TestMethodBuilder.addTestInterfaces</code>
34
*/
35
protected boolean isNameValid(Method method)
{
36
String name = method.getName();
37
return name.startsWith("test"); //$NON-NLS-1$
38
}
39
40
/** *//**
41
* Judges whether the parameters of this method conform to the convention of
42
* a test method.
43
*
44
* @param method
45
* @return <code>true</code> if the number of method parameters is zero
46
* and the test class is not marked as <code>Parameterized</code>,
47
* or the parameter length is 1, and the parameter is assignable
48
* from <code>Parameter</code>.
49
*/
50
protected boolean isParamValid(Method method)
{
51
Class clazz = method.getDeclaringClass();
52
Class[] params = method.getParameterTypes();
53
if (isParameterizedTest(clazz))
{
54
return params.length == 1 && isParameter(params[0]);
55
} else
{
56
return params.length == 0;
57
}
58
}
以上代碼中關于Method的一些操作。method.getDeclaringClass()是獲得類反射自身的方法,而對其繼承的父類方法過濾掉。
ReflectionUtil類中的方法,此類中方法的目的主要是得到方法描述符(Method.getModifiers())
1
/** *//**
2
* 主要是判斷方法是不是公共方法,其中 Modifier.PUBLIC是1,如果為1就是公共方法
3
* @param method
4
* @return
5
*/
6
public static boolean isPublic(Method method)
{
7
int modifier = method.getModifiers();
8
return isBitSet(modifier, Modifier.PUBLIC);
9
}
10
/** *//**
11
* 返回方法的修飾符,查看是否是靜態方法
12
* @param method
13
* @return
14
*/
15
public static boolean isStatic(Method method)
{
16
int modifier = method.getModifiers();
17
return isBitSet(modifier, Modifier.STATIC);
18
}
19
20
private static boolean isBitSet(int value, int expectedBit)
{
21
return (value & expectedBit) != 0;
22
}
關于方法的修飾符中常量代表
1
java.lang.reflect.Modifier
2
public static final int ABSTRACT 1024
3
public static final int FINAL 16
4
public static final int INTERFACE 512
5
public static final int NATIVE 256
6
public static final int PRIVATE 2
7
public static final int PROTECTED 4
8
public static final int PUBLIC 1
9
public static final int STATIC 8
10
public static final int STRICT 2048
11
public static final int SYNCHRONIZED 32
12
public static final int TRANSIENT 128
13
public static final int VOLATILE 64
14
從以上可以看出其使用反射機制一些代碼,其中主要是對類中的方法進行反射并進行一系列判斷操作,以下是自己使用反射做的一個方法,目前已在項目中使用
1
/** *//**
2
* 通過反射對指定屬性值的其他屬性進行判空處理,如果數據庫沒有此記錄或屬性都不為空都為true
3
*
4
* @param map
5
* 父級查詢
6
* @param subMap
7
* 子級查詢
8
* @param prefix
9
* 查詢方法的前綴,比如get
10
* @param key
11
* 進行查詢字段名稱
12
* @return 如果有一個屬性值為空返回false,全部不為空返回true
13
*/
14
15
public boolean getIsNotEmpty(Map map, Map subMap, String prefix,
16
String
key)
{
17
boolean flag = true;
18
List<T> list = getQueryForSubCri(map, subMap);
19
try
{
20
//如果所查詢的條件在數據庫不存在,那么也是true,這是為具體業務服務,通常應該是false
21
if(list==null||list.size()==0)
{
22
flag = true;
23
}
24
for (T ed : list)
{
25
Method method[] = (ed.getClass()).getDeclaredMethods();
26
for (int i = 0; i < method.length; i++)
{
27
String mname = method[i].getName();
28
if (mname.indexOf(prefix) != -1)
{
29
String subName = mname.substring(prefix.length());
30
for (String k : key)
{
31
if (subName.equalsIgnoreCase(k))
{
32
String t = (String) method[i].invoke(ed);
33
if (StringUtils.isBlank(t))
{
34
flag = false;
35
break;
36
}
37
38
}
39
}
40
}
41
}
42
}
43
} catch (Exception e)
{
44
ReflectionUtils.handleReflectionException(e);
45
}
46
return flag;
47
48
}
以上是自己花一點時間對反射機制的一些整理,時間有限,只對其中方法級反射進行總結,反射機制在JAVA中是很強大的特性,以后要重點關注!