1.简介 反射API可以获取程序在运行时刻的内部结构,反射API提供的动态代理是非常强大的功能,可以原生的实现AOP中的方法拦截功能,反射API就好像在看一个Java类在水中的倒影,知道Java类的内部结构,就可以和它们进行交互,包括创建对象,调用对象的方法,与直接在源代码中的交互是一样的,但又提供了额外的在运行时候的灵活性,但反射的一个最大的弊端就是性能比较差,相同的操作,用反射API所需的时间大概比直接使用慢一两个数量级,不过现在的JVM实现中,java反射的性能有很大的提升,在灵活和性能中需权衡
2.基本用法 反射API的第一个主要作用就是在程序运行时获取内部结构,能遍历出一个Java类中所有的内部结构,反射API的另一个强大的功能就是能在运行时刻操作java对象进行操作,包括动态的创建一个java类对象,获取每个域的值,以及调用某个方法
package com.reflect;
import java.util.List;
/**
* Person类 为后续的反射的使用服务 为方便程序调试,本程序中全部使用JUnit测试
*/
public class Person {
// 设置字段
public String name = "name";
private int age;
private static double height;
// 无参构造方法
public Person() {
System.out.println("Person");
}
// 含参构造方法
public Person(String name) {
System.out.println("Person" + name);
}
public Person(String name, int password) {
System.out.println("Person" + name + password);
}
private Person(List list) {
System.out.println("list");
}
// 其他共有方法
public void aa(String name, int password) {
System.out.println(name + ":" + password);
}
public void bb(String name, int[] password) {
System.out.println(name + ":password数组");
}
public Class[] cc() {
return new Class[] { String.class };
}
public static void dd() {
System.out.println("静态方法");
}
// 私有方法
private void ee() {
System.out.println("私有方法ee");
}
// main方法
public static void main(String[] args) {
System.out.println("main 方法");
}
}
package com.reflect;
/**
* 反射:加载类的方法
*/
public class demo1 {
public static void main(String[] args) throws Exception {
//加载类的方法一
Class clazz1=Class.forName("com.reflect");
//加载类的方二
Class clazz2=new Person().getClass();
//加载类的方法三
Class clazz3=Person.class;
}
}
package com.reflect;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
/**
* 反射类的构造方法
* @author Administrator
*/
public class demo2 {
//反射构造函数Person()
@Test
public void test1() throws Exception
{
Class clazz = Class.forName("com.reflect.Person");
Constructor c = clazz.getConstructor(null);
Person p = (Person)c.newInstance(null);
System.out.println(p.name);//测试对象是否创建成功
}
//反射构造函数Person(String name)
@Test
public void test2() throws Exception{
Class clazz=Class.forName("com.reflect.Person");
Constructor c=clazz.getConstructor(String.class);
Person p=(Person) c.newInstance("python");
System.out.println(p.name);//测试对象是否创建成功
}
//反射构造函数Person(String name,int password)
@Test
public void test3() throws Exception{
Class clazz=Class.forName("com.reflect.Person");
Constructor c=clazz.getConstructor(String.class,int.class);
Person p=(Person) c.newInstance("wangxiao",123456);
System.out.println(p.name);
}
//反射私有构造函数Person(List list)
@Test
public void test4() throws Exception
{
Class clazz = Class.forName("com.reflect.Person");
Constructor c = clazz.getDeclaredConstructor(List.class);
c.setAccessible(true);
int[] a = {2,3,4};
List list = Arrays.asList(a);
Person p = (Person)c.newInstance(list);
System.out.println(p.name);//测试对象是否创建成功
}
//反射对象的另一种方法,默认无参构造函数
@Test
public void test5() throws Exception{
Class clazzClass=Class.forName("com.reflect.Person");
Person p=(Person) clazzClass.newInstance();
System.out.println(p.name);//测试对象是否创建成功
}
}
package com.reflect;
import java.lang.reflect.Method;
import org.junit.Test;
/**
* 解剖类的所有方法
*/
public class demo3 {
//反摄aa()
@Test
public void test1() throws Exception{
System.out.println("test1程序结果--------------");
Class clazzClass=Class.forName("com.reflect.Person");
Person p=(Person) clazzClass.newInstance();
Method method=clazzClass.getMethod("aa", String.class,int.class);
method.invoke(p, "wangxiao",123);
}
//反射bb()
@Test
public void test2() throws Exception
{
System.out.println("test2程序结果------------");
Class clazz = Class.forName("com.reflect.Person");
Person p=(Person) clazz.newInstance();
Method m=clazz.getMethod("bb",String.class, int[].class);
int[] a ={1,2,3};
m.invoke(p,"zzw", a);
}
//反射cc()
@Test
public void test3() throws Exception
{
System.out.println("test3程序结果------------");
Class clazz = Class.forName("com.reflect.Person");
Person p = (Person) clazz.newInstance();
Method m = clazz.getMethod("cc",null);
Class[] c= (Class[]) m.invoke(p,null);
for(Class cla:c)
System.out.println(cla.getName());
}
//反射dd()
@Test
public void test4() throws Exception
{
System.out.println("test4程序结果------------");
Class clazz = Class.forName("com.reflect.Person");
Method m = clazz.getMethod("dd",null);
m.invoke(null,null);//静态方法可以不用对象,当然加对象也不会出错
}
//反射ee()
@Test
public void test5() throws Exception
{
System.out.println("test5程序结果------------");
Class clazz = Class.forName("com.reflect.Person");
Person p = (Person) clazz.newInstance();
Method m = clazz.getDeclaredMethod("ee",null);
m.setAccessible(true);//设置查看私有方法的权限
m.invoke(p,null);
}
//反射 main(),注意此处的参数传递方法
@Test
public void test6() throws Exception
{
System.out.println("test6程序结果------------");
Class clazz = Class.forName("com.reflect.Person");
Method m = clazz.getDeclaredMethod("main",String[].class);
m.invoke(null,new Object[]{new String[]{"aa","bb"}});//正确
m.invoke(null,(Object)new String[]{"aa","bb"});//正确
}
}