2010-11-16 10 views

risposta

10

Poiché il codice GWT è tradotto in Javascript l'uso diretto dell'API di reflection non è supportato.

C'è un piccolo progetto GWT-Reflection, che consente di utilizzare la riflessione in GWT.

+2

Progetto interessante. Nota: prima di utilizzarlo, assicurarsi di poter accettare la licenza GPL. –

+0

Nope non può usarlo a causa della licenza. Comunque grazie per il puntatore –

+0

Nota i miei commenti qui sotto ... Ho rilasciato una implementazione completa autorizzata Apache della reflection API: https://github.com/WeTheInternet/xapi/tree/master/gwt/gwt-reflect – Ajax

12

È possibile utilizzare la funzionalità GWT Generators che consente di generare codice durante la fase di compilazione GWT.

il bean, che si desidera introspezione, può estendere una classe che ha un metodo definito come

public Object getProperty(String propertyName){} 

Chiamiamo questa classe IntrospectionBean.

Diciamo che si resta con il bean definito come:

public class MyBean extends IntrospectionBean { 
    private String prop1; 
    private String prop2; 
} 

Il generatore di GWT avranno accesso a tutti i campi della MyBean ed è in grado di generare il metodo getProperty(String propertyName) durante GWT compilazione tempo, dopo iterazione attraverso tutti i campi di MyBean.

La classe generata potrebbe assomigliare a questo:

public class MyBean extends IntrospectionBean { 
    private String prop1; 
    private String prop2; 

    public Object getProperty(String propertyName) { 
     if ("propr1".equals(propertyName)) { 
      return prop1; 
     } 
     if ("propr2".equals(propertyName)) { 
      return prop2; 
     } 

     return null; 
    } 
} 

Si potrebbe semplicemente utilizzare myBean.getProperty("prop1") al fine di recuperare una proprietà in base a suo nome in fase di esecuzione.

Here è possibile trovare un esempio di come implementare un generatore di GWT

+0

Grazie per quello. Esattamente ciò di cui avevo bisogno –

0

Se si desidera utilizzare la riflessione per acquisire un campo privato, prendere in considerazione l'utilizzo di jsni (interfaccia nativa javascript); non ha alcuna nozione di pubblico o privato, in modo da poter semplicemente prendere tutto quello che vuoi in questo modo:

package com.foo; 

class SomeClass { 
    private String someField; 
    private static int someInt; 
} 

//accessors: 
native String ripField(SomeClass from) 
/*-{ 
    return [email protected]::someField; 
}-*/; 
native int ripInt() 
/*-{ 
    return @com.foo.SomeClass::someInt; 
}-*/; 

Inoltre, io sono in mezzo a finire emulazione per java.lang.ClassnewInstance/riflessione.

Postò di nuovo qui con un collegamento in circa due giorni se ti piacerebbe giocare con esso.

Si richiede che si passa una classe attraverso un metodo che ho percorso ad un generatore personalizzato (come GWT.create, eccetto che restituisce un java.lang.Class generato con il campo e il metodo di accesso che solo puntano a JSNI metodi/campi. :)

+0

Mi sono emozionato quando ho visto questa risposta per la prima volta, ma a un'ulteriore ispezione ha gravi carenze, come dover conoscere in anticipo il tipo di classe (non può essere usato in generici) e dover avere un metodo 'rip' per campo, anziché fornire il nome del campo. Potrebbe anche avere un getter javabean normale. – NickJ

+0

... a meno che tu non controlli il codice a cui devi accedere, e preferiresti non conservare copie del codice di qualcun altro per ottenere l'accesso ai membri privati. Inoltre, in che modo i generici potrebbero aiutare con la riflessione? I generici lavorano via cancellazione, e jsni lo confronta. – Ajax

+0

Solo un altro pensiero, puoi generare tutto questo. Mantengo una build pubblica di GWT, net.wetheinter: gwt - *: 2.7.0 che ha la riflessione implementata tramite l'iniezione del metodo magico. È un fork di Gwt perché ho dovuto sequestrare il meccanismo per GWT.create per trovare e sostituire il riflesso fatto tramite letterali di classe/stringa con codice generato simile all'esempio precedente. C'era una versione che permetteva di migliorare una classe con GWT.create per evitare di dover hackerare il compilatore, ma non c'era abbastanza interesse per mantenerlo (generò anche tonnellate di codice). – Ajax

1

Ho reso pubblica la mia libreria gwt-reflection.

https://github.com/WeTheInternet/xapi/tree/master/gwt/gwt-reflect https://github.com/WeTheInternet/gwt-sandbox/tree/xapi-gwt/user/src/com/google/gwt/reflect

A causa di problemi di classpath con il tentativo di rendere Gwt prendere la mia versione di Class.java sulla propria, alla fine ho appena biforcuta Gwt, ha aggiunto Java 8 e il supporto di riflessione, e ora mantenere netta .wetheinter: GWT - *: 2.7.0 che ha questo supporto cotto a (I rilascerà un 2.8 po 'di tempo dopo Gwt 2.8 va in diretta)

supporta tre livelli di riflessione:

monolitici:

// Embeds all data needed to perform reflection into hidden fields of class 
GwtReflect.magicClass(SomeClass.class); 
SomeClass.getField(fieldName).set(null, 1); 

Leggero:

// Allows direct reflection, provided ALL parameters are literals, or traced to literals 
SomeClass.class.getField("FIELD_NAME").set(null, 1); 

mosca:

// Skips creating a Field object entirely, and just invokes the accessor you want 
// All params must be literals here as well 
GwtReflect.set(SomeClass.class, "FIELD_NAME", null, 1); 

Questi esempi funzionano anche per i metodi e Costruttori. C'è un supporto di base per le annotazioni e altre ancora in futuro.

Problemi correlati