2012-04-04 2 views
0

정적 블록에서 hashmap을 초기화 한 클래스가 있습니다. 열쇠를 건네면서 나는 수업 인 가치를 얻었습니다. 이 클래스의 객체를 생성하기 위해서. 생성자 클래스를 사용하여 생성자를 가져오고 인수를 전달하고 객체를 생성했습니다.getConstructor 메서드를 선택하는 조건

해시 맵에는 두 개의 클래스가 있습니다. EchoExpression 객체를 만들려면 두 개의 인수를 전달해야하며 OutExpression 클래스에는 하나의 인수 (String) 만 전달해야합니다.

질문 : 내가 얻을 수있는 생성자 실행하고 구현하는 데 필요한 키에 의해 반환 된 클래스를 기반으로

, 여부를 하나 개의 인수 또는 두 개의 인수를 사용하여 생성자입니다.

public class ExampleFactory { 

    private static HashMap<String,Class<?>> hmap = new HashMap<String,Class<?>>(); 

    static 
    {     
     hmap.put("echo", EchoExpression.class);   
     hmap.put("Out", OutExpression.class);      
    } 

    public void getExpo(String key,String expression) 
    { 
    Class aClass =map.get(key); 

    //Constructor implementation for OutExpression where only one argument string is passed 

    Constructor constructor = aClass.getConstructor(new Class[]{String.class}); 

    Object object= constructor.newInstance(expression); 

    //constructor for passing two arguments string for EchoExpression 

    Constructor constructor = aClass.getConstructor(new Class[]{String.class,Class.class}); 

    Object object= constructor.newInstance(expression, Boolean.class); 


    return null;   
    }     
} 

if else를 사용하지 않고 구현할 값 (클래스) 중에서 선택하는 방법은 무엇입니까?

+0

어떤 언어입니까? – EdChum

답변

1

은 열거를 사용하고 켭니다. 다음은 예제의 반사 또는 구문에 너무 깊이 관여하지 않고 실행 가능한 스텁입니다.

package com.trip.test; 

import java.util.HashMap; 
import java.util.Map; 

public class ExampleFactory { 

    private static Map<String, Class<?>> hmap = new HashMap<String, Class<?>>(); 

    static { 
     hmap.put("echo", EchoExpression.class); 
     hmap.put("Out", OutExpression.class); 
    } 

    public static void getExpo(String key, String expression) { 

     Class aClass = hmap.get(key); 

     ClassMappingEnum myType = ClassMappingEnum.getClassMappingEnum(aClass); 

     switch (myType) { 
     case ECHO_EXPRESSION:{ 
      System.out.println(aClass.getName()); 
      // do something 
      break; 
     } 
     case OUT_EXPRESSION:{ 
      System.out.println(aClass.getName()); 
      // do something 
      break;   
     } 
     case UNKNOWN: 
     default: 
      System.out.println("Bummer: " + aClass.getName());   
     } 

    } 

    public static void main(String[] args) { 
     getExpo("echo", "B"); 
     getExpo("Out", "B"); 
    } 
} 

enum ClassMappingEnum { 
    ECHO_EXPRESSION(EchoExpression.class), OUT_EXPRESSION(OutExpression.class), UNKNOWN(null); 

    private Class typeDes; 

    private ClassMappingEnum(Class typeDes) { 
     this.typeDes = typeDes; 
    } 

    public static ClassMappingEnum getClassMappingEnum(Class compare) { 
     for (ClassMappingEnum cme : ClassMappingEnum.values()) { 
      if (cme.typeDes.equals(compare)) { 
       return cme; 
      } 
     } 
     return UNKNOWN; 
    } 


} 

class EchoExpression<T> { 
    private String someString; 
    private Class<T> someClass; 
    public EchoExpression(String someString, Class<T> someClass) { 
     super(); 
     this.someString = someString; 
     this.someClass = someClass; 
    } 
    public String getSomeString() { 
     return someString; 
    } 
    public void setSomeString(String someString) { 
     this.someString = someString; 
    } 
    public Class<T> getSomeClass() { 
     return someClass; 
    } 
    public void setSomeClass(Class<T> someClass) { 
     this.someClass = someClass; 
    } 


} 

class OutExpression { 
    private String someString; 

    public OutExpression(String someString) { 
     super(); 
     this.someString = someString; 
    } 

    public String getSomeString() { 
     return someString; 
    } 

    public void setSomeString(String someString) { 
     this.someString = someString; 
    } 

} 
0

두 생성자가 같은 서명을 (같은 순서로 인수 같은 수의/유형을 받아)가 있도록 클래스를 수정할 수 있다면, 당신은 두 클래스에 대한

Constructor constructor = aClass.getConstructor(new Class[]{String.class,Class.class}); 
Object object= constructor.newInstance(expression, Boolean.class); 

을 할 수 있습니다. 다음의 가능한 방법입니다 : 물론

은 지금 추가 매개 변수를 필요로하지 않는 클래스는, (가) 전달 된이 변화

UPDATE 후 이전에 사용하지 않은 한 무시해야한다는 것을 의미 공장 클래스를 사용하여 아이디어를 구현 :

public interface ObjectFactory 
{ 
    Object create(String expr, Class cls); 
} 

public class EchoExpressionFactory implements ObjectFactory 
{ 
    public EchoExpression create(String expr, Class cls) 
    { 
    return new EchoExpression(expr, cls); 
    } 
} 

public class OutExpressionFactory implements ObjectFactory 
{ 
    public OutExpression create(String expr, Class cls) 
    { 
    return new OutExpression(expr); 
    } 
} 

public class ExampleFactory { 

    private static HashMap<String,ObjectFactory> hmap = new HashMap<String,ObjectFactory>(); 

    static 
    {      
     hmap.put("echo", new EchoExpressionFactory());   
     hmap.put("Out", new OutExpressionFactory());       
    } 

    public void getExpo(String key,String expression) 
    { 
    ObjectFactory factory = map.get(key); 

    //Constructor implementation for Expression 
    Object object = factory.create(expression); 

    Object object= constructor.newInstance(expression, Boolean.class); 

    return; 
    }     
} 
+0

jar 파일 클래스 이후에 클래스를 수정할 수 없습니다. – Jessie

+0

그러면 가장 좋은 방법은'if'와'instanceof'입니다. 만약 당신이'if'를 피하고자한다면, 원하는 실제 객체를 생성하고 필요한 모든 매개 변수를 가진 공통의 create 메소드를 가진 팩토리 클래스를 사용하거나 저장할 수 있습니다. 위에서 언급 한 것들을 근본적으로 끝낼 것입니다. 공장 클래스 대신 – Attila

+0

또한 [이전 질문] (http://stackoverflow.com/questions/10018565/how-to-access-object-inside-static-block/)에서 답변 중 하나를 수락하는 것이 좋습니다. 당신은 제안 된 것을 사용하여 끝났습니까? – Attila