java 反射 常用函数_Java 反射详解

什么是反射?

反射(Reflection)能够让运行于 JVM 中的程序检测和修改运行时的行为。

Class 类

在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。虚拟机利用运行时信息选择相应的方法执行。可以通过专门的Java类访问这些信息,保存这些信息的类被称为Class。

将Class类中的forName和newInstance配合使用,可以根据存储在字符串中的类名创建一个对象。

String s = "java.util.Date";

Object m = Class.forName(s).newInstance();

为什么需要反射?

通过反射,我们能够

在运行时检测对象的类型;

动态构造某个类的对象;

检测类的属性和方法;

任意调用对象的方法;

修改构造函数、方法、属性的可见性。

JUnit

JUnit通过反射来遍历包含 @Test 注解的方法,并在运行单元测试时调用它们。

Web框架

开发人员可以在配置文件中定义对各种接口和类的实现。通过反射机制,框架能够快速地动态初始化所需要的类。

Spring框架使用如下的配置文件:

当Spring容器处理 bean 元素时,会使用Class.forName("com.programcreek.Foo")来初始化这个类,并再次使用反射获取 property 元素对应的setter方法,为对象的属性赋值。

Servlet

someServlet

com.programcreek.WhyReflectionServlet

如何使用反射?

反射的基本方法

本着不重复造轮子的原则,API 详细参考自 这里,下面只做简单介绍。

在java.lang.reflect包中有三个重要的类:

Field:描述类的域

Method:描述类的方法

Constructor:描述类的构造器

对于public域(包括超类成员):

getFields

getMethods

getConstructors

对于其它域(包括私有和受保护的成员,不包括超类成员):

gettDeclaredFields

gettDeclaredMethods

gettDeclaredConstructors

下面介绍 Java 反射的使用,其中 Person 类及测试完整代码在本文最后。

加载类

// 加载类的3种方法

Class clazz = Class.forName("com.yano.reflect.Person");

Class clazz1 = new Person().getClass();

Class class2 = Person.class;

获取类的无参构造函数,并实例化类

Class clazz = Class.forName("com.yano.reflect.Person");

Constructor c = clazz.getConstructor(null);

Person p = (Person) c.newInstance(null);

获取类的含参私有构造函数,并实例化类

Class clazz = Class.forName("com.yano.reflect.Person");

Constructor c = clazz

.getDeclaredConstructor(new Class[] { String.class });

// 由于构造函数是 private 的,所以需要屏蔽Java语言的访问检查

c.setAccessible(true);

Person p = (Person) c

.newInstance(new Object[] { "I'm a reflect name!" });

获取并调用类的无参方法

Class clazz = Class.forName("com.yano.reflect.Person");

Constructor c = clazz.getConstructor(null);

Person p = (Person) c.newInstance(null);

Method method = clazz.getMethod("fun", null);

method.invoke(p, null);

获取并调用类的含参方法

Class clazz = Class.forName("com.yano.reflect.Person");

Constructor c = clazz.getConstructor(null);

Person p = (Person) c.newInstance(null);

Method method = clazz.getMethod("fun", new Class[] { String.class });

method.invoke(p, new Object[] { "I'm a reflect method!" });

获取类的字段

Class clazz = Class.forName("com.yano.reflect.Person");

Constructor c = clazz

.getDeclaredConstructor(new Class[] { String.class });

// 由于构造函数是 private 的,所以需要获取控制权限

c.setAccessible(true);

Person p = (Person) c

.newInstance(new Object[] { "I'm a reflect name!" });

Field f = clazz.getField("name");

Object value = f.get(p);

Class type = f.getType();

System.out.println(type);

if (type.equals(String.class)) {

System.out.println((String) value);

}

完整代码

Person 类

package com.yano.reflect;

public class Person {

public String name = "default name";

public int[] array = new int[10];

public Person() {

System.out.println(name);

for (int i = 0; i < array.length; i++) {

array[i] = i;

}

}

private Person(String name) {

this.name = name;

System.out.println(name);

}

public void fun() {

System.out.println("fun");

}

public void fun(String name) {

System.out.println(name);

}

}

test 类

package com.yano.reflect;

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

public class test {

/**

* 反射:加载类的字节码

*

* @throws SecurityException

* @throws NoSuchMethodException

*/

public static void main(String[] args) throws Exception {

refGetClass();

// 获取并调用无参构造函数

refGetPublicConstructor();

// 获取并调用私有的含参构造函数

refGetPrivateConstructor();

// 获取并调用无参方法 fun

refGetMethodWithNoArg();

// 获取并调用有参数方法 fun

refGetMethodWithArg();

// 获取类的字段

refGetField();

}

private static void refGetField() throws Exception {

Class clazz = Class.forName("com.yano.reflect.Person");

Constructor c = clazz

.getDeclaredConstructor(new Class[] { String.class });

// 由于构造函数是 private 的,所以需要获取控制权限

c.setAccessible(true);

Person p = (Person) c

.newInstance(new Object[] { "I'm a reflect name!" });

Field f = clazz.getField("name");

Object value = f.get(p);

Class type = f.getType();

System.out.println(type);

if (type.equals(String.class)) {

System.out.println((String) value);

}

System.out.println();

}

private static void refGetMethodWithArg() throws Exception {

Class clazz = Class.forName("com.yano.reflect.Person");

Constructor c = clazz.getConstructor(null);

Person p = (Person) c.newInstance(null);

Method method = clazz.getMethod("fun", new Class[] { String.class });

method.invoke(p, new Object[] { "I'm a reflect method!" });

System.out.println();

}

private static void refGetMethodWithNoArg() throws Exception {

Class clazz = Class.forName("com.yano.reflect.Person");

Constructor c = clazz.getConstructor(null);

Person p = (Person) c.newInstance(null);

Method method = clazz.getMethod("fun", null);

method.invoke(p, null);

System.out.println();

}

private static void refGetPrivateConstructor() throws Exception {

Class clazz = Class.forName("com.yano.reflect.Person");

Constructor c = clazz

.getDeclaredConstructor(new Class[] { String.class });

// 由于构造函数是 private 的,所以需要屏蔽Java语言的访问检查

c.setAccessible(true);

Person p = (Person) c

.newInstance(new Object[] { "I'm a reflect name!" });

System.out.println();

}

private static void refGetPublicConstructor() throws Exception {

Class clazz = Class.forName("com.yano.reflect.Person");

Constructor c = clazz.getConstructor(null);

Person p = (Person) c.newInstance(null);

System.out.println();

}

private static void refGetClass() throws ClassNotFoundException {

// 加载类的3种方法

Class clazz = Class.forName("com.yano.reflect.Person");

Class clazz1 = new Person().getClass();

Class class2 = Person.class;

System.out.println();

}

}

本文参考自:

你可能感兴趣的:(java,反射,常用函数)