java的反射机制

反射的概念:

java的反射机制_第1张图片

1.Class类的引出

* 一切皆对象,用类来描述一般对象,但用什么来描述类这个对象呢?
 *  eg: Date  d=new Date(),用什么类来描述Date这个类呢?
 *  引入 Class类
 *  Class类 用来描述类或者接口的类型, 即描述类的类
 *  Class类的实例: 在JVM中的一份字节码
 *  
 *  当程序第一次把使用某一个java.utile.Date类的时候就会把该类的字节码对象加载进JVM

 *  并创建出一个Class对象,此时的Class对象就是java.utile.Data的字节码

2.获取Class类实例的三种方法

 *  //方式1.class属性
 *  //方式2.通过对象的getClass()方法来获取,getClass是object中的方法
 *  //方式3.通过Class类中的静态方法forname(String ClassName)
 *   

 *  方式2和方式3经常用,尤其是方式3在框架中用的很多

实例如图:

java的反射机制_第2张图片

3.通过反射去获取构造器

 * 需求:通过反射来获取某一个类的构造器
 * 1).获取该类的字节码对象
 * 2).从该类的字节码对象中去找需要获取的构造器
 * 
 * Class类获取所有构造器的方法:
 * Constructor类; 表示类中构造器的类型,Constructor的实例是某一个类中的构造器
 * 
 * public Constructor[] getConstructor();该方法只能获取当前Class表示类的public修饰的构造器
 * public Constructor[] getDeclaredConstructor();获取当前Class表示类中的所有构造器和访问权限无关
 * 
 * 
 * Class类获取指定构造器的方法:
 * public Constructor getConstructor(Class...parameterTypes):获取当前Class所表示类中指定的一个public修饰的构造器
 *    参数:parameterYypes表示:构造器参数的Class类型,即字节码对象
 *    
 *    eg: public User(String name)
 *    Constructor c=clz.getConstructor(String.class)
 *    
 * public Constuctor  getDeclaredConstructor(Class...parameterTypes):获取当前Class所表示类中指定的一个构造器

 java的反射机制_第3张图片java的反射机制_第4张图片

4.使用反射调用构造器创建对象

* 使用反射创建对象
 * 步骤:
 * 1):找到构造器所在类的字节码对象
 * 2):获取构造器对象
 * 3):使用反射,创建对象
 * 
 * Constructor<>类:表示类中构造器的类型,Constructor的实例就是某一个类中的某一个构造器
 * 常用方法:
 * public T newInstance(Object...initargs):如果调用带参数的构造器,只能使用该方式
 *  参数:initargs表示调用构造器的实际参数
 *  返回:返回创建的实例,T表示Class所表示类的类型
 */ 
// 如果一个类中的构造器可以直接访问,同时没有参数,那么直接使用Class类中的newInstance()方法创建对象

//访问私有的成员,必须将其设置为可访问的

//对象.setAccessible(true)

java的反射机制_第5张图片java的反射机制_第6张图片

5.九大内置Class实例

 * 有是三种获取Class对象的方法,但是基本数据类型不能表示为对象,也就不能使用getClass的方式
 * 基本类型没有类名的概念,而且也不能使用Class.forname(String className)方式获取Class对象
 * 
 * 问题:那么如何获取基本数据类型的字节码对象呢?
 * 所有的数据类型(引用数据类型和基本数据类型)都有Class属性,即第一种获取Class对象的方法
 * 
 * 九大内置Class实例:JVM中预先提供好的Class实例,有九种,byte short char int long double
 *  float boolean void(看Class的API)
 *  
 * 在8大基本数据类型的包装类中都有一个常量:TYPE,用于返回该包装类对应的基本类的字节码对象
 * system.out.println(Integer.class==int.class); //true
 * 
 * 注意:Integer和int是不同的数据类型
 * system.out.println(Integer.class==int.class); //false
 * 
 * 
 * 数组的Class实例:数组是引用数据类型,数组其实是对象
 * 如何来表示数组的Class实例
 * 方式1:数组类型.class
 * 方式2:数组对象.getclass
 * 
 * 数组没有包名所以不能使用第三种方法,即 Class.forname(String className)
 * 
 * 注意:所有的具有相同维数和相同元素类型的数组共享同一个字节码对象(非同一份字节码文件)
 * 
 * Class: 描述所有的类型,所以Class类中应该具备所有类型
 * object:描述所有的对象,所以在object类中应该具备所有对象的共同的方法

java的反射机制_第7张图片java的反射机制_第8张图片

6.使用反射获取类中的方法

* 使用反射获取类中的方法
 * 1).获取字节码对象
 * 2).获取方法所在类的方法
 * 3).获取方法
 * 
 * Class类中的常用方法:
 * public Method[] getMethods(): 获取包括自身和继承过来的所有public方法
 * public Method[] getDeclaredMetheds(): 获取自身类中所有的方法(不包过继承的),和访问权限无关
 * 
 * public Method getMethod(String methodName,Class..paramentTypes):
 * 表示调用指定的一个公共方法(包括继承的)
 * 
 * 参数:
 *   methodName:表示被调用方法的名字
 *   paramentTypes:表示调用方法的参数的Class类型,如String.class
 *   
 * public Method getDeclaredMethod(String methodName,Class..paramentTypes):
 * 表示调用指定的一个本类中的方法(不包括继承的)
 * 
 * 参数:
 *   methodName:表示被调用方法的名字

 *   paramentTypes:表示调用方法的参数的Class类型,如String.class

java的反射机制_第9张图片java的反射机制_第10张图片

7.使用反射调用类中的方法

* 使用反射调用问题:
 * 1).获取方法所在类的字节码对象
 * 2).获取方法对象
 * 3).使用反射调用方法
 * 
 * 如何使用反射调用一个方法:
 * 在Method类中的方法:
 * public Object invoke(Object obj,Object...args):表示调用当前Method所表示的方法
 *   参数:
 *     obj:表示被调用方法底层所属对象
 *     Method m=clz.getMethod("start",String.class);
 *     args:表示调用方法是传递的实际参数
 *     
 *   返回:
 *     底层方法的返回结果
 *     
 //调用静态方法,则  public Object invoke(null,Object...args),第一个参数毫无意义
 //这个null可以是任意值,因为静态方法的调用和对象无关

 *     
 
 // 调用私有方法:
 //  在调用私有方法之前应该设置该方法为可访问的
 *  又因为Method是AccessibleObject子类,所以Method中具备该方法
 *  所有在这道程序题中有: 

 *        m3.setAccessible(true);

java的反射机制_第11张图片java的反射机制_第12张图片

8.使用反射调用参数是数组的方法

* 使用反射调用数组参数:
 *         调用方法的时候把实际参数统统作为Object数组的元素即可

 *  Method对象.invoke(方法底层所属对象,new Object[]{实参})

java的反射机制_第13张图片

9.加载资源文件的路径

java的反射机制_第14张图片java的反射机制_第15张图片

10.反射其他的API

java的反射机制_第16张图片java的反射机制_第17张图片

你可能感兴趣的:(java的反射机制)