English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
요약
자바에 대해 기본적인 위임 메커니즘이 없어 항상 불만을 갖고 있었지만, 최근에 조금의 시간이 있어서 반사를 사용하여 간단한 위임 모듈을 작성하여 참고로 제공합니다.
모듈 API
public Class Delegater()//공백 파라미터 생성자, 이 클래스는 위임 인스턴스를 관리하고 위임 메서드를 구현합니다 //정적 메서드 위임을 추가하고, 이 메서드와 파라미터로 구성된 인스턴스를 대표하는 정수형 값 ID를 반환합니다. 실패 시, 반환됩니다-1。 public synchronized int 함수위임추가(Class<?> srcClass, String methodName, Object... params); //인스턴스 메서드 위임을 추가하고, 이 메서드와 파라미터로 구성된 인스턴스를 대표하는 정수형 값 ID를 반환합니다. 실패 시, 반환됩니다-1。 public synchronized int addFunctionDelegate(Object srcObj, String methodName, Object... params); //정수형 ID에 따라 위임 인스턴스에서 메서드 위임을 제거하고, 성공 여부를 반환합니다 public synchronized Boolean removeMethod(int registerID); //이 위임 인스턴스에서의 모든 메서드 위임(비정렬)을 차례대로 실행합니다 public synchronized void invokeAllMethod(); //파라미터 테이블을 파라미터 타입 테이블로 변환합니다 private Class<?>[] getParamTypes(Object[] params); //지정된 Class, 메서드 이름, 파라미터 타입 테이블을 통해 메서드 인스턴스를 얻습니다 private Method getDstMethod(Class<?> srcClass, String methodName, Class<?>[] paramTypes); class DelegateNode(Method refMethod, Object[] params)//DelegateNode 클래스는 Object를 사용하지 않고 생성할 때, 정적 메서드 위임을 설명하며, 메서드 인스턴스 및 파라미터 테이블을 포함합니다 class DelegateNode(Object srcObj, Method refMethod, Object[] params)//DelegateNode 클래스는 Object를 사용하여 생성할 때, 인스턴스 메서드 위임을 설명하며, 클래스 인스턴스, 메서드 인스턴스 및 파라미터 테이블을 포함합니다 public void invokeMethod(); //이 노드 설명을 통해 메서드 위임을 실행합니다
소스 코드
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Hashtable; /**Delegater 클래스는 RTTI 및 반영을 사용하여 Java에서의 위임 메커니즘을 구현합니다 * @author 삼방석 * */ public class Delegater { static int register = Integer.MIN_VALUE; //ID 할당 변수 Hashtable<Integer,DelegateNode> nodeTable; //ID와 해당 위임에 대한 컨테이너를 관리합니다 public Delegater() { nodeTable = new Hashtable<Integer,DelegateNode>(); } //정적 메서드 위임을 추가합니다 public synchronized int 함수위임추가(Class<?> srcClass,String methodName,Object... params) { Class<?> paramTypes = getParamTypes(params); Method refMethod; if((refMethod = getDstMethod(srcClass,methodName,paramTypes)) != null) { register++; nodeTable.put(register,new DelegateNode(refMethod, params)); return register; } else { return -1; } } //동적 메서드 위임을 추가합니다 public synchronized int 함수위임추가(Object srcObj,String methodName,Object... params) { Class<?> paramTypes = getParamTypes(params); Method refMethod; if((refMethod = getDstMethod(srcObj.getClass(),methodName,paramTypes)) != null) { register++; nodeTable.put(register,new DelegateNode(srcObj,refMethod, params)); return register; } else { return -1; } } //한 메서드 위임을 제거합니다 public synchronized Boolean 메서드제거(int registerID) { if(nodeTable.containsKey(registerID)) { nodeTable.remove(registerID); return true; } return false; } //비정렬적으로 위임 메서드를 실행합니다 public synchronized void 호출모든메서드() { for (DelegateNode node: nodeTable.values()) { node.invokeMethod(); } } //将参数表转化为参数类型表 private Class<?();> getParamTypes(Object[] params) { Class<?>[] paramTypes = new Class<?>[params.length]; for (int i = 0; i < params.length; i++) { paramTypes[i] = params[i].getClass(); } return paramTypes; } //根据Class类实例、方法名、参数类型表获得一个Method实例 private Method getDstMethod(Class<?> srcClass, String methodName, Class<?>[] paramTypes) { Method result = null; try { result = srcClass.getMethod(methodName, paramTypes); if(result.getReturnType() != void.class) { System.out.println("警告,方法: ")+methodName+"有返回值!"); } } catch (NoSuchMethodException | SecurityException e) { System.out.println("找不到方法: ")+methodName+"确保它存在且可见!"); } return result; } } class DelegateNode { Object srcObj; Method refMethod; Object[] params; public DelegateNode(Method refMethod, Object[] params) { this.refMethod = refMethod; this.params = params; } public DelegateNode(Object srcObj, Method refMethod, Object[] params) { this.srcObj = srcObj; this.refMethod = refMethod; this.params = params; } public void invokeMethod() { try { refMethod.invoke(srcObj,params); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { System.out.println("메서드:");+refMethod.toString()+" 호출 실패!"); } } }
모듈 테스트
public class DelegaterTest { public void showInfo() { System.out.println("Hello Delegate!"); } public void showCustomInfo(String info) { System.out.println(info); } public static void showStaticInfo() { System.out.println("Static Delegate!"); } public static void showCustomStaticInfo(String info) { System.out.println(info); } public static void main(String[] args) { Delegater dele = new Delegater(); DelegaterTest tester = new DelegaterTest(); int ID = dele.addFunctionDelegate(tester,"showInfo"); dele.addFunctionDelegate(tester,"showCustomInfo","Custom!"); dele.addFunctionDelegate(DelegaterTest.class,"showStaticInfo"); dele.addFunctionDelegate(DelegaterTest.class,"showCustomStaticInfo","StaticCustom!"); dele.invokeAllMethod(); dele.removeMethod(ID); System.out.println("------------------"); dele.invokeAllMethod(); } }
실행 결과:
StaticCustom!
StaticDelegate!
Custom!
HelloDelegate!
------------------
StaticCustom!
StaticDelegate!
Custom!
기타 사항
일부 public 메서드는 register 변수의 스레드 safety를 보장하기 위해 synchronized를 사용합니다. 이는 다중 스레드에서 오류가 발생하지 않도록 합니다.
반환 값을 가진 위임에 대해 경고가 발생하지만, 모듈은 이러한 위임을 받아들이지만, 위임을 실행할 때 반환 값을 받을 수 없습니다.
위임에 추가할 수 있는 최대 값은 Integer.MAX_VALUE입니다.-Integer.MIN_VALUE를 초과한 오류 tolerance 처리를 고려하지 않았습니다. (일반적으로 이렇게 많은 함수가 위임을 필요로 하는 것은 아닙니다.)
위임 실행은 비정렬적이며, 성능 요구 시, 위임 함수는 블록 과정을 피하도록 해야 합니다. 그렇지 않으면 다른 위임 함수의 실행에 영향을 미칩니다.
문제가 더 있으면 함께 논의할 수 있습니다.
결론
이제 Java에서 반영사상을 통해 위임 기계 코드 설명이 완료되었습니다. 많은 도움이 되길 바랍니다. 관심이 있는 분은 이 사이트의 다른 Java 관련 주제를 계속 참조할 수 있습니다. 부족한 점이 있으면, 댓글을 남겨 주세요. 친구들이 이 사이트를 지지해 주셔서 감사합니다!
성명: 이 문서의 내용은 인터넷에서 가져왔으며, 저작권자는 모두 소유자입니다. 내용은 인터넷 사용자가 자발적으로 기여하고 업로드한 것이며, 이 사이트는 소유권을 가지지 않으며, 인공적인 편집을 하지 않았으며, 관련 법적 책임도 부담하지 않습니다. 저작권 문제가 있는 내용을 발견하면, 이메일을 보내 주시기 바랍니다: notice#oldtoolbag.com에 이메일을 보내면 (#을 @으로 변경하십시오) 신고하시고 관련 증거를 제공하십시오. 일단 확인되면, 이 사이트는 즉시 위반된 내용을 삭제합니다.