工作中日常总结、查看!!!
1.反射的前提必须有Class类,还有反射影响性能,日常运用不多,主要是在框架等中利用。
2.使用反射需要获取Class类,这个上篇文章中以做总结,可以查看上篇文章
3.反射是对运行的中类,进行刨析获取类中的方法,成员信息等
一、利用反射获取构造方法并创建对象
1.1获取构造方法的四种方法
1. Constructor getConstructor(Class... parameterTypes) 只能获得public修饰的构造方法
2. Constructor getDeclaredConstructor(Class... parameterTypes) 可以是public、protected、(默认)、private修饰符的构造方法。
3. Constructor[] getConstructors() 只能获得public的
4. Constructor[] getDeclaredConstructors()可以是public、protected、package-private、private修饰符的构造方法。
测试类:
测试类以及结果:
2.1根据获取的构造方法获取对应的类
T newInstance(Object... initargs)根据指定的参数创建对象,传入的参数一定要和原来构造方法的参数类型,顺序,个数要一致
void setAccessible(boolean flag)设置"暴力反射"——是否取消权限检查,true取消权限检查,false表示不取消
注:如果是获取非public,需要设置setAccessible为true,进行暴力获取。
二、获取类中的成员方法
一次获取一个方法:
Method getMethod 根据方法名和参数类型获得对应的方法对象,只能获得public的
Method getDeclaredMethod根据方法名和参数类型获得对应的方法对象,包括private的
一次获取多个方法:
Method[] getMethods()获得类中的所有成员方法对象,返回数组,只能获得public修饰的且包含父类的
Method[] getDeclaredMethods()获得类中的所有成员方法对象,返回数组,只获得本类的,包含private修饰的
测试类:
public class ActionMethodPojo { public void eat(){ System.out.println("eat方法执行了..." ); } public void eat(String food){ System.out.println("eat方法执行了..."+food) ; } public static void drink(String food){ System.out.println("静态方法执行了...喝" + food); } private int work(int a,int b){ System.out.println("非public方法执行了..." +(a+b)); return a+b; } 测试方法类:
public class getGirlMethod { public static void main(String[] args) throws Exception { Class<?> mCls = Class.forName("com.bank.pojo.ActionMethodPojo"); /** * getMethod 和getDeclaredMethod 两个方法都只能一次获取一个方法 * getMethod 方法只能获取public类型的方法 * getDeclaredMethod 方法可以获取 public protected 默认 private 以及静态方法 */ Method eat1 = mCls.getMethod("eat"); Method eat2 = mCls.getMethod("eat",String.class); Method drink = mCls.getDeclaredMethod("drink", String.class); Method work = mCls.getDeclaredMethod("work", int.class, int.class); //执行方法前需要获取一个实体类对象 ActionMethodPojo pojo = (ActionMethodPojo) mCls.getDeclaredConstructor().newInstance(); eat1.invoke(pojo); eat2.invoke(pojo,"猪蹄"); //这里静态方法可以不传对象 drink.invoke(null,"咖啡"); //非public方法执行需要暴力反射,才能正常执行,否则报错 work.setAccessible(true); Object result = work.invoke(pojo, 1, 9); System.out.println("result = " + result); /** * getMethods获取类中以及父类的pulbic方法 * getDeclaredMethods获取类中的所以方法 */ Method[] methods = mCls.getMethods(); for (Method method : methods) { System.out.println("method = " + method); } System.out.println("===========================" ); Method[] declaredMethods = mCls.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println("declaredMethod = " + declaredMethod); } } }
结果截图:
1.
2.
类中的成员变量获取不在细说,通过再次整理,开发中java中的反射轻易不要,除非非用不可。
三、练习一下自己定义一个框架:
1.配置文件
beanName=com.bank.pojo.DiyPojo mothedName=Study
2.测试类
public class DiyPojo { private void Study(String name){ System.out.println(name+"周末还在努力工作...."); } }
3.测试方法
public class DiySpring { public String ConfigName; public void actionWorking(String name) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //1.获取类加载器 InputStream in = DiySpring.class.getClassLoader().getResourceAsStream(ConfigName); //2.读取内容 Properties pp = new Properties(); pp.load(in); System.out.println("pp = " + pp); String beanName = pp.getProperty("beanName"); String mothedName = pp.getProperty("mothedName"); //3.执行方法 Class<?> bCls = Class.forName(beanName); Object instance = bCls.getDeclaredConstructor().newInstance(); Method method = bCls.getDeclaredMethod(mothedName,String.class); //暴力反射 method.setAccessible(true); method.invoke(instance,name); } public static void main(String[] args) throws NoSuchMethodException, IOException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException { DiySpring diySpring = new DiySpring(); diySpring.ConfigName="config.properties"; diySpring.actionWorking("狗子"); } }
简单的创建一个类,项目启动的时候可以把要加载的内容这样编辑,比如提前查库加载一些通用的信息、数据库的配置信息等