Typsichere Reflections in Java mit Manifold

Nach einigen bereits veröffentlichen Artikeln in der Serie zu Manifold soll es in diesem Teil darum gehen, wie man die eigenen Reflections in Java mit Manifold typsicher machen kann. Zuvor hatten wir bereits beschrieben, wie man recht einfach JSON-Schnittstellen im Programmcode verwenden kann, wie man fremde Klassen um Methoden erweitern kann und wie man eine beliebige Klasse von einem eigenen Interface erben lassen kann, sofern sie denn die entsprechenden Methoden mitbringt.

Auch für die Typisierung von Reflections haben sich die Macher von Manifold etwas ausgedacht. Damit kann man gleich zur Compilezeit sehen, ob alles korrekt typisiert ist und bekommt nicht erst zur Laufzeit eine Exception.

Zu Demonstrationszwecken ändern wir unser Customer-Objekt aus dem letzten Artikel ein wenig ab und machen es zum NewCustomer:

public class NewCustomer {
    private long id;

    private long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }
}

Die getId()-Methode ist nun private statt public. Der Java-Code, um nun auf diese private Methode zuzugreifen, ist schon etwas länger und komplexer und involviert einen Cast von java.lang.Object auf long, sowie die Verwendung der Reflection API:

NewCustomer nc = new NewCustomer();
nc.setId(2);
try {
   Method m = nc.getClass().getDeclaredMethod("getId", null);
   m.setAccessible(true);
   long id = (long)m.invoke(nc);
   System.out.println(id);
} catch (NoSuchMethodException | IllegalAccessException | 
      InvocationTargetException e) {
   e.printStackTrace();
 }

Viel einfacher und dazu typsicher mit Manifold:

@Jailbreak NewCustomer nc = new NewCustomer();
nc.setId(2);
long id = nc.getId();
System.out.println(id);

Hier wird die Annotation @Jailbreak vor das Reflection-Objekt NewCustomer gesetzt. Dadurch werden sämtliche private Methoden und Felder der NewCustomer-Klasse für das Objekt nc freigegeben. Damit fällt auch der Cast, sowie das Exception-Handling weg. Die Lesbarkeit des Codes steigt merklich an.

Natürlich wird auch hier im Hintergrund fleißig “echter” Reflection-API-Code generiert, nur sieht der Entwickler davon nichts mehr. Außerdem kann Manifold sicherstellen, dass der generierte Code typsicher ist.

Damit lässt sich die Lesbarkeit des Codes stark erhöhen und das Fehlerrisiko sinkt. So sieht man etwa gleich zur Compilezeit, ob ein Objekt etwa durch einen Tippfehler bedingt die via getDeclaredMethod() angefragte Methode gar nicht besitzt.

Es versteht sich von selbst, dass dieses Feature nur mit sehr viel Bedacht eingesetzt werden sollte. Insbesondere sollte man damit natürlich nicht allzu leichtsinnig die Datenkapselung von Klassen umgehen.

Short URL for this post: https://wp.me/p4nxik-3kO
Steffen Jacobs

About Steffen Jacobs

Java Consultant & Developer at Orientation in Objects GmbH. Follow me on Twitter and find me on LinkedIn and Xing. Some of the source code associated with the blog articles can be found on GitHub.
This entry was posted in Java and Quality and tagged , , , . Bookmark the permalink.

Leave a Reply