目录
- 概念
- 应用场景
- 反射常用API
- 获取字节码对象的三种方式
- 通过字节码对象获取其他对象
- 获取类中方法的几种方式
- 反射普通方法调用
- 反射私有方法调用
- 反射私有构造方法调用
- Field用法
- 总结
概念
反射:java提供的一种机制,可以在类的运行时期动态的获取类中所有的信息(任意字段、构造方法,普通成员方法。。。。)
应用场景
缺点:会破坏封装性,损失性能。 尽量少用反射
安卓应用场景:安卓中一些私有的类通常是系统相关的比如调用系统硬件设备等类,设备管理器。开发需要,就只能通过反射去调用这些私有的方法
Java应用场景:解耦的。在开发中,做一个项目是很多人一起开发,a(用户登录注册相关) b(列表,加入购物车) c(订单结算) 三个程序员共同开发
反射常用API
1.java.lang.Class
2.java.lang.reflect.Constructor
3.java.lang.reflect.Method
4.java.lang.reflect.Field
…
获取字节码对象的三种方式
//获取字节码对象的第一种方式: 类名.class*/Class clazz = User.class;//获取字节码对象的第二种方式: Class.forName(); 解耦合了 jdbcClass clazz1 = Class.forName("cn.itsource.reflect.User");//获取字节码对象的第三种方式 对象.getClass() Class clazz2 = new User().getClass();
通过字节码对象获取其他对象
//用字节码对象调用相关方法获取Field,Constructor,Method所有对象。(加s代表所有)Class clazz = User.class;Method[] ms = clazz.getMethods();Field[] fs = clazz.getFields();Constructor[] cs = clazz.getConstructors();
获取类中方法的几种方式
Class clazz = User.class;Method[] ms = clazz.getMethods(); //获取本类公有的方法和父类继承过来的方法Method[] ms2 = c2.getDeclaredMethods(); //获取本类公有和私有的所有方法 //获取指定的方法 (不加s代表指定)(没有参数类型就不写)Method m = clazz.getMethod("method",int.class); //获取本类和父类指定公有方法Method m2 = clazz.getDeclaredMethod("method",int.class);//获取本类指定可以是私有方法
反射普通方法调用
Class<User> clazz = User.class;//获取指定的方法,("方法名",参数类型.class)Method m = clazz.getMethod("method",int.class);User user = new User();//返回值表示调用方法本身的返回内容// obj :表示方法所属的对象 ,args:表示方法的实际参数。Object r = m.invoke(user, 10);System.out.println(r);
反射私有方法调用
private编译时期有效,反射是在运行时期
Class clazz = User.class;Method m = clazz.getDeclaredMethod("methodPrivate"); //2.获取指定的方法m.setAccessible(true); //暴力反射。破坏了封装,设置可以访问。//通过反射获取类的对象。但是private构造创建对象无效。需要先用反射去暴力获取私有构造方法再造对象Object newInstance = clazz.newInstance(); //底层反射。或者还用User user = new User();m.invoke(newInstance);
反射私有构造方法调用
//获取Runtime构造器对象Constructor<Runtime> c = Runtime.class.getDeclaredConstructor();//设置可以访问c.setAccessible(true);//invoke --> newInstance 通过反射创建Runtime类对象Runtime newInstance = c.newInstance();System.out.println(newInstance);//通过单例模式创建对象Runtime runtime = Runtime.getRuntime();System.out.println(newInstance);
Field用法
Field f = User.class.getDeclaredField("name");//设置可以访问f.setAccessible(true);User user = new User();f.set(user, "jack");System.out.println(f.get(user));System.out.println(user.getName());
总结
1.找到字节码对象
2.通过字节码对象找到具体对象(Method,Constructor,File)。
3.找具体要反射的方法
4.要反射的方法是私有的需要设置可以访问,setAccessible
5.调用,invoke,newInstance,set