- 参考:
- https://blog.csdn.net/a724888/article/details/80160662
- https://blog.csdn.net/sinat_38259539/article/details/71799078
- https://www.cnblogs.com/rocomp/p/4781987.html
- 反射(Reflection)
- 在java中,任何一个类都是类Class的实例对象,也叫类对象
- 反射机制:在运行状态时,动态获取目标类对象(Class对象),并对其进行相关操作的功能
- 反射获取类对象(Class对象)
// 1、通过类路径来获取类对象
Class c = Class.forName("reflection.Monkey");
// 2、通过类的实例对象来获取类对象
Class c = monkey.getClass();
// 3、通过类名直接获取类对象
Class c = Monkey.class;
- 通过类对象获取类的实例对象
- 直接调用类对象的 newInstance()方法获取实例对象
- 先获取类的构造器对象,再通过构造器对象获取类的实例对象
// 1、
// 直接调用newInstance()方法获取实例对象,必须保证类含有无参构造方法,否则会抛出异常
Monkey monkey = (Monkey) c.newInstance();
monkey.say();
// 2、
// 先获取构造器对象,必须保证类中有当前参数类型的构造方法,否则会抛出异常 java.lang.NoSuchMethodException
// 再通过构造器对象获取实例对象
Constructor<Monkey> constructor = c.getConstructor(String.class);
Monkey monkey = constructor.newInstance("孙悟空");
monkey.say();
- 通过类对象获取类的属性对象
// 获取所有的公有属性对象,如果没有不会抛出异常
Field[] fields = c.getFields();
// 获取属性名为 "name" 的公有属性对象,如果没有则抛出异常 java.lang.NoSuchFieldException
Field field = c.getField("name");
- 通过类对象获取类的方法对象
// 获取类的所有公有方法对象,包括继承父类的或者实现的接口的方法
Method[] methods = c.getMethods();
// 获取指定方法名的公有方法对象,如果当前方法没有参数则参数类型设置为null或者不填;如果有参数,类型不一致会抛出异常
Method say = c.getMethod("say");
Method say = c.getMethod("say",null);
Method cry = c.getMethod("cry",String.class);
// 获取指定方法的参数类型
Class[] agrs = say.getParameterTypes();
// 执行方法
// 第一个参数:类的实例对象
// 第一个参数:方法的参数,如果方法无参数,参数可不填或者填null
say.invoke(monkey);
say.invoke(monkey,null);
cry.invoke(monkey,"孙行者");
注:
如果要获取类的私有方法,调用 getDeclaredMethod() 方法可以获得所有访问权限的方法对象
Method method = c.getDeclaredMethod("say");
如果要执行私有方法,则必须设置
method.setAccessible(true);
- 通过 new 获取对象和通过反射获取对象的区别?
- new出的对象只能访问类的公有方法,反射出的对象可以访问类的私有方法
- new属于静态编译,反射属于动态编译;很多情况下我们无法new因为我们不知道具体的类,比如JDK动态代理中,我们的处理器可以代理不同的实例,我们在编译期根本不知道它要代理哪个实例,那么我们只能根据运行时它传入的具体实例通过反射动态获取实例的类信息。
- new方法相对于反射来说效率稍好一点