
嘻道奇闻
- 文章199742
- 阅读14625734
5种Java反射调用私有方法场景与避坑指南
鍦烘櫙1锛氬崟鍏冩祴璇曡楠屽案 馃И
"娴嬭瘯绉佹湁鏂规硶锛熻繖涓嶆槸鑴辫¥瀛愭斁灞佸悧锛? 寰堝鏂版墜鐪嬪埌绉佹湁鏂规硶鍔燖Test娉ㄨВ鎶ラ敊閮芥嚨杩囥€傛瘮濡傜數鍟嗙郴缁熺殑鐢ㄦ埛鏍¢獙鏂规硶锛?/p>
java澶嶅埗private boolean isValidUser(String phone){...}
鈥?strong>鈥嬫毚鍔涚牬瑙f硶鈥?/strong>鈥嬶細
java澶嶅埗@Test void testUserCheck() throws Exception { Method method = UserService.class.getDeclaredMethod("isValidUser", String.class); method.setAccessible(true); //馃攽 鍏抽敭閽ュ寵 assertTrue((boolean)method.invoke(userService, "13812345678")); }
馃挜閬垮潙鎸囧崡锛?/p>
- 蹇呴』鐢?code>setAccessible(true)瑙i櫎灏佸嵃
- 娴嬭瘯瀹岀珛鍗宠繕鍘熸潈闄愶紙閬垮厤褰卞搷鍏朵粬娴嬭瘯鐢ㄤ緥锛?/li>
- JUnit5鍙互鐢ˊReflectiveAccess娉ㄨВ鏇翠紭闆呭鐞?/li>
鍦烘櫙2锛氱牬瑙g涓夋柟搴撳皝鍗?馃敁
閬囧埌鑰佸鍐欑殑SDK閲屾湁杩欐牱鐨勪唬鐮侊細
java澶嶅埗private void initSecureConnection(){...} //涓嶈皟鐢ㄥ氨鎶ラ敊
鍜变滑鍙互杩欐牱寮哄惎锛?/p>
java澶嶅埗public void forceInitSDK() { try { Method init = ThirdPartySDK.class.getDeclaredMethod("initSecureConnection"); init.setAccessible(true); init.invoke(sdkInstance); } catch (Exception e) { throw new RuntimeException("鑰佸鍩嬬殑闆风偢浜?, e); } }
鈿狅笍琛€娉暀璁細鏌愭敮浠樼郴缁熷崌绾DK鐗堟湰鍚庯紝杩欎釜鏂规硶鍚嶅彉鎴愪簡initializeSecureConn()
锛屽鑷寸嚎涓婃晠闅溾€斺€旀墍浠ヤ竴瀹氳鍔犵増鏈垽鏂紒
鍦烘櫙3锛氬姩鎬佷唬鐞嗙帺鑺辨椿 馃幁
缁欏唴閮ㄦ湇鍔″仛鐩戞帶浠g悊鏃讹紝鍙戠幇鐩爣鏂规硶闀胯繖鏍凤細
java澶嶅埗private String internalApiCall(int code){...}
浠g悊鏂规锛?/p>
java澶嶅埗public Object invoke(Object proxy, Method method, Object[] args) { // 鐩戞帶浠g爜... Method targetMethod = target.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes()); targetMethod.setAccessible(true); Object result = targetMethod.invoke(target, args); // 鏃ュ織璁板綍... return result; }
馃搶鎬ц兘鏁版嵁锛氬湪10000娆¤皟鐢ㄤ腑锛岀紦瀛楳ethod瀵硅薄姣旀瘡娆¢兘鍙嶅皠鑾峰彇蹇?7鍊嶏紒
鍦烘櫙4锛氬吋瀹瑰巻鍙查仐鐣欎唬鐮?馃彌锔?/h3>
鎺ユ墜10骞村墠鐨勮€佺郴缁燂紝鍙戠幇杩欐牱鐨勭浼犱唬鐮侊細
java澶嶅埗private void saveToDB_V1(){...} //宸插簾寮冧絾蹇呴』淇濈暀
鏂伴渶姹傝鍚屾椂鏀寔鏂版棫鐗堟湰瀛樺偍锛?/p>
java澶嶅埗public void saveData(boolean isLegacy) { String methodName = isLegacy ? "saveToDB_V1" : "saveToDB_V2"; Method saveMethod = Dao.class.getDeclaredMethod(methodName); saveMethod.setAccessible(true); saveMethod.invoke(dao); }
馃挕瀹炴垬缁忛獙锛氱敤鏋氫妇绠$悊鐗堟湰鏂规硶鍚嶏紝閬垮厤婊″睆鐨刬f-else
鍦烘櫙5锛氬疄鐜版鏋剁骇鎵╁睍 鉁?/h3>
寮€鍙戣嚜宸辩殑ORM妗嗘灦鏃讹紝闇€瑕佸鐞嗗疄浣撶被鐨勭鏈塻etter锛?/p>
java澶嶅埗private void setCreatedTime(LocalDateTime time){...}
鍙嶅皠瑙e喅鏂规锛?/p>
java澶嶅埗public void injectValue(Object entity, String fieldName, Object value) { String setterName = "set" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1); Method setter = entity.getClass().getDeclaredMethod(setterName, value.getClass()); setter.setAccessible(true); setter.invoke(entity, value); }
馃毃瀹夊叏璀︽姤锛?/p>
- 蹇呴』鏍¢獙鏂规硶鍙傛暟绫诲瀷
- 瑕佸鐞嗙户鎵块摼涓婄殑绉佹湁鏂规硶
- 闃茶寖鎭舵剰璋冪敤閾撅紙姣斿閫氳繃鍙嶅皠璋冪敤
System.exit()
锛?/li>
闃茬炕杞﹀疂鍏?馃摉
- 鈥?strong>鈥嬫潈闄愮鎺р€?/strong>鈥嬶細鐢ㄥ畬绔嬪嵆
setAccessible(false)
锛屽氨鍍忕敤瀹岀叅姘旇鍏抽榾闂?/li> - 鈥?strong>鈥嬫€ц兘浼樺寲鈥?/strong>鈥嬶細鎶奙ethod瀵硅薄缂撳瓨鍒伴潤鎬丮ap锛岄€熷害鐩存帴璧烽
- 鈥?strong>鈥嬪紓甯稿鐞嗏€?/strong>鈥嬶細蹇呴』鎹曡幏InvocationTargetException锛屽惁鍒欏紓甯稿爢鏍堜細涓㈠け
- 鈥?strong>鈥嬬増鏈€傞厤鈥?/strong>鈥嬶細绉佹湁鏂规硶鏀瑰悕鏄父鏈夌殑浜嬶紝瑕佸仛濂藉吋瀹规柟妗?/li>
鏌愮數鍟嗗钩鍙扮殑琛€妗堬細鍥犱负娌℃湁缂撳瓨Method瀵硅薄锛屽湪澶т績鏈熼棿鍙嶅皠璋冪敤瀵艰嚧GC椋欏崌锛岀洿鎺ユ崯澶?00涓囪鍗曗€斺€旂幇鍦ㄤ粬浠殑浠g爜閲岄兘寮哄埗鍔犱笂浜?code>ConcurrentHashMap缂撳瓨灞傦紒
鐏甸瓊鎷烽棶锛氬弽灏勮繖涔堝嵄闄╋紝涓哄暐杩樿鐢紵馃し
鑰佺帇鍦ㄤ唬鐮佽瘎瀹℃椂璇村緱濂斤細"寮€杞﹀彲鑳藉嚭杞︾ジ锛屼絾浣犱細鍥犳涓嶈€冮┚鐓у悧锛? 鍏抽敭鏄鍋氬埌锛?br/> 鉁?鏄庣‘浣跨敤杈圭晫锛堝彧鍦ㄥ繀瑕佸満鏅敤锛?br/> 鉁?鍋氬ソ瀹夊叏闃叉姢锛堟潈闄愭帶鍒?寮傚父鎹曡幏锛?br/> 鉁?鎬ц兘浼樺寲鍒颁綅锛堢紦瀛?鎳掑姞杞斤級
涓嬫褰撲綘蹇嶄笉浣忔兂鐢ㄥ弽灏勭牬瑙g鏈夋柟娉曟椂锛屽厛闂嚜宸变笁涓棶棰橈細
- 鏈夋病鏈夋洿瀹夊叏鐨勬浛浠f柟妗堬紵
- 鏄惁鍋氬ソ浜嗗厹搴曞鐞嗭紵
- 杩欎釜鎿嶄綔涓夊勾鍚庣湅浼氫笉浼氳鍚庝汉楠傦紵
姣曠珶锛屽挶浠啓鐨勪笉鏄竴娆℃€т唬鐮侊紝鑰屾槸瑕佸湪鍚屼簨闂存祦浼犵殑浼犺鍟婏紒锛堟墜鍔ㄧ嫍澶达級