/* *作者:呆萌老师 *csdn认证讲师 *51cto高级讲师 *腾讯课堂认证讲师 *网易云课堂认证讲师 *华为开发者学堂认证讲师 *爱奇艺千人名师计划成员 *在这里给大家分享技术、知识和生活 *各种干货,记得关注哦! *vx:it_daimeng */
反射是框架设计的灵魂
一、什么是反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
二、反射的原理
反射就是把java类中的各种成分映射成一个个的Java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述
编辑
三、反射机制主要提供以下功能:
①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理。
四、Class类
1.获取Class对象的三种方式
1、Class clazz1 = Class.forName(“全限定类名”); //通过Class类中的静态方法forName,直接获取到一个类的字节码文件对象,此时该类还是源文件阶段,并没有变为字节码文件。
2、Class clazz2 = Person.class; //当类被加载成.class文件时,此时Person类变成了.class,在获取该字节码文件对象,也就是获取自己, 该类处于字节码阶段。
3、Class clazz3 = p.getClass(); //通过类的实例获取该类的字节码文件对象,该类处于创建对象阶段
通过类名获取Class对象,Class<T> c = Class.forName(“类的完全路径”);
通过Class对象获取具体的类对象:Object o = (Object) c.newInstance();
2、获取类中的构造方法:
编辑
编辑
3、获取类中的属性:
编辑
编辑
4、获取类中的方法:
编辑
编辑
五、反射的使用
注意:在运行期间,一个类,只有一个Class对象产生。
1.通过反射获取构造方法并使用
编辑
2 .通过反射获取不同的构造方法。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //response.getWriter().append("Served at: ").append(request.getContextPath()); //反射用法1 try { Class clazz1=Class.forName("com.test.pojo.Student"); //根据参数列表获得指定的构造函数 Constructor constructor= clazz1.getDeclaredConstructor(String.class,int.class); //根据构造函数创建对象 Student student=(Student) constructor.newInstance("zhangsan",23); response.getWriter().println(student.getSname()); //获得所有的构造函数 Constructor[] arr= clazz1.getDeclaredConstructors(); for(Constructor constructor2 : arr) { //获得构造函数的参数类型 Class[] brr= constructor2.getParameterTypes(); for(Class clazz2:brr) response.getWriter().print(clazz2.getName()+","); response.getWriter().println(); } } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //response.getWriter().append("Served at: ").append(request.getContextPath()); try { Class clazz=Class.forName("com.test.pojo.Student"); //获得student类中所有定义的属性(每个属性组装成了一个对象) Field[] arr=clazz.getDeclaredFields(); for(Field field: arr) { response.getWriter().println(Modifier.toString(field.getModifiers())+","+field.getName()+","+field.getType()); } //根据名称找到指定的字段 Field field=clazz.getDeclaredField("sid"); Student student=(Student) clazz.newInstance(); field.setAccessible(true); field.set(student, 1); response.getWriter().println(student.getSid()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
4、通过反射获取方法
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub //response.getWriter().append("Served at: ").append(request.getContextPath()); Class clazz=Student.class; Student student=new Student(); try { //通过反射 获得指定的方法 Method method= clazz.getDeclaredMethod("test", String.class,int.class); //调用改方法 method.invoke(student, "zhangsan",23); Method method2=clazz.getDeclaredMethod("test", int.class); Object o=method2.invoke(student, 25); System.out.println(o.toString()); } catch (NoSuchMethodException | SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } }