做过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中是很强大的特性,以后要重点关注!