45

Lombok misses field's annotation while auto generating constructor. Is there a way to retain field's annotation in constructor input params?

Class to generate constructor,

@RequiredArgsConstructor(onConstructor = @__(@Inject))
public class Test {

    @Named("MyField")
    private final String field;
    @Named("MyHandler")
    private final SomeHandler handler;
}

Generated class :

public class Test {

    @Named("MyField")
    private final String field;
    @Named("MyField")
    private final SomeHandler handler;

    @Inject
    public Test(final String field, final SomeHandler handler) {
        this.field = field;
        this.handler = handler;
    }
}

Desired class :

public class Test {

    @Named("MyField")
    private final String field;
    @Named("MyHandler")
    private final SomeHandler handler;

    @Inject
    public Test(@Named("MyField")final String field, 
                @Named("MyHandler")final SomeHandler handler) {
        this.field = field;
        this.handler = handler;
    }

}
JJD
  • 50,076
  • 60
  • 203
  • 339
sidss
  • 923
  • 1
  • 12
  • 20
  • 1
    I don't think this ever got implemented as per: https://groups.google.com/forum/#!topic/project-lombok/2vaujDkV8Nw – Cheetah Mar 04 '17 at 12:40
  • 1
    @Cheetah I'm afraid, you're right. I started implementing it years ago, but it was more complicated than I thought. Nobody cared and I found out that I myself needed it only rarely and there was a workaround. – maaartinus Mar 07 '17 at 04:13

2 Answers2

59

In version v1.18.4 Lombok added support for copying specific annotations. Meaning, that if you put following setting to lombok.config:

lombok.copyableAnnotations += com.google.inject.name.Named

and apply following Lombok annotations to your class:

@RequiredArgsConstructor(onConstructor = @__(@Inject))
public class Hello {
    @NonNull @Named("my-name") String name;
}

the @Named annotation should be copied to your generated constructor argument.

Limitations: this does not work when annotation can't be put on a field or annotation on a field overrides constructor initialization

Konstantin Pelepelin
  • 1,303
  • 1
  • 14
  • 29
mladzo
  • 1,885
  • 1
  • 18
  • 10
12

There's no such feature and it looks like nobody cares. I proposed it once and started to implement it, but gave up (no demand and too much work).

It could look like

@RequiredArgsConstructor(onConstructor=@__(@Inject))
public class Something {
    @OnConstructor(@Named("userName"))
    private final String userName;

    @OnConstructor(@Named("userPassword"))
    private final String userPassword;

    private final int anotherField;

    private final int yetAnotherField;
}

or maybe just

@RequiredArgsConstructor(
     onConstructor=@__(@Inject),
     moveToConstructorArg=@__(@Named))
public class Something {
    @Named("userName")
    private final String userName;

    @Named("userPassword")
    private final String userPassword;

    private final int anotherField;

    private final int yetAnotherField;
}

or it could be controlled using lombok.config as you probably want all @Named annotations to be moved to the constructor.

I'm afraid, if you want it, then you have to do it yourself (my incomplete implementation might help you a bit).

FTR: There's a feature request now.

maaartinus
  • 44,714
  • 32
  • 161
  • 320