反射是框架设计的灵魂
反射使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)
要想解刨一个类就先拿到该类的Class对象 1.获取Class对象的三种方式
1.1 Object-->getClass(); 因为所有类都是继承Object类,所以调用Object类来获取
1.2 任何数据类型(包括基本数据类型)都有一个静态class属性
1.3 ***通过Class类的静态方法:forName(String classname) classname就是包名.类名 比如在Day包中的Apple类,就Day.Apple 在运行期间一个类只有一个Class对象产生
2.通过的反射来获取构造方法 Class类的newInstance()实际上是调用类中的无参构造,如果类中没有无参构造或者权限不是public那么这个方法无效。 不能取得父类的构造方法,只能在本类中
2.1 获取批量的构造方法: public Constructor[] getDeclaredConstructors();所有权限的构造方法 public Constructor[] getConstructors();所有public权限的构造方法
2.2 获取单个的构造方法: public Constructor getDeclaredConstructor();所有指定的构造方法 public Constructor getConstructor(); 所有public权限的指定构造方法
2.3 newInstance是Constructor类的方法(管理构造函数的类) public T newInstance(Object ... initargs) 可以使用它来创建新对象
3.通过反射取得信息:
3.1 取得包信息:getPackage();
3.2 取得父类的Class对象:getSuperclass();
3.3 取得父接口信息:getInterfaces();
4.通过反射取得类的普通方法:
4.1 取得全部普通方法:public Method[] getMethods(); 4.2 取得指定普通方法:public Method getMethod(String name,Class<?>...parameterTypes); 4.3 调用invoke:public Object invoke(Object obj,Object...args);
5.通过反射取得类中普通属性: 5.1 (父类中)取得类中全部属性:public Field[] getFields(); 5.2 (父类中)取得类中指定属性:public Field getField(String name); 5.3 (本类中)取得类中全部属性:public Field[] getDeclaredFields(); 5.4 (本类中)取得类中指定属性:public Field getDeclaredField(String name); 5.5 设置属性内容:public void set(Object obj,Object value); 取得属性内容:public Object get(Object obj);
6.反射特性:动态破坏封装性 Constructor/method/field都继承AccessibleObject类; 此类中有一个破坏封装的方法:public void setAccessible(boolean flag) 反射并非永久破坏动态封装性,只是在一次JVM进程中,当下次启动JVM进程时,依旧封装,并且只能通过反射来调用。 取得属性类型:public Class<?> getType();