Java反射
1. 定义
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态
语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序
可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。其中,有一个Class类型,
它是实现反射的起源,针对任何您想探勘的类,唯有先为它产生一个Class 对象,接下来才能经由后者唤起为数十多个的Reflection APIs。而关于jvm如何加载类的过程,见文
2. 实例应用
案例接口
public interface China { public void sayHello(String name, Integer age); }
案例类
public class Person implements China{ private int age; private String name; public int getAge() { return age; } public final void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person [age=" + age + ", name=" + name + "]"; } public Person(int age, String name) { super(); this.age = age; this.name = name; } public Person(int age){ super(); this.age = age; } public Person(String name){ super(); this.name = name; } public Person() { super(); } @Override public void sayHello(String name, Integer age) { System.out.println("hello "+ name + " : " + age); } }
public class ReflectTest { /** * 通过Class.forName和ClassLoader来加载类 * @throws ClassNotFoundException */ @Test public void test1() throws ClassNotFoundException{ Class<?> demo1 = null; Class<?> demo2 = null; Class<?> demo3 = null; Class<?> demo4 = null; demo1 = Class.forName("cn.test.reflect.Demo"); demo2 = new Demo().getClass(); demo3 = Demo.class; demo4 = Demo.class.getClassLoader().loadClass("cn.test.reflect.Demo"); System.out.println(demo1.getName()); System.out.println(demo2.getName()); System.out.println(demo3.getName()); System.out.println(demo4.getName()); } /** * 通过Class.forName("").newInstance()生成新对象,调用的是无参构造函数 * @throws ClassNotFoundException * @throws InstantiationException * @throws IllegalAccessException */ @Test public void test2() throws ClassNotFoundException, InstantiationException, IllegalAccessException{ Class<?> demo = Class.forName("cn.test.reflect.Person"); Person person = (Person) demo.newInstance(); person.setAge(12); person.setName("张三"); System.out.println(person); } /** * 打印出该类所有的信息:属性,方法,构造函数 * @throws ClassNotFoundException */ @Test public void test3() throws ClassNotFoundException{ Class<?> demo = Class.forName("cn.test.reflect.Person"); System.out.println("类属性"); Field[] fields = demo.getDeclaredFields(); for(Field field : fields){ int mo = field.getModifiers(); System.out.print(Modifier.toString(mo)+" "); System.out.print(field.getType().getName()+" "); System.out.print(field.getName()); System.out.println(); } System.out.println("所有方法"); Method[] methods = demo.getDeclaredMethods(); for(Method method : methods){ Class<?>[] parms = method.getParameterTypes(); int mo = method.getModifiers(); System.out.print(Modifier.toString(mo)+" "); System.out.print(method.getName()+"("); int i=1; for(Class<?> parm : parms){ System.out.print(parm.getName() + " arg"+i++); if(i<=parms.length){ System.out.print(","); } } System.out.print(")"); System.out.println(); } Constructor<?>[] constructors = demo.getConstructors(); System.out.print("构造方法:"); for(Constructor<?> constructor : constructors){ System.out.println(); Class<?>[] parms = constructor.getParameterTypes(); int mo = constructor.getModifiers(); System.out.print(Modifier.toString(mo)+" "); System.out.print(constructor.getName()+"("); int i=1; for(Class<?> parm : parms){ System.out.print(parm.getName() + " arg"+i++); if(i<=parms.length){ System.out.print(","); } } System.out.print("){}"); } } /** * 获取接口 * @throws ClassNotFoundException */ @Test public void test4() throws ClassNotFoundException{ Class<?> demo = Class.forName("cn.test.reflect.Person"); Class<?>[] intes = demo.getInterfaces(); for(Class<?> interf : intes){ System.out.println(interf.getName()); } } /** * 获取父类 * @throws ClassNotFoundException */ @Test public void test5() throws ClassNotFoundException{ Class<?> demo = Class.forName("cn.test.reflect.Person"); Class<?> superClass = demo.getSuperclass(); System.out.println(superClass.getName()); } /** * 反射调用类的中任意方法,需要知道方法名 * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException * @throws SecurityException * @throws NoSuchMethodException * @throws InvocationTargetException * @throws IllegalArgumentException */ @Test public void test6() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ Class<?> demo = Class.forName("cn.test.reflect.Person"); Person person = (Person) demo.newInstance(); Method sayHelloMethod = demo.getMethod("sayHello", String.class, Integer.class); sayHelloMethod.invoke(person, "张三", 20); Method setAgeMethod = demo.getMethod("setAge", Integer.class); setAgeMethod.invoke(person, 2); Method getAgeMethod = demo.getMethod("getAge"); System.out.println(getAgeMethod.invoke(person)); Method setNameMethod = demo.getMethod("setName", String.class); setNameMethod.invoke(person, "李四"); Method getNameMethod = demo.getMethod("getName"); System.out.println(getNameMethod.invoke(person)); Method toStringMethod = demo.getMethod("toString"); System.out.println(toStringMethod.invoke(person)); } /** * 反射设置属性值 * @throws ClassNotFoundException * @throws InstantiationException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws SecurityException * @throws IllegalArgumentException * @throws InvocationTargetException * @throws NoSuchFieldException */ @Test public void test7() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException{ Class<?> demo = Class.forName("cn.test.reflect.Person"); Person person = (Person) demo.newInstance(); Field ageField = demo.getDeclaredField("age"); ageField.setAccessible(true); ageField.set(person, 10); Field nameField = demo.getDeclaredField("name"); nameField.setAccessible(true); nameField.set(person, "王武"); System.out.println(person); } }