Domanda

Dati i seguenti tre classi come posso utilizzare la reflection per chiamare la funzione di inizializzazione per la classe genitore (i) e poi la sottoclasse:

public class Test {

    public static void main(String[] args) {
        ExtendedElement ee = new ExtendedElement();
        initialize(ee);
     }

    public static void initialize(Element element) {
        System.out.println(element.getClass());
        initialize(element.getClass());
    }

    public static void initialize(Class clazz) {
        System.out.println(clazz.getClass());
    }
}

public class Element {
    protected String value;
    public String getValue() { return value; }
    public void setValue(String value) { this.value = value; }
}

public class ExtendedElement extends Element {
    protected String extendedValue;
    public void setExtendedValue(String extendedValue) {
        this.extendedValue = extendedValue;
    }
    public String getExtendedValue() { return extendedValue; }
}

Non sono del tutto sicuro su come paramertize la funzione di inizializzazione nella classe di test, come parametro Clazz è un tipo grezzo.

Quello che in sostanza necessità è quella di richiamare inizializzare la gerarchia delle classi se quello che mi passa in inizializzazione è di una sottoclasse di elemento.

Qualcosa di simile a quanto segue:

public void initialize(Class clazz) { 
    if (Element.class.isInstance(clazz.getClass().getSuperclass()) {
         initialize(clazz.getClass().getSuperclass());
    }
    //Work to call initialize function 
}

Modifica 1:

Non Posso parametrizzare la funzione pseudo sopra in modo diverso per mantenere il tipo di oggetto e quindi chiamare la funzione che ho bisogno di?

Quello che sto cercando di fare è evitare di dover avere lo stesso metodo ignorato per ciascuna delle mie classi e consentire ad alcuni di successione per il mio Selenio 2 Page Objects. Quello che devo fare è essere in grado di è l'introspezione del superclasse (ES) della mia auto e inizializzare ogni mio WebElement fields prima di eseguire test su questi campi.

Queste sono essere iniettato con la primavera, e ad ulteriori cose complicare sto permettendo test per essere scritti utilizzando il linguaggio Espressione primavera. Sono lazy loading miei fagioli, e utilizzando l'interfaccia InitializingBean per tentare di inizializzare i miei WebElements prima del loro utilizzo a NPE evitare.

ho dovuto avvolgere i WebElements con un oggetto personalizzato in modo che potessi iniettare le strategie di localizzazione che utilizzano molla (Abbiamo riutilizzare un sacco di pezzi, ma hanno diverse IDS / nomi delle classi che dipendono in cui vengono utilizzati nella domanda; questo è stato fatto prima di me arrivare qui e non sarà cambiata in questo momento, nonostante i miei argomenti per la coerenza). Per esempio abbiamo un widget data che ha diverse granularità, a volte abbiamo bisogno solo di un mese, a volte del mese e dell'anno, ecc ... Sarebbe bello se potessi usare una classe astratta e rompere questi punti in comune fino al loro minimo comune denominatore e si estendono da lì. Per fare questo ho bisogno di essere in grado di effettuare le seguenti operazioni nella mia classe di base:

public abstract class PageObject implements InitializingBean {
    ...
    public void afterPropertiesSet() {
        //Pass in concrete impl we are working with - this allows me to initialize properly
        initializeWebElements(this.getClass());
    }
    ...
    public void initializeWebElements(Class clazz) {
        //This does not grab inherited fields, which also need to be initialized
        for (Field field : clazz.getDeclaredFields()) {
            if (WidgetElement.class == field.getType()) {
                Method getWidgetElement = clazz.getDeclaredMethod("get" +
                    StringUtils.capitalize(field.getName()), new Class [] {});
                    WidgetElement element = 
                      (WidgetElement) getWidgetElement.invoke(this, new Object [] {});
                    element.initElement();
    }
}
È stato utile?

Soluzione 3

Ecco la mia soluzione temporanea, lasciando aperta la questione di raccogliere spera alcune risposte migliori anche se per il mio caso d'uso.

public abstract class PageObject implements InitializingBean {
...
public void afterPropertiesSet() {
    Class clazz = this.getClass();
    do {
        initializeElements(clazz);
        clazz = clazz.getSuperclass();
    } while (clazz != null);
}

Altri suggerimenti

Non è possibile chiamare un metodo ad un livello specifico. L'unica cosa è che si ha accesso alla parola super all'interno della classe stessa.

Per fare questo lavoro, si desidera chiamare super.initialize() dall'interno di ogni sottoclasse, allora lo chiamano semplicemente attraverso la riflessione.

Non si tratta di C ++, dove possono chiamare un metodo specifico ad un livello specifico della gerarchia di ereditarietà.

Non sono del tutto sicuro su come parametrizzare la funzione di inizializzazione nella classe di test, come parametro Clazz è un tipo grezzo.

Niente nel tuo esempio richiede di utilizzare il parametro di tipo generico, in modo dichiareremo come Class<?>.

Non capisco che cosa i vostri metodi di inizializzazione sono veramente cercando di fare, ma ci sono una serie di problemi:

Sembra che tu abbia un metodo initialize che prende un'istanza (di Element) come argomento, e un altro che prende un oggetto Class come argomento. Questo è davvero mele e arance roba ... ed hai bisogno di spiegare che cosa si sta cercando di fare.

Il tuo tentativo di dare un contenuto al metodo contiene questo:

Element.class.isInstance(clazz.getClass().getSuperclass())

Questo non potrà mai valutare al vero, perché si sta chiedendo se qualche oggetto Class è un istanza della classe Element. (Per di più, clazz.getClass().getSuperclass() in realtà sta per essere lo stesso java.lang.Object.class. La classe di un oggetto Class è java.lang.Class e la sua superclasse è java.lang.Object).

Ma io non riesco a capire quello che dovrebbe essere, perché non descrivere in modo chiaro ciò che si sta cercando di ottenere.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top