框架设计之魂——反射

Posted 呆萌老师博客号

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了框架设计之魂——反射相关的知识,希望对你有一定的参考价值。


 

/*
*作者:呆萌老师
*☑csdn认证讲师
*☑51cto高级讲师
*☑腾讯课堂认证讲师
*☑网易云课堂认证讲师
*☑华为开发者学堂认证讲师
*☑爱奇艺千人名师计划成员
*在这里给大家分享技术、知识和生活
*各种干货,记得关注哦!
*/

框架设计之魂——反射_字节码

反射是框架设计的灵魂

一、什么是反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

二、反射的原理

反射就是把java类中的各种成分映射成一个个的Java对象

例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述

框架设计之魂——反射_字节码_02

框架设计之魂——反射_字节码_03

编辑

三、反射机制主要提供以下功能:

①在运行时判断任意一个对象所属的类;

②在运行时构造任意一个类的对象;

③在运行时判断任意一个类所具有的成员变量和方法;

④在运行时调用任意一个对象的方法;

⑤生成动态代理。

四、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、获取类中的构造方法:

框架设计之魂——反射_构造函数_04

框架设计之魂——反射_字节码_05

框架设计之魂——反射_构造函数_06

框架设计之魂——反射_构造方法_07

3、获取类中的属性:

框架设计之魂——反射_字节码_08

框架设计之魂——反射_构造方法_09

框架设计之魂——反射_字节码_10

框架设计之魂——反射_字节码_11

4、获取类中的方法:

框架设计之魂——反射_构造方法_12

框架设计之魂——反射_字节码_13

框架设计之魂——反射_构造函数_14

框架设计之魂——反射_构造方法_15

五、反射的使用


注意:在运行期间,一个类,只有一个Class对象产生。

1.通过反射获取构造方法并使用

框架设计之魂——反射_构造函数_16

框架设计之魂——反射_字节码_17

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

框架设计之魂——反射_字节码_18

  1. 根据反射获取类中所有的字段
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

框架设计之魂——反射_字节码_19

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

框架设计之魂——反射_字节码_20

更多了解

​https://edu.51cto.com/lecturer/14175030.html​

以上是关于框架设计之魂——反射的主要内容,如果未能解决你的问题,请参考以下文章

万字总结之设计模式七大原则

万字总结之设计模式七大原则

万字总结之设计模式(扫盲篇)

hadoop之魂--mapreduce计算框架,让收集的数据产生价值 (第4篇)

Bootstrap框架

Spring简介