Java反射————Method根据方法名称字符串调用方法
引言
之前瀏覽廖雪峰老師的個人博客網站,無意間發現了關于在Java8中獲取參數的方法,隨手一轉《Java 8中獲取參數名稱》,沒想到今天遇到一個功能,非常符合這種反射調用的使用場景。回看了這篇之前轉載的文章,然后根據自己的理解完成了這個功能。
場景描述
功能其實并不復雜。一個設備表中有兩個字段,A和B,希望既可以通過A來查找相應記錄,又能夠通過B來查找相應記錄,但問題就在于A和B的樣子非常相似,不僅類型相同,就連名字也幾乎完全一樣(lntDeviceType和ytDeviceType)。
我在Repository中定義了兩個方法,分別區分開不同設備類型的查詢:
public DeviceType findByYtDeviceType(String ytDeviceType); public DeviceType findByLntDeviceType(String lntDeviceType);可是如何在Service中區分應該調用哪個方法呢?第一個能想到的方法就是寫死,通過一個值來區分是根據A字段來查詢還是B字段來查詢,像如下這種形式:
public DeviceType findDeviceType(String column, String deviceTypeStr) {if(column.equals("yt")) {return findByYtDeviceType(deviceTypeStr);} else if (column.equals("lnt")) {return findByLntDeviceType(deviceTypeStr);} else {return null;} }上述代碼,通過一個colum字符串來得知究竟是通過ytDeviceType字段來查詢,還是通過lntDeviceType來查詢。問題可以得到解決,但是如果增加了一個C字段怎么辦?又增加了一個D字段呢?難道每加一個字段都要加一個else if 寫死一個分支?
解決辦法——反射調用
思考過后,我想到了通過反射的方式來實現這個功能:
public DeviceType findByDeviceType(String deviceTypeTitle, String deviceType) {// 校驗deviceTypeTitle是否正確try {Set<String> deviceTypeColumSet = mapper.convertValue(new DeviceType(), Map.class).keySet();if (!deviceTypeColumSet.contains(deviceTypeTitle))return null;String findBy = "findBy";// 根據deviceTypeTitle查找對應方法名并調用方法Method findByXxDeviceType = dtRepo.getClass().getMethod(findBy + StringUtils.capitalize(deviceTypeTitle),String.class);DeviceType deviceTypeBean = (DeviceType) findByXxDeviceType.invoke(dtRepo, deviceType);logger.info("按類型查找設備類型deviceTypeTitle = " + deviceTypeTitle + "; deviceType = " + deviceType);return deviceTypeBean;} catch (Exception e) {e.printStackTrace();}return null; }(說明:try塊的前三行代碼主要是驗證deviceTypeTitle是否在DeviceType類型的屬性之列,比如DeviceType有A、B兩個屬性,那么如果deviceTypeTitle是A或者B就符合要求,如果是C就不可以了。StringUtils.capitalize方法主要是將deviceTypeTitle的首字母變為大寫,然后加上前綴 “findBy” 從而得到Repository中的方法名)
因為不論是用哪個字段來查詢,其方法名始終都是? “findByXxxx” ,那何不通過映射自動匹配到對應的方法然后調用呢?這個時候我突然回想起了之前轉載的廖雪峰老師的博客《Java 8中獲取參數名稱》,簡單回看之后果然可以解決我的問題,再進一步搜索相關資料之后完成了上述代碼。
可以看到我通過拼接一個“findBy”前綴,然后將傳入的 deviceTypeTitle 首字母大寫與前綴拼接后即可得到Repository中對應的方法名,然后我通過方法名即可進行調用,完全不需要擔心未來擴展的問題。即便未來擴展新的設備類型字段,而只需要在Repository中按照 “findByXxxx” 命名規則新加一個查詢即可,service中的分發請求完全不需要改動,豈不美哉?!
綜上,就是關于通過方法名稱字符串映射調用方法的例子,希望能夠對大家有所幫助,歡迎文末留言。
總結
以上是生活随笔為你收集整理的Java反射————Method根据方法名称字符串调用方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蓝桥杯第七届决赛之---阶乘位数
- 下一篇: 复制含有随机指针节点的链表~哈希表的使用