2010-11-16 5 views

Antwort

10

Da der GWT-Code in Javascript übersetzt wird, wird die direkte Verwendung der Reflection-API nicht unterstützt.

Es gibt ein kleines Projekt GWT-Reflection, das erlaubt, Reflexion in GWT zu verwenden.

+2

Interessantes Projekt. Hinweis: Stellen Sie vor der Verwendung sicher, dass Sie die GPL-Lizenz akzeptieren können. –

+0

Nö kann das wegen der Lizenz nicht benutzen. Wie auch immer, danke für den Zeiger –

+0

Beachten Sie meine Kommentare unten ... Ich habe eine Apache lizenzierte vollständige Implementierung der Reflektion API veröffentlicht: https://github.com/WeTheInternet/xapi/tree/master/gwt/gwt-reflect – Ajax

12

Sie können die GWT Generators-Funktionalität verwenden, mit der Sie während der GWT-Kompilierungsphase Code generieren können.

Ihre Bohne, dass Sie introspect möchten, können Sie eine Klasse erweitern, die eine Methode als

public Object getProperty(String propertyName){} 

Lassen Sie uns diese Klasse nennen IntrospectionBean definiert hat.

Lassen Sie uns sagen, dass Sie dann Ihre Bohne wie definiert haben:

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

Der GWT-Generator Zugriff auf alle Bereiche der MyBean haben und es kann die getProperty(String propertyName) Methode erzeugen während GWT Zeit kompilieren, nachdem alle Felder Iterieren durch von MyBean.

Die generierte Klasse könnte wie folgt aussehen:

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; 
    } 
} 

Sie könnten dann einfach myBean.getProperty("prop1") verwenden, um eine Eigenschaft, basierend auf seinen Namen zur Laufzeit abzurufen.

Here Sie ein Beispiel, wie finden Sie einen gwt Generator implementieren

+0

Danke dafür. Genau das, was ich brauchte –

0

Wenn Sie nur Reflektionen verwenden möchten, um ein privates Feld zu erfassen, sollten Sie stattdessen jsni (javascript native interface) verwenden. es hat keine Ahnung von privat oder öffentlich, so können Sie einfach alles, was Sie wie so wollen greifen:

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; 
}-*/; 

Auch ich in der Mitte für java.lang.ClassnewInstance/Reflexion von Finishing-Emulation bin.

Ich poste zurück hier mit einem Link in ungefähr zwei Tagen, wenn Sie damit spielen möchten.

Es erfordert, dass Sie eine Klasse durch eine Methode übergeben, die ich den Weg zu einem benutzerdefinierten Generator (wie GWT.create, außer es ein generiertes java.lang.Class mit Feld und Methode Accessoren zurückgibt, die nur Methoden/Felder JSNI zeigen. :)

+0

Ich wurde ganz aufgeregt, als ich diese Antwort zum ersten Mal sah, aber bei genauerer Betrachtung hat sie schwerwiegende Mängel, wie zum Beispiel die Klassenart im Voraus kennen zu müssen (kann nicht in Generika verwendet werden) und eine "Rip" -Methode haben pro Feld, anstatt den Feldnamen anzugeben. Könnte genauso gut einen normalen Javabean Getter haben. – NickJ

+0

... es sei denn, Sie kontrollieren nicht den Code, auf den Sie zugreifen müssen, und behalten lieber keine Kopien von Code anderer Personen bei, um Zugriff auf die privaten Mitglieder zu erhalten. Auch, wie würden Generika überhaupt mit der Reflexion helfen? Generics funktionieren durch Löschen, und jsni passt darauf. – Ajax

+0

Nur ein weiterer Gedanke, können Sie all dies generieren. Ich behalte einen öffentlichen Build von GWT, net.wetheinter: gwt - *: 2.7.0, der über eine magische Methodeninjektion implementiert wurde. Es ist eine Abzweigung von Gwt, weil ich den Mechanismus für GWT.create entführen musste, um Reflektionen zu finden und zu ersetzen, die über Klassen-/String-Literale mit generiertem Code, der wie im obigen Beispiel aussieht, durchgeführt werden. Früher gab es eine Version, mit der man eine Klasse mit GWT.create erweitern konnte, um nicht in den Compiler eindringen zu müssen, aber es gab nicht genug Interesse, um das aufrechtzuerhalten (es erzeugte auch Tonnen von Code). – Ajax

1

Ich habe meine gwt-reflection-Bibliothek veröffentlicht.

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

Aufgrund Classpath Probleme mit dem Versuch, GWT holt meine Version von Class.java über seine eigenen, ich schließlich nur gegabelt GWT, hinzugefügt Java 8 und Reflexion Unterstützung, und jetzt hält net zu machen .wetheinter: gwt - *: 2.7.0, die diese Unterstützung in (I ein 2,8 wird Release einige Zeit nach GWT 2.8 live geht) gebacken hat

Es unterstützt drei Ebenen der Reflexion:

Monolithic:

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

Leicht:

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

Flyweight:

// 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); 

Diese Beispiele auch für Methoden und Konstruktoren arbeiten. Es gibt grundlegende Unterstützung für Anmerkungen und weitere in der Zukunft.

Verwandte Themen