2013-06-06 15 views
5

Ich habe verwendet Java seit geraumer Zeit jetzt, aber manche Dinge sind noch nicht ganz klar zu mir, vor allem, wenn es um Generika kommt ...Java Generics - Klasse <?> Konstruktorargument Ausgabe

Hier ist das Ding: ich habe diese Search Klasse, die ich verwende (see here for details), die wie folgt aufgebaut ist:

public Search(Class<?> searchClass) {...} 

Weiter mehr, ich habe eine parametrisierte generischen Wrapper um diese wie folgt:

public class HibernateSearch<E> extends Search implements Serializable { 
    public HibernateSearch(Class<E> entityClass) { 
     super(entityClass); 
    } 
    // ... omitted for brevity 
} 

Nun, was ich brauche, ist das Folgende: Ich möchte parametrisierte Klasse erstellen, die diese Klasse als ihr Feld enthält, z.

Ich denke, dass das Problem, das ich gegenüberstelle, aus dem gegebenen Beispiel offensichtlich ist.
Kann jemand beraten, was hier getan werden kann, oder eine Alternative?

Antwort

5

Der einfachste Weg, um die Verantwortung auf, wer eigentlich instanciates und verwendet Instanzen von BaseSelectorComposer, also passieren würde

class IntSelectorComposer extends BaseSelectorComposer<Integer> { 
    ... 
} 

dh wie für Klassen Basisklasse, die als „bind“ die Typparameter, gibt Möglichkeiten, um obtain the type information via reflection sind (obwohl das unglaublich hässlich ist, da dies in der API IMHO nicht wirklich gut unterstützt wird).

1

Im Allgemeinen ist dies ein schwer zu umgehendes Szenario. Aus dem .NET-Hintergrund kommend habe ich persönlich sehr wenige Fälle gefunden, in denen ich das ausarbeiten konnte, da Java keine statische generische Typauflösung unterstützt (wie zB in .NET, wo Sie typeof(T) verwenden können).

Um dies zu umgehen empfehle ich, dass Sie einen Weg finden, entweder die Klasse extern oder eine Instanz dieser Klasse zu bekommen. Eine mögliche Lösung wäre, die doAfterCompose Verfahren in einer der folgenden Weisen zu ändern:

@Override 
public void doAfterCompose(Window comp, Class<?> entityClass) throws Exception { 
    super.doAfterCompose(comp); 
    this.searchObject = 
     new HibernateSearchObject<T>(entityClass); 
    ... 
} 

-oder

@Override 
public void doAfterCompose(Window comp, SomeEntity entity) throws Exception { 
    super.doAfterCompose(comp); 
    this.searchObject = 
     new HibernateSearchObject<T>(entity.getClass()); 
    ... 
} 

Wenn Sie die Methode Signatur nicht ändern können (ich sehe es ist eine Überschreibung), Versuchen Sie, ein Mitglied der Klasse BaseSelectorComposer<T> zu verwenden, das die gewünschte Class<?> Instanz enthält.

public class BaseSelectorComposer<T> extends SelectorComposer<Window> { 

    private HibernateSearch<T> searchObject; 
    private final Class<T> theType; 

    public BaseSelectorComposer(Class<T> token) { 
     theType = token; 
    } 

    ... 
    @Override 
    public void doAfterCompose(Window comp) throws Exception { 
     super.doAfterCompose(comp); 
     this.searchObject = new HibernateSearchObject<T>(theType); 
     ... 
    } 
    ... 
} 

Wenn Ihr BaseSelectorComposer eine abstrakte Unterklasse ist, die immer nur wie verwendet wird:

public class BaseSelectorComposer<T> extends SelectorComposer<Window> { 
    private Class<?> entityClass; 

    public BaseSelectorComposer<T>(Class<?> entityClasss) { 
     this.entityClass = entityClass; 
    } 

    .... 
    @Override 
    public void doAfterCompose(Window comp) throws Exception { 
     super.doAfterCompose(comp); 
     this.searchObject = 
      new HibernateSearchObject<T>(this.entityClass); 
     ... 
    } 
} 
Verwandte Themen