概念
反射是Java的一个特性,反射允许程序运行时动态获取类的所有信息以及对其进行操作。反射在框架(spring,springboot,mybatis等)中的使用非常的广发,可谓是框架的灵魂。
获取Class对象
在使用反射之前,需要获取到Class对象,获取到对象之后才可以对其进行操作。Java提供了三个获取Class对象的方法:
public class App { public static void main(String[] args) { } }
①.getClass()
.getClass()是Object类的方法,对象实例化之后可以调用该方法获取到Class对象。因为Java中的所有类隐式继承了Object类,所以每个类都包含.getClass()方法。
public static void main(String[] args) { App app = new App(); //根据实例获取类 Class appClass = app.getClass(); }
②.class
类直接.class就能获取Class对象。
public static void main(String[] args) { Class appClass = App.class; }
③Class.forName("classFullName")
这种方式与前俩各种不太一样,前两者在有了类之后才可以获取Class对象。这种方式根据全类名获取到类的Class对象,错误输入全类名会导致错误,所以需要捕获异常
public static void main(String[] args) { try { Class appClass = Class.forName("com.agi.App"); } catch (Exception e) { e.printStackTrace(); } }
在反射中,第三种方式用的比较多。
反射应用
创建Action接口
public interface Action { void doSomething(String param); }
创建Anno注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Anno { }
创建App类
@Anno public class App implements Action { private String name; public int count; public App() { } public App(String name, int count) { this.name = name; this.count = count; } private void print() { System.out.println(name + count); } @Override public void doSomething(String param) { System.out.println(name + "\t" + param); } public static void main(String[] args) { } }
获取注解
public static void main(String[] args) { try { Class app = Class.forName("com.agi.App"); //根据类型获取注解 Annotation annotation = app.getAnnotation(Anno.class); //获取所有注解 Annotation[] declaredAnnotations = app.getDeclaredAnnotations(); for (Annotation declaredAnnotation : declaredAnnotations) { System.out.println(declaredAnnotation); } } catch (Exception e) { e.printStackTrace(); } } // 打印结果 // @com.agi.Anno()
获取类实现的接口
public static void main(String[] args) { try { Class app = Class.forName("com.agi.App"); Class[] interfaces = app.getInterfaces(); for (Class inter : interfaces) { System.out.println(inter); } } catch (Exception e) { e.printStackTrace(); } } // 打印结果 // interface com.agi.Action
获取构造方法
public static void main(String[] args) { try { Class app = Class.forName("com.agi.App"); //根据参数类型获取公有构造器 Constructor constructor = app.getConstructor(new Class[]{String.class, int.class}); //根据参数类型获取构造器 Constructor declaredConstructor = app.getDeclaredConstructor(new Class[]{String.class, int.class}); //获取所有公有构造器 Constructor[] constructors = app.getConstructors(); //获取所有构造器 Constructor[] declaredConstructors = app.getDeclaredConstructors(); for (Constructor c : declaredConstructors) { System.out.println(c); } } catch (Exception e) { e.printStackTrace(); } } // 打印结果 /* public com.agi.App() public com.agi.App(java.lang.String,int) */
实例化对象
public static void main(String[] args) { try { Class app = Class.forName("com.agi.App"); //使用默认构(无参)造方法实例化对象 Object instance = app.newInstance(); Constructor appConstructor = app.getConstructor(); instance = appConstructor.newInstance(); //使用公有构造器实例化对象 Constructor constructor = app.getConstructor(new Class[]{String.class, int.class}); Object constructorInstance = constructor.newInstance("hi", 12); //使用构造器实例化对象 Constructor declaredConstructor = app.getDeclaredConstructor(new Class[]{String.class, int.class}); Object declaredConstructorInstance = declaredConstructor.newInstance("hi", 30); } catch (Exception e) { e.printStackTrace(); } }
获取成员变量
public static void main(String[] args) { try { Class app = Class.forName("com.agi.App"); //据名称获取公有成员变量 Field count = app.getField("count"); //根据名称获取成员变量 Field name = app.getDeclaredField("name"); //获取所有公有成员变量 Field[] fields = app.getFields(); //获取所有成员变量 Field[] declaredFields = app.getDeclaredFields(); for (Field field : declaredFields) { System.out.println(field); } } catch (Exception e) { e.printStackTrace(); } // 打印结果 // private java.lang.String com.agi.App.name // public int com.agi.App.count
成员变量赋值
public static void main(String[] args) { try { Class app = Class.forName("com.agi.App"); //使用默认构(无参)造方法实例化对象 Object instance = app.newInstance(); //获取成员变量 Field name = app.getDeclaredField("name"); //赋值 name.set(instance, "hello"); System.out.println(name.get(instance)); } catch (Exception e) { e.printStackTrace(); } } // 打印结果 // hello
获取成员方法
public static void main(String[] args) { try { Class app = Class.forName("com.agi.App"); //根据方法名获取公有方法 Method doSomething = app.getMethod("doSomething", String.class); //根据方法名获取方法 Method print = app.getDeclaredMethod("print"); //获取所有公有方法(包括Object类的方法) Method[] methods = app.getMethods(); //获取该类的所有方法 Method[] declaredMethods = app.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod); } } catch (Exception e) { e.printStackTrace(); } } // 打印结果 /* public void com.agi.App.doSomething(java.lang.String) public static void com.agi.App.main(java.lang.String[]) private void com.agi.App.print() */
成员方法调用
public static void main(String[] args) { try { Class app = Class.forName("com.agi.App"); //使用默认构(无参)造方法实例化对象 Object instance = app.newInstance(); //获取成员方法 Method method = app.getMethod("doSomething", String.class); method.invoke(instance, "hello"); } catch (Exception e) { e.printStackTrace(); } } // 打印结果 // null hello