2014-11-13 5 views
2

클래스 이름과 메서드 이름이 String 매개 변수로 호출자에게 전달 될 때 특정 메서드를 실행하는 프로그램을 만들려고합니다. 아래의 코드를 고려하십시오.클래스 이름과 메서드 이름을 매개 변수로 전달하여 Java 메서드를 실행하십시오.

runTheMehod("CarBean","getColor"); 

이 runTheMethod의 구현은 다음과 같이 될 것이다 :

public runTheMethod(String className, String methodName){ 
try { 
      Object carObj = Class.forName(className).newInstance(); 
      //What to do now??? 
     } catch (InstantiationException | IllegalAccessException 
       | ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 
} 

내가 할 수있는

public class CarBean { 

    private String brand; 
    private String color; 

    /** 
    * @return the brand 
    */ 
    public String getBrand() { 
     return brand; 
    } 

    /** 
    * @param the brand to set 
    */ 
    public void setBrand(String brand) { 
     this.brand= brand; 
    } 

    /** 
    * @return the color 
    */ 
    public String getColor() { 
     return color; 
    } 

    /** 
    * @param the color to set 
    */ 
    public void setColor(String color) { 
     this.color= color; 
    } 

} 

가 지금은 아래와 같은 방법을 통해이 작업을 실행하려면 : 나는 클래스 CarBean이 클래스 이름을 사용하여 객체를 가져옵니다. 이제 CarBean 객체에 캐스팅해야하고 메소드를 실행할 수 있습니다. 따라서 런타임시 클래스 이름으로 캐스팅하는 방법이 각 호출마다 다를지 궁금합니다. 또한 호출하기 전에 클래스에 특정 메서드가 있는지 여부를 확인할 수 있습니까?

문제에 대한 제안 사항에 감사드립니다. 또한, 나는 이것을하기위한 더 나은 접근법이 있는지를 아는 모든 귀입니다.

+2

https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getMethod % 28java.lang.String, % 20java.lang.Class ... % 29, https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Method.html#invoke%28java .lang.Object, % 20java.lang.Object ... % 29 –

+1

그 유형의 새로운 객체를 인스턴스화 하시겠습니까? 예 : 'runTheMethod (Object instance, String methodName)'도 작동 할 것이고 그 타입의 객체를 만들기 위해 당신에게 맡길 것입니다. – zapl

+0

@zapl 예 문자열 형식의 클래스 이름을 얻고 있습니다. –

답변

3

지금해야 할 일 ???

이제이처럼 carObj에 메소드를 호출 할 수

Method method = carObj.getClass().getMethod(methodName); 
method.invoke(carObj); 

항목 :

Method.invoke

+0

입력 해 주셔서 감사합니다. 이것은 잘 작동합니다. 또 하나의 질문이 있습니다. 구현을 확장하려면 반환 값을 입력으로 전달하고 비교 한 다음 CarBean (또는 모든 클래스를 전달하는)의 hashCode를 구현하거나 구현해야합니다. 그것에 대한 어떤 제안? - public runTheMethod (String className, String methodName, Object returnValue) –

+0

네, 일부 캐스트를 수행해야합니다. 또는 ... ('returnValue'가 전달 된 값과 실제 반환 된 값)을'Object's와 비교하여 그들의 equals 메소드 (단 하나 또는 둘 다'null' 인 경우'null'을주의하십시오). –

1

을 당신이하려고하는 모든 이름으로 메소드를 호출하는 경우 , 당신은 그것을 무엇이든 던질 필요가 없습니다. 추가 반사음이있는 Object을 사용하면 충분합니다.

는 같이 Class.getDeclaredMethod() 참조 : 우리는 상관하지 않습니다

Object carObj = ...; 
Method method = carObj.getClass().getDeclaredMethod(methodName, ...); 
Object retObj = method.invoke(carObj, ...); 

주 유형 carObj 실제로, 당신은 당신이 항상 instanceof 또는 Class.isAssignableFrom 또는 Class.isInstance를 사용할 수 확인하기를 원한다면하지만.

그러나 이상하게 들리지만 새로운 객체를 인스턴스화하여 한 번에 그 메소드 중 하나를 호출합니다. 그 물체는 당신의 runTheMethod이 돌아 오면 사라집니다.


그건 그렇고, 당신은 단지 콩 속성을 얻고 설정하려고하는 것처럼 보입니다. 대신 Apache Commons BeanUtils를 보라 할 수 있습니다, 다음 예는 간단하게 :

CarBean bean = ...; 
String color = (String)PropertyUtils.getSimpleProperty(bean, "color"); // calls getter. 
+0

입력 해 주셔서 감사합니다. CarBean을 예로 들었지만 자바 빈에 국한되지 않습니다. 액션/서비스/DAO 레이어에서와 같이 다른 방법으로이 작업을 실행해야 할 수도 있습니다. –

+1

'getDeclaredMethod'와'getMethod'를주의 깊게 살펴보면 먼저이 클래스에 정의 된 메소드 (re)를 반환합니다. 상속 된 메소드는 발견되지 않으며, 후자의 public 메소드는 http://ideone.com/veKNyU입니다. – zapl

관련 문제