您的位置:首页 > 编程语言 > Java开发

java之反射机制

2015-07-22 09:05 591 查看

什么是Java反射(Reflection)?

程序在运行时(不是编译时)能够自我检查,并且能够对内部成员进行操作。例如它允许一个java类获取他所有的变量和方法。利用java中反射机制可以通过Reflection API获取该类的内部信息,如superclass、interfaces、modifiers(修饰public、private等)、以及field和methods,并且运行中能够修改field和调用methods。java的这种反射机制使其被视为动态语言的关键因素。

反射可以做什么?

在运行中分析类的能力。

在运行中查看对象。

实现通用的数组操作代码。

利用Method对象。

Class类

java在运行是为每个对象维护一个类型标识,这个类型标识跟踪着这个对象所属的类。虚拟机通过这个类型标识获取类中相关信息,java将这些信息保存在Class类中。这个Class类不能够创建对象,不是因为其没有构造方法,而是因为他的构造方法是private类型,之所以用private类型,就是为了避免其他类构造该类的实例,这个类的实例是由虚拟机自己构造的。有了这个Class就可以通过反射获取类中的信息了。

[java] view
plaincopyprint?

class Class<T> implements java.io.Serializable,

java.lang.reflect.GenericDeclaration,

java.lang.reflect.Type,

java.lang.reflect.AnnotatedElement {

private static final int ANNOTATION= 0x00002000;

private static final int ENUM = 0x00004000;

private static final int SYNTHETIC = 0x00001000;

private static native void registerNatives();

static {

registerNatives();

}

/*

* Constructor. Only the Java Virtual Machine creates Class

* objects.

*/

private Class() {}

获取Class类型

可以通过一下三种方式获取类的class类型。

1、通过Object的getClass()方法

比如,Employee e;

e.getClass();

2、通过Class类的静态方法forName()获取,注意这个需要添加异常处理器

Class.forName(className);

这个className包括包名的完整名称。

3、直接通过类名

Employee.class就是返回一个class类型

Class类提供的方法

通过class类提供的方法获取当前类的信息。

static Class<?>
forName(String className)

Returns the
Class
object associated with the class or interface with the given string name.
static Class<?>
forName(String name,
boolean initialize, ClassLoader loader)

Returns the
Class
object associated with the class or interface with the given string name, using the given class loader.
通过forName获取class类型,第二种方式是指使了是否一定初始化以及指定类加载器


ClassLoader
getClassLoader()

Returns the class loader for the class.
Constructor<T>
getConstructor(Class<?>... parameterTypes)

Returns a
Constructor
object that reflects the specified public constructor of the class represented by this
Class
object.
Constructor<?>[]
getConstructors()

Returns an array containing
Constructor
objects reflecting all the public constructors of the class represented by this
Class
object.
通过getClassLoader()获取当前类的类加载器。

getConstructor()返回当前类的构造方法,第一个paramterTyper是指示特定获取构造方法的指定参数类型的构造器

Constructor类型稍后说

Field
getField(String name)

Returns a
Field
object that reflects the specified public member field of the class or interface represented by this
Class
object.
Field[]
getFields()

Returns an array containing
Field
objects reflecting all the accessible public fields of the class or interface represented by this
Class
object.
返回公共变量,指定参数的话获取特定参数的变量Field,getFields()获取所有公共域变量。

Method
getMethod(String name,Class<?>... parameterTypes)

Returns a
Method
object that reflects the specified public member method of the class or interface represented by this
Class
object.
Method[]
getMethods()

Returns an array containing
Method
objects reflecting all the publicmember methods of the class or interface represented by this
Class
object, including those declared by the class or interface and those
inherited from superclasses and superinterfaces.
返回该类的公共方法,包括由父类或着接口继承过来的

Constructor<T>
getDeclaredConstructor(Class<?>... parameterTypes)

Returns a
Constructor
object that reflects the specified constructor of the class or interface represented by this
Class
object.
Constructor<?>[]
getDeclaredConstructors()

Returns an array of
Constructor
objects reflecting all the constructors declared by the class represented by this
Class
object.
Field
getDeclaredField(String name)

Returns a
Field
object that reflects the specified declared field of the class or interface represented by this
Class
object.
Field[]
getDeclaredFields()

Returns an array of
Field
objects reflecting all the fields declared by the class or interface represented by this
Class
object.
Method
getDeclaredMethod(String name,Class<?>... parameterTypes)

Returns a
Method
object that reflects the specified declared method of the class or interface represented by this
Class
object.
Method[]
getDeclaredMethods()

Returns an array of
Method
objects reflecting all the methods declared by the class or interface represented by this
Class
object.
这些方法与上面的方法类似,但是他们是类中声明的全部域,全部方法,全部构造器,包括私有和受保护的,但是不包括超类的。而之前的不带Declared是返回当前类共有的变量、方法、构造方法,包括父类和接口的

int
getModifiers()

Returns the Java language modifiers for this class or interface, encoded in an integer.
String
getName()

Returns the name of the entity (class, interface, array class, primitive type, or void) represented by this
Class
object, as a
String
.
返回该类的修饰类型,这个返回的是一个整形的编码,对应着其类型public, protected, private, final, static, abstract and interface,这些需要使用Modifier类进行解析。

getName()获取当前了类的完整类名

boolean
isInterface()

Determines if the specified
Class
object represents an interface type.
boolean
isLocalClass()

Returns
true
if and only if the underlying class is a local class.
boolean
isPrimitive()

Determines if the specified
Class
object represents a primitive type.
boolean
isSynthetic()

Returns
true
if this class is a synthetic class; returns
false
otherwise.
T
newInstance()

Creates a new instance of the class represented by this
Class
object.
String
toString()

Converts the object to a string.
Class还提供了许多isXxx用来类型判断

newInstance()快速获取该类的实例,但是只能使用该类的无参构造方法,因为没有提供有参的构造方法,所以必须保证该类有无参构造方法。之后可以通过Constructor类的newInstance()提供含参的构造方法。

java.lang.reflect反射api接口



这里面有Field、Method、Constructor、Modifier类,都是之前提到类

AccessiableObject类:是Field、Method、Constructor的超类,其中方法setAccessible设置为true可以设置允许访问私有域

Array类:提供了动态生成和访问数组的类

Field类:提供类的域的信息,以及访问域的接口

Constructor类:提供了类的构造方法的信息,以及访问构造方法的接口

Modifier类:提供了类的方法信息,以及访问该类方法的接口

通过代码来看获取这些信息:

[java] view
plaincopyprint?

class ReflectionTest{

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

String name = scanner.next();

try{

Class c1 = Class.forName(name);

Class superCl = c1.getSuperclass();

System.out.println("superClass"+superCl.getName());

String modifilter = Modifier.toString(c1.getModifiers());

System.out.println("modifiers:" + modifilter );

printContruct(c1);

}catch(ClassNotFoundException e){

e.printStackTrace();

}

System.exit(0);

}

public static void printContruct(Class c1){

System.out.println("*********打印Constructor*********");

Constructor[] construct = c1.getConstructors();

for (Constructor c : construct) {

System.out.println("该构造方法所属类:" + c.getName());

System.out.println("使用Modifier类:" +Modifier.toString(c.getModifiers()) );

Class[] paramTypes = c.getParameterTypes();

for (Class class1 : paramTypes) {

System.out.println("参数类型:"+class1.getName());

}

System.out.println("toString方法:" + c.toString());

}

}

public static void printField(Class c1) throws IllegalArgumentException, IllegalAccessException{

System.out.println("*********打印Field*********");

Field[] fields = c1.getFields();

for (Field field : fields) {

System.out.println("获取所属类:" +field.getName());

System.out.println(Modifier.toString(field.getModifiers()));

System.out.println("获取type" + field.getType());

Object b = new ReflectionTest();

System.out.println("get()方法做什么用的:"+field.get(b));//对应还有getDouble(),getInt()....

}

}

public static void printMethod(Class c1){

System.out.println("*********打印Method*********");

Method[] method = c1.getDeclaredMethods();

for (Method m : method) {

System.out.println(m.getName());

System.out.println(m.getReturnType());//获取返回类型

m.invoke(obj, args)//允许调用包装在Method对象中的方法。

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: