2012-04-04 4 views
0

Ich habe eine Klasse, in der ich hashmap im statischen Block initialisiert habe. Übergeben Sie den Schlüssel, ich habe den Wert, der eine Klasse ist, abgerufen. Um ein Objekt für diese Klasse zu erstellen. Ich habe die Konstruktorklasse verwendet, um den Konstruktor abzurufen und Argumente und erstelltes Objekt zu übergeben.Bedingung zu wählen, die getConstructor Methode

Ich habe zwei Klassen in hashmap. Um ein Objekt für EchoExpression zu erstellen, muss ich zwei Argumente übergeben und für die OutExpression-Klasse muss ich nur ein Argument übergeben (String).

Frage:

basierend auf der Klasse des Schlüssel, den ich ausführen muß wieder in der Konstruktor zu bekommen und zu implementieren, ob der Konstruktor mit einem Argumente oder zwei Argumente.

Wie wählt man aus dem Wert (Klasse) welche Klasse zu implementieren ohne zu verwenden, wenn sonst?

+0

Welche Sprache ist das? – EdChum

Antwort

1

Verwenden Sie ein Enum und schalten Sie es ein. Hier ist eine ausführbare Stub, ohne zu tief in die Reflexion oder die Syntax Ihres Beispiels zu gehen:

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

Wenn Sie die Klassen ändern können, so dass beide Konstruktor die gleiche Signatur hat (übernimmt die gleiche Anzahl/Art der Argumente in der gleichen Reihenfolge), könnten Sie tun

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

für beide Klassen.

Das bedeutet natürlich, dass die Klasse, die gerade jetzt, den übergebenen in einem müssen nicht ignorieren die zusätzlichen Parameter müssen nicht vor nach dem Wechsel

UPDATE wurde mit: ist eine mögliche Art und Weise hier von Implementierung der Idee mit Factory-Klassen:

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

Ich kann die Klassen nicht ändern, da es eine JAR-Dateiklasse ist – Jessie

+0

Dann ist Ihre beste Wette mit 'if' und' instanceof'. Wenn Sie 'if' wirklich vermeiden möchten, können Sie Factory-Klassen verwenden/speichern, die die gewünschten Objekte erstellen, und eine gemeinsame Erstellungsmethode mit allen erforderlichen Parametern haben - Sie würden im Wesentlichen das tun, was ich oben vorgeschlagen habe, aber mit die Fabrikklassen stattdessen – Attila

+0

Auch, wie wäre es mit einer der Antworten auf [Ihre vorherige Frage] (http://stackoverflow.com/questions/10018565/how-to-access-object-inside-static-block/), seit Sie haben am Ende verwendet, was vorgeschlagen wurde? – Attila