Class类为编写可动态操纵的java代码程序提供了强大功能。这项功能广泛用于java构件体系结构javaBean中。特别是运行期动态增类的能力。
能够分析类的能力的程序称为反射器。Java提供些功能的包是java.lang.reflect.反射机制极为强大。
1.在运行时分析类的能力
2.在运行时探查对象,比如,只写一个toString方法提供所有类的使用
3.实现通用数组操作代码
4.利用method对象。
使用反射分析类的功能:
Java.lang.reflec包中的三个类Filed、Method、Constructor类分别描述类的字段,方法和构造器。它们都有一个getName的方法返回相应条目的名称。Field类有个getType方法,返回一个用来描述类型的Class对象。而Method和Constructor类都有报告这些方法的返回类型和参数类型的方法。这三个类还都有一个getModifiers方法,它返回一个整数,可以使用Modifier类中的三个方法 isPublic,isPrivate和isFinal 分别判断一个一个方法或构造器是否是public,private或者final.
Class类中的getFields、getMethods和getConstructors方法分别返回类所支持的公有字段,方法和构造器的数组,其中包括私有成员和受保护成员,但不包括超类成员。
代码实例:
package
com.jianshe;
import
java.lang.reflect.Constructor;
import
java.lang.reflect.Field;
import
java.lang.reflect.Method;
import
java.lang.reflect.Modifier;
import
javax.swing.JOptionPane;
public
class
RefectionTest
{
public
static
void
main(String[]
args)
{
String
name;
if
(args.
length
>0)
name
=
args[0];
else
// name = JOptionPane.showInputDialog("Class name (e.g. java.util.Date): ");
name
=
"java.util.Date"
;
try
{
//print class name and superclass name(if !=Object)
Class
cl
=
Class.forName(name);
Class
superclass
=
cl.getSuperclass();
System.
out
.println(
" class "
+name);
if
(superclass!=
null
&&
superclass
!=Object.
class
)
System.
out
.println(
" extends "
+superclass.getName());
System.
out
.println(
"{"
);
printConstructors
(cl);
System.
out
.println();
printMethods
(cl);
System.
out
.println();
printFields
(cl);
System.
out
.println(
"}"
);
}
catch
(Exception
e)
{
e.printStackTrace();
}
}
/**
*
*
@param
cl
*/
public
static
void
printConstructors(Class
cl)
{
Constructor[]
declaredConstructors
=
cl.getDeclaredConstructors();
for
(
int
i
=
0;
i
<
declaredConstructors.
length
;
i++)
{
Constructor
constructor
=
declaredConstructors[i];
String
name
=
constructor
.getName();
System.
out
.println(Modifier.toString(constructor.getModifiers()));
System.
out
.println(
" "
+
name
+
" ("
);
// print parameter types
Class[]
paramTypes
=
constructor
.getParameterTypes();
for
(
int
j
=
0;
j
<
paramTypes.
length
;
j++)
{
Class
type
=
paramTypes[j];
if
(j
>
0)
{
System.
out
.println(
" , "
);
}
System.
out
.println(type.getName());
System.
out
.println(type.getSimpleName());
}
System.
out
.println(
");"
);
}
}
/**
*
@param
cl
*/
public
static
void
printMethods(Class
cl)
{
Method[]
declaredMethods
=
cl.getDeclaredMethods();
for
(
int
i
=
0;
i
<
declaredMethods.
length
;
i++)
{
Method
method
=
declaredMethods[i];
Class
returnType
=
method.getReturnType();
String
name
=
method.getName();
// print modifiers,return type and method name
System.
out
.println(Modifier.toString(method.getModifiers()));
System.
out
.println(
" "
+
returnType
+
" "
+
name
+
"); "
);
// print parameter types
Class[]
parameterTypes
=
method.getParameterTypes();
for
(
int
j
=
0;
j
<
parameterTypes.
length
;
j++)
{
Class
type
=
parameterTypes[j];
if
(j
>
0)
System.
out
.println(
", "
);
System.
out
.println(type.getName());
}
System.
out
.println(
");"
);
}
}
public
static
void
printFields(Class
cl)
{
Field[]
declaredFields
=
cl.getDeclaredFields();
for
(
int
i
=
0;
i
<
declaredFields.
length
;
i++)
{
Field
field
=
declaredFields[i];
Class
type
=
field.getType();
String
name
=
field.getName();
System.
out
.println(Modifier.toString(field.getModifiers()));
System.
out
.println(
" "
+
type.getName()
+
" "
+name
+
";"
);
}
}
}
在运行时使用反射分析对象
反射机制的默认行为受限于java访问控制。如果java程序不受安全管理控制,那么就有可能屏蔽访问控制。setAccessible(true).这个方法是AcessibleObject类的一个方法,这项功能是给调试器、持久存储及类似机制提供的。
代码演示:
package
com.jianshe;
public
class
A
{
private
String
name
=
"default name"
;
public
void
printName(){
System.
out
.println(
" name is :"
+
name
);
}
public
String
getName()
{
return
name
;
}
public
void
setName(String
name)
{
this
.
name
=
name;
}
}
package
com.jianshe;
import
java.lang.reflect.Field;
import
java.lang.reflect.InvocationTargetException;
import
java.lang.reflect.Method
;
/**
*
演示如何通过反射来为Filed赋值。
*
*
如何通过Mehtod调用方法。
*
*
@author
jiansheliu
*
*/
public
class
TEst
{
public
static
void
main(String[]
args)
{
A
a
=
new
A();
Class
class1
=
a.getClass();
try
{
//
通过Field对象得到属性值
Field
field
=
class1.getDeclaredField(
"name"
);
field.setAccessible(
true
);
String
name
=
(String)field.get(a);
System.
out
.println(name);
//
通过Field对象设置属性值
field.set(a,
"jianshe"
);
System.
out
.println(a.getName());
//Method
方法调用printName方法
Method
declaredMethod
=
class1.getDeclaredMethod(
"printName"
,
null
);
Object
object
=
declaredMethod.invoke(a,
null
);
}
catch
(SecurityException
e)
{
//
TODO
自动生成 catch 块
e.printStackTrace();
}
catch
(NoSuchFieldException
e)
{
//
TODO
自动生成 catch 块
e.printStackTrace();
}
catch
(IllegalArgumentException
e)
{
//
TODO
自动生成 catch 块
e.printStackTrace();
}
catch
(IllegalAccessException
e)
{
//
TODO
自动生成 catch 块
e.printStackTrace();
}
catch
(NoSuchMethodException
e)
{
//
TODO
自动生成 catch 块
e.printStackTrace();
}
catch
(InvocationTargetException
e)
{
//
TODO
自动生成 catch 块
e.printStackTrace();
}
}
}