一:通过反射获取类信息
获取类信息的方法:
方法 | 功能 |
---|---|
getName() | 获得类的名字(包名+类名) |
getSimpleName() | 获得类的简单名字(类名) |
getFields() | 获取类public属性 |
getDeclaredFields() | 得到全部的类属性 |
getField(String name) | 得到指定名称的类public属性 |
getDeclaredField(String name) | 得到全部指定名称的类属性 |
getMethods() | 获取本类及其父类全部的public方法 |
getDeclaredMethods() | 获得本类的所有方法 |
getMethod(name, parameterTypes) | 获取指定类public方法 |
getConstructors() | 获取全部public构造器 |
getDeclaredConstructors() | 获取全部构造器 |
getDeclaredConstructor(parameterTypes) | 获取指定构造器 |
样例代码:
Person类:
class Person{
public String name;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "Person [name=" + name + "]";
}
}
User类:
class User{
private String name;
private int age;
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试:
package Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//获得类信息
public class test07 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException {
Class c = Class.forName("Reflection.Person");
//获得类的名字(包名+类名)
System.out.println(c.getName());
//获得类的简单名字(类名)
System.out.println(c.getSimpleName());
System.out.println("<<<<<<<<getFields<<<<<<<<<<");
//获得类的属性
Field[] fields = c.getFields();
for(Field field:fields) {
System.out.println(field);
}
System.out.println("<<<<<<<<<getDeclaredFields<<<<<<<<<");
Field[] field2s = c.getDeclaredFields();
for(Field field:field2s) {
System.out.println(field);
}
System.out.println("<<<<<<<<<getField<<<<<<<<<");
Field name = c.getField("name");
System.out.println(name);
System.out.println("<<<<<<<<<获得类的方法<<<<<<<<<");
//获得类的方法
Method[] methods = c.getMethods();
for(Method m:methods) {
//System.out.println("正常的"+m);
}
methods = c.getDeclaredMethods();
for(Method k:methods) {
//System.out.println(k);
}
//获取指定方法
Method m1 = c.getMethod("toString", null);
Class c1 = Class.forName("Reflection.User");
Method m2 = c1.getMethod("setName", String.class);
System.out.println(m1);
System.out.println(m2);
System.out.println("<<<<<<<<<获得指定的构造器<<<<<<<<<");
//获得构造器
Constructor[] con = c.getConstructors();//获取全部public方法
Constructor[] con1 = c.getDeclaredConstructors();//全部方法
for(Constructor constructor:con) {
System.out.println(constructor);
}
//获得指定构造器
Constructor con2 = c.getConstructor(String.class);
System.out.println("***"+con2);
}
}
二:通过反射动态创建方法
方法 | 功能 |
---|---|
newInstance() | 本质上是调用类的无参构造来创造对象 |
invoke(对象,方法值) | 激活方法 |
setAccessible(true) | 关闭安全监测 |
- 通过反射构造一个方法
//反射获取class
Class c1 = Class.forName("Reflection.User");
//构造一个对象(默认是Object,所以强转)
User user1 = (User)c1.newInstance();//实际上调用了类的无参构造器
System.out.println(user1);
- 通过构造器创建对象
//反射获取class
Class c1 = Class.forName("Reflection.User");
//通过构造器创建对象
Constructor con = c1.getDeclaredConstructor(String.class,int.class);
User user2 = (User) con.newInstance("name",90);
System.out.println(user2);
- 通过反射调用方法
//反射获取class
Class c1 = Class.forName("Reflection.User");
//通过反射调用方法
User user3 = (User)c1.newInstance();
//通过反射获取方法
Method setname = c1.getDeclaredMethod("setName", String.class);
//invoke激活
setname.invoke(user3, "name2");
System.out.println(user3.getName());
- 通过反射操作属性
//反射获取class
Class c1 = Class.forName("Reflection.User");
//通过反射操作属性
User user4 = (User)c1.newInstance();
Field name = c1.getDeclaredField("name");
//关闭安全监测才能操作私有属性
name.setAccessible(true);
name.set(user4, "通过反射操作属性");
System.out.println(user4.getName());
性能分析:
比起直接new,频繁利用反射会大幅度降低性能,在使用大量反射但又不想拖慢性能的时候可以使用放弃安全检查来稍微提高一下效率。
package Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//性能分析
public class test09 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
test01();
test02();
test03();
}
//普通方式调用
public static void test01() {
User user = new User();
long startTime = System.currentTimeMillis();
for(int i=0;i<=10000000;i++) {
user.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方式执行时间"+(endTime-startTime)+"ms");
}
//反射方式调用
public static void test02() throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class c1 =Class.forName("Reflection.User");
User user = (User)c1.newInstance();
Method m = c1.getDeclaredMethod("getName", null);
long startTime = System.currentTimeMillis();
for(int i=0;i<=10000000;i++) {
m.invoke(user, null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方式执行时间"+(endTime-startTime)+"ms");
}
//关闭安全检查
public static void test03() throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class c1 =Class.forName("Reflection.User");
User user = (User)c1.newInstance();
Method m = c1.getDeclaredMethod("getName", null);
m.setAccessible(true);
long startTime = System.currentTimeMillis();
for(int i=0;i<=10000000;i++) {
m.invoke(user, null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射关闭安全检查执行时间"+(endTime-startTime)+"ms");
}
}
控制台输出: