@NonNull or final fields in parent class

860 views
Skip to first unread message

mkimberlin

unread,
Dec 23, 2009, 11:40:23 AM12/23/09
to Project Lombok
I've attempted to search around for a solution to this, or even anyone
else who has noticed this, to no avail. If you have a class annotated
with @Data that contains a field annotated with @NonNull or that is
final and you extend that class and add other @NonNull or final fields
to the subclass, Lombok doesn't seem to handle it appropriately. I am
fairly new to using the Project Lombok annotations, so I am sure that
it is just as likely that I am missing something. So far, I'm not
finding that something. :)

Here is a rather contrived example:

---- SentientBeing.java ----
import java.util.Date;

import lombok.Data;
import lombok.NonNull;

@Data
public abstract class SentientBeing {
@NonNull private Date dateOfBirth;
}
---- End SentientBeing.java ----

---- Person.java ----
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;

@Data()
@EqualsAndHashCode(callSuper=true,exclude=
{"address","city","state","zip"})
@ToString(callSuper=true)
public class Person extends SentientBeing {
enum Gender { Male, Female }

@NonNull private String name;
@NonNull private final Gender gender;

private String ssn;
private String address;
private String city;
private String state;
private String zip;
}
---- End Person.java ----

In Eclipse this will give an error complaining about the implicit
default constructor being undefined. I could certainly write my own
constructor for this type of situation...but I would have expected to
get a constructor in person that looked something like:

public Person(@NonNull final Data dateOfBirth, @NonNull final String
name, @NonNull final Gender gender) {
super(dateOfBirth);
if (name == null) throw new java.lang.NullPointerException("name");
if (gender == null) throw new java.lang.NullPointerException
("gender");
this.name = name;
this.gender = gender;
}

Is there a complication here that I'm not keying in on?

Thanks,
-michael

Reinier Zwitserloot

unread,
Dec 23, 2009, 12:01:12 PM12/23/09
to Project Lombok
There is indeed a complication that you're not keying in on. It's an
unfortunate shortcoming of lombok (though it's near the top of our
priority list in fixing). Lombok does not have resolution: It does not
know about other java classes if they aren't in the source file with
the lombok annotation in it. So, lombok does not know what
constructors are available in the superclass. In practice this means
@Data-generated constructors cannot call super() because they don't
know what to pass on. @Data/@EqualsAndHashCode generated equals and
hashCode methods DO call on super.hashCode() and super.equals() where
appropriate, because lombok does not need to know about the structure
of the superclass to do it, all it needs to know is that there is one,
which it can figure out based on your 'extends' clauses.

The workaround is to write your own constructor, as you already
mentioned at the end of your post; once there's any hand-written
constructor in the class, @Data will not generate any constructors
itself.


The biggest issue in the way of making resolution work (once
resolution works, generating an appropriate constructor that calls
super with the required arguments is easy), is eclipse. However, Roel
and I are trying to run lombok later in the eclipse compilation
process, and we've booked some tentative success here (though we're by
not quote in a phase where we can say definitively that we've figured
out how to do it). Resolution in javac processors (and by extension,
netbeans) is easy.

mkimberlin

unread,
Dec 23, 2009, 12:16:45 PM12/23/09
to Project Lombok
Excellent. Thanks for the prompt reply!
Reply all
Reply to author
Forward
0 new messages