首页IT科技反射弧包括哪五个部分(反射时竟然NoSuchMethodException了!看这篇超详细的解决方案吧)

反射弧包括哪五个部分(反射时竟然NoSuchMethodException了!看这篇超详细的解决方案吧)

时间2025-05-02 16:51:48分类IT科技浏览4206
导读:前几天九哥在讲Servlet时,为了灵活地使用同一个Servlet来处理对同一张表的业务操作请求,我给学生讲解了BaseServlet工具类的封装,基本实现思路有如下几个步骤。...

前几天九哥在讲Servlet时            ,为了灵活地使用同一个Servlet来处理对同一张表的业务操作请求                  ,我给学生讲解了BaseServlet工具类的封装      ,基本实现思路有如下几个步骤            。

一. 反射封装BaseServlet工具类

使用反射封装BaseServlet工具类            ,无论是哪个Servlet接收到请求                  ,都由该类完成请求分发                  。因此该类的主要作用就是通过反射机制      ,确定我们请求的到底是哪个Servlet的哪个方法      。

/*  * BaseServlet 获取客户端请求的是哪个servlet的哪个方法  * */ public class BaseServlet extends HttpServlet {     @Override     protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {         //获取客户端发来请求的标识:即要执行的方法名         String method = req.getParameter("method");         //获取方法属于哪个Servlet类         Class<? extends BaseServlet> clazz = this.getClass();         //通过类字节码对象获取要执行方法的对象         try {             Method mh = clazz.getMethod(method, HttpServletRequest.class, HttpServletResponse.class);             //执行方法             mh.invoke(this,req,resp); // this.insert(req,resp);         } catch (Exception e) {             e.printStackTrace();         }     } }

二. 继承BaseServlet父类

以后再创建Servlet时      ,我们要使任意一个Servlet类                  ,不再直接继承HttpServlet            ,而是要继承统一的BaseServlet      ,完成请求的分发管理                  ,例如:

@WebServlet("/stuinfo") public class StuinfoServlet extends BaseServlet {     //删除方法     public void delById(HttpServletRequest req, HttpServletResponse resp) {     }     //修改学员信息     public void update(HttpServletRequest req, HttpServletResponse resp){     }     //根据学号查询方法     public void findById(HttpServletRequest req, HttpServletResponse resp)  {     }     //查询全部方法     public void findAll(HttpServletRequest req, HttpServletResponse resp)  {     }     //添加方法     public void insert(HttpServletRequest req, HttpServletResponse resp)  {     } }

三. 异常展现

然而有个别同学在按照上述思路自己编写代码时            ,却遇到了下面的NoSuchMethodException异常            。他排查许久未果,于是就来找九哥帮他解决                  。

四. 异常原因

起初                  ,九哥以为是学生从客户端发出请求时                  ,未携带执行方法的标识或携带的方法标识与实际方法名不匹配,从而导致通过反射机制获取方法对象时报错      。因为我们知道            ,在通过Methodmh=clazz.getMethod(method,HttpServletRequest.class,HttpServletResponse.class)获取Method对象时                  ,必须保证方法名            、参数匹配      ,才能找到指定的方法            ,否则就会出现此类异常      。

但经过排查                  ,发现并不是以上原因      ,该学生的代码如下:

@WebServlet("/stuinfo") public class StuinfoServlet extends BaseServlet {     //创建serivce层对象     private StuinfoService ss = new StuinfoSerivceImpl();          //查询方法     private void findAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {         //调用service层查询方法         List<Stuinfo> list = ss.findAll();         //将list集合数据保存到域对象中         req.setAttribute("stuList",list);         //跳转到主页面         req.getRequestDispatcher("index.jsp").forward(req,resp);     } }

五. 异常解决

可能你也一眼就看到了      ,上述代码中                  ,查询方法使用的是private修饰符            ,而私有成员在该类的外部是不能被访问的!因此我们在利用反射      ,通过getMethod()方法获取Method对象时就会出现NoSuchMethodException异常                  。所以现在的解决办法                  ,你是不是立刻就明朗了            ,我们直接将private改成public就可以了            。

六. 暴力反射

上面的问题是解决了,但大家还要知道                  ,反射机制中还有一种叫暴力反射                  ,听起来是不是很厉害!!利用暴力反射,即使被private修饰也可以进行正常的操作      。

九哥在这里给大家再补上一刀            ,反射里的Constructor                  、Field      、Method三个类都有getDeclaredXxx方法(这里的Xxx表示Constructor      、Field                  、Method)                  ,该方法可以不受权限控制      ,就能够获取到类中的这些成员信息                  。如果我们想要使用私有的构造函数            、字段      、方法            ,则会自动访问类的isAccessable                  ,其默认值是false      ,表示在访问成员时需要安全检查      ,如果发现是私有的则不允许访问            。所以                  ,如果我们想要访问类中的私有成员时            ,需要调用setAccessible(boolean flag)方法      ,将其改为true。这样                  ,我们就可以对类中的私有成员进行操作了                  。

*威哥Java学习交流Q群:691533824

加群备注:CSDN推荐       

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
vue在线聊天(vue:聊天对话框的实现) vue render ref(vue中的render函数(通俗、易懂))