2014-07-22 1 views
1

개체의 필드에 추가해야하는 XML 데이터가 있습니다 (모든 문자열 임). 객체에는 XML 데이터에 해당하는 필드와 메서드가 있습니다. 예를 들어 XML의 <RmkSk>123</RmkSk>setRmkSk(String)과 일치합니다. 그러나 때때로 int, long 또는 double과 같은 다른 유형을 예상하는 필드가 있습니다. 예를 들어 <Capacity>456</Capacity>setCapacity(double)과 일치합니다. 리플렉션을 사용하여 매개 변수 유형을 확인할 수 있지만 문자열을 적절한 데이터 유형으로 안정적으로 변환하는 방법을 모르겠습니다. 예를 들어문자열이있을 때 알려지지 않은 프리미티브를 예상하는 메서드를 어떻게 호출합니까?

for(Method m: o.getClass().getDeclaredMethods()) { 
    if(!m.getName().startsWith("set")) continue; 
    System.out.println(m.getName()); 
    for(Class c: m.getParameterTypes()) { 
     System.out.println(" " + c.getName()); 
    } 
} 

표시 :

setEqpSk 
    java.lang.String 
setCapacity 
    double 

java.lang.Double 있다면 그것은 쉽게 (상대적으로) Double.valueof 전화를 다시 반사를 사용하는 것입니다하지만 기본 유형이 아닌 개체 유형입니다. 첫 번째 문자를 대문자로 바꾸고 이것을 "java.lang."과 연결하는 것 이외의 다른 방법을 사용할 수있는 확실한 방법이 있습니까? 내가 잘못된 방향으로가는거야?

누군가가 외부의 도서관을 제안하기 전에, 나는 그들에 대해 듣는 것에 대해 개방적이지만, 이것은 제한된 정부 시스템에 있으며 승인 된 것과 같은 것을 얻는 것이 항상 쉬운 것은 아닙니다.

편집 : 명확히하기 위해, 나는 다음과 같은 피하려고 노력 해요 :

if (types[0] == String.class) { 
    m.invoke(o, value); 
} else if (types[0] == double.class || types[0] == Double.class) { 
    m.invoke(o, Double.parseDouble(value)); 
} else if (types[0] == int.class || types[0] == Integer.class) { 
    m.invoke(o, Integer.parseInt(value)); 
} else if (types[0] == //add checks for EVERY primitive type 

등 등

+0

XML 데이터를 수정할 수 있습니까? 가능한 경우 예상되는 데이터 형식을 추가 할 수 있습니다. 그렇지 않으면 두 번 데이터를 설정해야하는데, 처음에는'Double'을 사용하고 그 다음에'double'을 사용합니다 ... – MadProgrammer

+0

그것은 현재 문자열 "456"입니다. 나는 다른 사람이 제공 한 XML 데이터를 검색하고있다. – Derek

+0

매개 변수 유형이'double'이라면 프리미티브를 다루고 있고 그에 따라 변환 할 수 있어야한다는 것을 알아야한다. 만약 java.lang.Double이라면 새로운'Double' 객체를 생성해야한다. – MadProgrammer

답변

2

일반적으로, 오토 박싱과 함께, 당신은 double을 기대하는 방법에 대한 Double을 사용하여 멀리 얻을 수 있습니다, 예를 들어 ...

import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.util.HashMap; 
import java.util.Map; 

public class Test101 { 

    public static void main(String[] args) { 
     Map<String, String> values = new HashMap<>(3); 
     values.put("EqpSk", "123"); 
     values.put("Capacity", "456"); 
     values.put("Quanity", "987"); 

     Test101 o = new Test101(); 
     for (Method m : o.getClass().getDeclaredMethods()) { 
      String name = m.getName(); 
      if (name.startsWith("set")) { 
       name = name.substring(3); 
       if (values.containsKey(name)) { 
        try { 
         String value = values.get(name); 
         Class<?>[] types = m.getParameterTypes(); 
         if (types[0] == String.class) { 
          m.invoke(o, value); 
         } else if (types[0] == double.class || types[0] == Double.class) { 
          m.invoke(o, Double.parseDouble(value)); 
         } 
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException exp) { 
         exp.printStackTrace(); 
        } 
       } 
      } 
     } 
    } 

    public void setEqpSk(String value) { 
     System.out.println("EqpSk = " + value); 
    } 

    public void setCapacity(double value) { 
     System.out.println("Capacity = " + value); 
    } 

    public void setQuanity(Double value) { 
     System.out.println("Quanity = " + value); 
    } 

} 
+0

리플렉션을 통해 클래스와 메소드를 가져 오는 대신 실행시킬 수있는 각 프리미티브를 명시 적으로 나열하는 것이 가장 좋습니다. if/else를 참조하는 경우 – Derek

+0

내가 한 모든 것은 매개 변수의 클래스 유형을 결정하고 메서드에 전달한 값이 올바른 클래스 유형이라는 것을 보장합니다.같은 이름을 가진 두 개의 메소드가 있는데 하나는 원시 타입을 취하고 다른 하나는 객체 타입을 취하는 경우 문제가 발생할 수 있습니다.하지만 실제로는 충분한 정보가 없으므로이를 해결해야하는 유스 케이스입니다 . – MadProgrammer

+0

당신이 한 일을 정확히 이해합니다. 내 문제는 모든 기본 유형을 확인해야하기 때문에 5 개의 if if와 같이 끝날 것입니다. 매개 변수 유형을 얻고 valueof를 호출하여 일부 타이핑을 저장하고 코드를보다 깨끗하게 보이도록 마법을 쓸 수 있기를 바랬습니다. – Derek

관련 문제