反射的前提是得到这个类的class对象,这个class对象中存在该类的所有属性,方法等其他信息。反射机制存在于程序运行状态中,对于任何一个类,只要提供了该类的全限类名,就可以获取该类的所有信息。底层的工作就交给JVM完成。
下面是自己今天关于反射做的一个小练习入门案例,仅供小白学习 详细可参考 JDK_API ,如果有需要的同学可以留下邮箱哟
1 package agree.reflect; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Field; 5 import java.lang.reflect.Method; 6 7 /** 8 * @since 2018.8.4 9 * @author yangl 10 * 11 * Serializable实现序列化接口,标识该对象可以被序列化,在对象传递过程中,使用transient的 字段将不再存在持久化对象中 12 * 13 * 反射被广泛地用于那些需要在运行时检测或修改程序行为的程序中。这是一个相对高级 14 * 的特性,只有那些语言基础非常扎实的开发者才应该使用它。如果能把这句警示时刻放在心 15 * 里,那么反射机制就会成为一项强大的技术,可以让应用程序做一些几乎不可能做到的事情。 16 * 17 * 缺陷1: 性能第一 Performance Overhead 反射包括了一些动态类型,所以 JVM 18 * 19 * 缺陷2: 安全限制 Security Restrictions 20 * 使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有 安全限制的环境中运行, 如 21 * Applet,那么这就是个问题了。 22 * 23 * 缺陷3:内部暴露 Exposure of Internals由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方 24 * 法),所以使用反射可能会导致意料之外的副作用--代码有功能上的错误,降低可移植性。 25 * 反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。 26 * 27 */ 28 public class ReflectDemo { 29 public static void main(String[] args) throws Exception { 30 // 获取A对象主要是通过该类的class类对象构造方法然后通过newInstance方法实力化 31 // 获取A的构造方法 32 Constructor<A> a = A.class.getConstructor(String.class, String.class); 33 System.out.println("获取A的单个构造方法:" + a); 34 // 获取A的public 声明的构造方法构造方法 35 Constructor<A>[] as = (Constructor<A>[]) A.class.getConstructors(); 36 print(as, "构造方法 除了private"); 37 // 获取所有的构造方法 38 Constructor<A>[] all = (Constructor<A>[]) A.class.getDeclaredConstructors(); 39 print(all, "所有构造方法"); 40 41 // 得到客户的实例对象 42 A av = A.class.newInstance(); 43 A av1 = A.class.cast(av);// 将一个对象强制转换成此 Class 对象所表示的类或接口 44 System.out.println("获取实例化对象"+av1.getPwd()); 45 46 // 带参数实例化对象,由构造器实现 47 A av2 = a.newInstance("yangl", "1"); 48 System.out.println("得到带参数的实力化对象:"+av2.toString()); 49 50 // 获取类public所有的属性 51 Field[] fields = A.class.getFields(); 52 print(fields,"不包括private属性"); 53 54 //获取所有的成员属性 包括私有属性 55 Field[] allFields=A.class.getDeclaredFields(); 56 print(allFields,"类的所有成员属性"); 57 58 59 //获取成员所有方法 60 Method[] ms=A.class.getDeclaredMethods(); 61 print(ms, "成员所有的方法"); 62 63 //执行无参私有方法 64 Method m=A.class.getDeclaredMethod("sayHello"); 65 m.setAccessible(true);//修改执行权限 private 66 m.invoke(av1);//放入该对象 67 68 //执行带参方法 69 Method m2=A.class.getMethod("sayBye", String.class); 70 m2.invoke(av2, "leon"); 71 72 } 73 74 75 /** 76 * 打印数组 77 * @param objs 78 * @param msg 79 */ 80 public static void print(Object[] objs,String msg){ 81 for(Object obj:objs){ 82 System.out.println(msg+":"+obj.toString()); 83 } 84 } 85 86 87 }
package agree.reflect; public class A { public String name; private String pwd; public static int count; public A() { // TODO Auto-generated constructor stub this.pwd = "789A"; } private A(String name) { this.name = name; this.pwd = "456"; } public A(String name, String x) { this.name = name; this.pwd = x; } public String getPwd() { return pwd; } private void sayHello() { System.out.println("Hello A!"); } public void sayBye(String name){ System.out.println(name+",see you again~"); } @Override public String toString() { return "A [name=" + name + ", pwd=" + pwd + "]"; } }