本文转自:https://blog.csdn.net/ft118520/article/details/79231435
Java反射机制,
1. 对任意的一个类都能知道这个列中的所有属性和方法,
2. 对于任意一个对象都能调用这个他的任意属性和方法。
反射必须要学习的一个类---------Class类
1. 所有的类文件都有共同的属性,路径,如字段,方法,构造函数等。把这些类向上的抽取,让他们共性的内容封装成一个类。这个类叫Class 。Class 字段中包含field、method、 constuction 。
1.1 field 包含修饰符,类型,变量名。可以把字段封装成一个对象来获取field内容
1.2 同理方法和构造函数Method、Contructor 要相对内容获取,必须要先获取字节码文件对象。该对象就是Class类型。
2. Class类描述信息,类的名称,类访问属性,类包名,字段列表,方法名称列表。
获取Class类的三种方式
Student s=new Student(); Class clazz1 = s.getClass(); Class clazz3 =Student.class; Class clazz2 = Class.forName("www.cn.wf.Student");
反射的代码
public class fanshe { public static void main(String args[]) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { try { Class<?> clazz = Class.forName("RegExpress.Person"); //获取所有构造器 Constructor[] constructor = clazz.getDeclaredConstructors(); for(int i =0;i<constructor.length;i++) { System.out.println(constructor[i]); } //获取特定构造器 Constructor con = clazz.getDeclaredConstructor(String.class,int.class,Person.class); //创建实例对象 con.setAccessible(true); Person person = (Person) con.newInstance("dousil",33,null); System.out.println(person); //获取名字这个字段 Field field = clazz.getDeclaredField("age"); field.setAccessible(true); //该field是在哪个对象的上边进行数据的获取的。 Integer age = (Integer) field.get(person); System.out.println(age); //设置field指端 field.set(person, 22); System.out.println(person); //对方法的处理机制 Method[] methods = clazz.getDeclaredMethods(); for(Method method:methods) { System.out.println(method); } Method myFriends = clazz.getDeclaredMethod("myFriends",null); myFriends.setAccessible(true); Object invoke = myFriends.invoke(person); System.out.println(invoke); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
为什么要用反射,以及什么时候用反射
转自:https://blog.csdn.net/weixin_41771218/article/details/82894852
优点
java 反射机制就是增加程序的灵活性,避免将程序写死在代码里。例如实力话一个person()对象,不适用反射,new Person();如果想要变成实例化的其他类那么必须改代码,并重新编译。
如果使用反射,可以将这个类的描述放到配置文件中,如**.xml中,这样如果实力化其他类,只需要修改配置文件就可以了。不需要重新修改代码并进行编译。
增加了程序的灵活性,如strus中,请求的派发控制,当请求来到的时候,strus通过查询配置文件,找到改请求对应的action。然后在通过反射将action实例化并调用method方法。如果不适用反射,那么就只能写死在代码里边了。
反射的缺点:
反射的效率比不用反射的效率低很多
反射必须要在一个安全限制的环境中运行
破坏了代码的抽象性。破坏了抽象性,平台发生改变,代码的行为可能发生改变。