Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Implementing a default toString method with AspectJ

DZone's Guide to

Implementing a default toString method with AspectJ

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

Overview

AspectJ has some real powerful usages. One is to inject a method inside a set of classes. Most of the time, I implement the toString() method using the useful reflectionToString method of Apache common. So, I have decided to define an Aspect that will add the toString method to all my classes.

 

The Aspect

public aspect ToString {
    private interface ReflectiveToString {}
    declare parents : com.invalidcodeexception.experiment.aspectj.* implements ReflectiveToString;

    public String ReflectiveToString.toString(){
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}

With AspectJ you cannot define a method implemtation for a set of classes directly, but you can do it for an interface, and so all inherited classes! Therefore, I first declare the ReflectiveToString interface; Then, I make all classes that I want to modify inheriting this interface; Finally, I add the toString implementation to all classes implementing ReflectiveToString. That's it! Now, all classes inside the package com.invalidcodeexception.experiment.aspectj and its sub-package will have a nice implementation of toString!

 

 Test

package com.invalidcodeexception.experiment.aspectj;

public class MyEntity {
    private String name;

    public MyEntity(String name) {
        this.name = name;
    }

    public static void main(String[] args) {
        MyEntity e = new MyEntity("hello");
        System.out.println("print entity : " + e.toString());
    }
}
 print entity : MyEntity[name=hello] 

Inheritance and overriding

The interesting point is that, you can override the toString methods in your classes. So the aspect acts like a default implementation. The only limitation is when one of your classes extends a class not concerned by your aspects which already define toString. You are facing a kind of multiple inheritance problem. In this case you will end with a "inter-type declaration" compilation error. Your best option is to simply define the toString method in the concerned class and calling super.toString()

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}