2013-04-25 5 views
2

안녕하세요 저는 성취를 위해 반사를 사용하고 있습니다. 클래스 이름, 해당 클래스의 메서드 이름 및 파일의 해당 메서드에 전달해야하는 매개 변수 값이 제공되었습니다 (제약 조건이 아닌 파일 가져 오기). 매개 변수를 사용하여 해당 메서드를 호출해야합니다. 이 메서드는 아무 것도 반환하지 않습니다. 이 클래스에는 많은 메서드 목록이 있으며 각각의 매개 변수 목록은 다양합니다.자바 반사에서 메서드에 여러 매개 변수를 전달하는 방법

예 : method1(String, String, int, boolean) method1(String, int, boolean) 마찬가지로 다른 순열과 조합이 있습니다. 그래서 어떻게 할 수 있습니까? 서로 다른 스위치 절을 사용하여 하드 코딩 작업을 시도했지만 유지 관리 작업은 실제 오버 헤드와 위험한 작업입니다. 우리는 동적으로이 작업을 동적으로 수행 할 수 있습니까? 예를 들어 파일에서 메서드 이름과 해당 매개 변수를 읽고 호출하십시오. 작은 코드 스 니펫이 유용 할 것입니다. TIA.

+0

개체 사용 [] {par1, par2, ..} – BlackJoker

+1

StackOverflow 서식으로 _twice_를 입력해야합니다. – Zyerah

+0

메서드 매개 변수의 순열 조합을 공유 할 수 있습니까? – Apurv

답변

6

안녕하세요. 위의 질문에 대한 해결책을 찾았습니다. 다음은 샘플 코드 스 니펫입니다.

package reflections; 

import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 

public class ReflectionTest { 
    public void method1(String str, int number) { 
     System.out.println(str + number); 
    } 

    public void method1(String str) { 
     System.out.println(str); 
    } 

    public void method1() { 
     System.out.println("helloworld"); 
    } 

    public static void main(String[] args) throws ClassNotFoundException, 
      InstantiationException, IllegalAccessException, 
      NoSuchMethodException, SecurityException, IllegalArgumentException, 
      InvocationTargetException { 
     // Step 1) Make an object array and store the parameters that you wish 
     // to pass it. 
     Object[] obj = {};// for method1() 
     // Object[] obj={"hello"}; for method1(String str) 
     // Object[] obj={"hello",1}; for method1(String str,int number) 
     // Step 2) Create a class array which will hold the signature of the 
     // method being called. 
     Class<?> params[] = new Class[obj.length]; 
     for (int i = 0; i < obj.length; i++) { 
      if (obj[i] instanceof Integer) { 
       params[i] = Integer.TYPE; 
      } else if (obj[i] instanceof String) { 
       params[i] = String.class; 
      } 
      // you can do additional checks for other data types if you want. 
     } 

     String methoName = "method1"; // methodname to be invoked 
     String className = "reflections.ReflectionTest";// Class name 
     Class<?> cls = Class.forName(className); 
     Object _instance = cls.newInstance(); 
     Method myMethod = cls.getDeclaredMethod(methoName, params); 
     myMethod.invoke(_instance, obj); 
    } 
} 

다른 사람들에게도 도움이되기를 바랍니다.

+1

참고 : 모든 줄 앞에 4 칸을 추가하여 코드 서식을 지정하십시오.) – Tobber

+0

@Bittenus 코드 서식을 지정하기 위해 Ctrl + K를 누르기 만하면됩니다. 코드 서식 지정 경고 메시지가 표시되어 코드의 형식을 지정합니다. 다음 번에는 어쨌든 내가 확실히 할거야. 감사합니다 –

+0

당신은 자바에게 다소 새로운 사람입니다. 나는 이것, 한 가지 질문으로 어려움을 겪었습니다. 왜 .class를 사용하지 않고 Integer.Type을 사용합니까? –

2
public class ReflectionSample 
{ 
    private Object mString = null; 
    private int mValue; 

    public ReflectionSample() 
    { 
    } 

    public ReflectionSample(int oValue) 
    { 
     mValue = oValue; 
    } 

    public ReflectionSample(String oString) 
    { 
     mString = oString; 
    } 

    public ReflectionSample(String oString, int oValue) 
    { 
     setValues(oString, oValue); 
    } 

    public void setValues(String oString, int oValue) 
    { 
     mString = oString; 
     mValue = oValue; 
    } 

    public String toString() 
    { 
     return ""+mString+":"+mValue; 
    } 

    public void run() 
    { 
     String oInput = "Teststring"; 
     Class<?> cls; 
     String clsname = "main.ReflectionSample"; 
     Object rs = null; // ReflectionSample 
     Object rsc = null; 

     System.out.println(this.getClass().getName()); 
     try 
     { 
      System.out.println(clsname); 
      cls = Class.forName(clsname); 
      if(cls == null) 
      { 
       System.err.println(clsname + " doesn't exist"); 
       return; 
      } 

      // Look for a constructor which has a single string 
      Constructor<?> ct = null; 
      Class<?>[] param_types = new Class<?>[1]; 
      Object[] arguments = new Object[1]; 

      param_types[0] = String.class; 

      // get the string constructor 
      ct = cls.getConstructor(param_types); 

      // We only have one object 
      arguments = new Object[1]; 
      arguments[0] = oInput; 

      // Instantiate the object with passed in argument. 
      rs = ct.newInstance(arguments); 
      System.out.println("String constructor sample: "+rs); 

      // Instantiate with default constructor 
      param_types = new Class<?>[0]; 
      arguments = new Object[0]; 
      ct = cls.getConstructor(param_types); 
      rs = ct.newInstance(arguments); 
      rsc = rs; // Keep it for later, to lazy to call it again 
      System.out.println("Default constructor sample: "+rs); 

      // Instantiate with string and int constructor 
      param_types = new Class<?>[2]; 
      arguments = new Object[2]; 

      // Must be in the same order as the params I think 
      param_types[0] = String.class; 
      param_types[1] = Integer.TYPE;  // <-- Its a primitive so use TYPE not Class 

      arguments[0] = oInput; 
      arguments[1] = new Integer(1); 

      ct = cls.getConstructor(param_types); 
      rs = ct.newInstance(arguments); 
      System.out.println("String plus int constructor sample: "+rs); 

      // call the setValues method 
      param_types[0] = String.class; 
      param_types[1] = Integer.TYPE;  // <-- Its a primitive so use TYPE not Class 

      arguments[0] = oInput; 
      arguments[1] = 1; 

      System.out.println("setValues invocation before: "+rsc); 
      Method m = cls.getMethod("setValues", param_types); 
      m.invoke(rsc, arguments); 
      System.out.println("setValues invocation after: "+rsc); 

      // An alternative method to pass the parameters 
      m = cls.getMethod("setValues", String.class, Integer.TYPE); 
      m.invoke(rsc, oInput+"x", 2); 
      System.out.println("setValues invocation after: "+rsc); 
     } 
     catch(Throwable e) 
     { 
      System.err.println(e.getLocalizedMessage()); 
     } 
    } 
} 

출력 :이 도움이

main.ReflectionSample 
main.ReflectionSample 
String constructor sample: Teststring:0 
Default constructor sample: null:0 
String plus int constructor sample: Teststring:1 
setValues invocation before: null:0 
setValues invocation after: Teststring:1 

희망.

이것이 Java의 새로운 기능인지는 모르겠지만 배열을 사용하는 대신 매개 변수와 함께 invoke를 사용하면 코드를 더 잘 읽을 수 있습니다. 대체 방법). 변수 개수가 필요하고 얼마나 많은 변수가 있는지 미리 알지 못하는 경우 배열을 할당하는 것은 소용이 없으며 역 호환 가능해야합니다.

관련 문제