大家都知道反射技术在Java里面时非常重要的一个技术点,因为Java好多框架的编写都是基于反射的,别的不多说,spring框架里面的IOC就是基于反射实现。那么什么是反射呢?JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。说白了,反射就是加载类,并且反射出类的各个组成部分的一种实现方式。
java是一种面向对象的语言,所以我们处理任何东西,第一反应就是去找对象,并且调用它内部封装的方法。接下来我们演示如何通过反射来获取一个类中的方法,并执行该方法。
1.定义一个简单Person类
package com.day09; public class Person { public void show() { System.out.println("I am zhangsan and my age is 1"); } public void show(String name) { System.out.println("I am " + name); } public void show(String name, int age) { System.out.println("I am " + name + " and my age is " + age); } private void show(String[] hobbies) { System.out.println("my hobby such as: "); for (String hobby : hobbies) { System.out.println(hobby); } } public String getNameAndAge() { return "zhangsan:32"; } public static void speak() { System.out.println("I am a person"); } public static void main(String[] args) { System.out.println("this is main!"); } }
2.利用Junit来演示进行演示测试
package com.day09; import java.lang.reflect.Method; import org.junit.Test; public class ReflectMethodDemo { /* * 反射普通的无参方法 public void show() */ @Test public void reflectNoParameter() throws Exception { // 将类加载如内存 Class<?> clazz = Class.forName("com.day09.Person"); // 传入方法的名称和方法的参数信息,得到我们需要的方法 Method method = clazz.getMethod("show", null); // 需要传入调用的对象,并传入方法参数,并运行该方法 method.invoke(clazz.newInstance(), null); } /* * 反射普通的方法 public void show(String name) */ @Test public void reflectOneParameter() throws Exception { // 将类加载如内存 Class<?> clazz = Class.forName("com.day09.Person"); // 传入方法的名称和方法的参数信息,得到我们需要的方法 Method method = clazz.getMethod("show", String.class); // 需要传入调用的对象,并传入方法参数,并运行该方法 method.invoke(clazz.newInstance(), "马里奥"); } /* * 反射普通的方法public void show(String name, int age) */ @Test public void reflectManyParameter() throws Exception { // 将类加载如内存 Class<?> clazz = Class.forName("com.day09.Person"); // 传入方法的名称和方法的参数信息,得到我们需要的方法 Method method = clazz.getMethod("show", String.class, int.class); // 需要传入调用的对象,并传入方法参数,并运行该方法 method.invoke(clazz.newInstance(), "马里奥", 100); } /* * 反射普通的私有方法 private void show(String[] hobbies) */ @Test public void reflectPrivateParameter() throws Exception { // 将类加载如内存 Class<?> clazz = Class.forName("com.day09.Person"); // 因为是私有方法,所以要用传入方法的名称和方法的参数信息,得到我们需要的方法 Method method = clazz.getDeclaredMethod("show", String[].class); // 因为是私有方法,需要打开权限,设为可见 method.setAccessible(true); // 需要传入调用的对象,并传入方法参数,并运行该方法new String[] { "游泳", "跑步", "健身", "篮球" } method.invoke(clazz.newInstance(), new Object[] { new String[] { "游泳", "跑步", "健身", "篮球" } }); } /* * 反射普通的无参方法public String getNameAndAge() */ @Test public void reflectReturnValue() throws Exception { // 将类加载如内存 Class<?> clazz = Class.forName("com.day09.Person"); // 传入方法的名称和方法的参数信息,得到我们需要的方法 Method method = clazz.getMethod("getNameAndAge", null); // 需要传入调用的对象,并传入方法参数,并运行该方法,用一个object对象接收参数 Object obj = method.invoke(clazz.newInstance(), null); System.out.println(obj); } /* * 反射静态方法 public static void speak() */ @Test public void reflectStatic() throws Exception { // 将类加载如内存 Class<?> clazz = Class.forName("com.day09.Person"); // 传入方法的名称和方法的参数信息,得到我们需要的方法 Method method = clazz.getMethod("speak", null); // 因为是静态方法,所以可以不传对象,直接null就行,并传入方法参数,并运行该方法 method.invoke(null, null); } /** * 反射main方法 * * @throws SecurityException * @throws NoSuchMethodException * */ @Test public void reflectMain() throws Exception { // 将类加载如内存 Class<?> clazz = Class.forName("com.day09.Person"); // 传入方法的名称和方法的参数信息,得到我们需要的方法 Method method = clazz.getMethod("main", String[].class); // 因为是静态方法,所以可以不传对象,直接null就行,并传入方法参数,并运行该方法 method.invoke(null, new Object[1]); } }
至此,我们已将常见的几种通过反射获取对象方法,并运行方法演示完毕,有不足的地方,希望大家多多提意见!