From 599b6aab677439ae1bdea2cdca3233d0b763fd3f Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot
+ Any class definition may be annotated with
+ By setting
+ Setting
+ NEW in Lombok 0.10: Unless your class is
+ NEW in Lombok 1.14.0: To put annotations on the
+ Arrays are 'deep' compared/hashCoded, which means that arrays that contain themselves will result in
+ You may safely presume that the hashCode implementation used will not change between versions of lombok, however this guarantee is not set in stone; if there's a significant performance improvement to be gained from using an alternate hash algorithm, that will be substituted in a future version.
+
+ For the purposes of equality, 2
+ If there is any method named either
+ Attempting to exclude fields that don't exist or would have been excluded anyway (because they are static or transient) results in warnings on the named fields. You therefore don't have to worry about typos.
+
+ Having both
+ By default, any variables that start with a $ symbol are excluded automatically. You can onlyinclude them by using the 'of' parameter.
+
+ If a getter exists for a field to be included, it is called instead of using a direct field reference. This behaviour can be suppressed:
+ You can let lombok generate a getter which will calculate a value once, the first time this getter is called, and cache it from then on. This can be useful if calculating the value takes a lot of CPU, or the value takes a lot of memory. To use this feature, create a
+ You should never refer to the field directly, always use the getter generated by lombok, because the type of the field will be mangled into an
+ Other Lombok annotations such as
+ You can annotate any field with
+ The generated getter/setter method will be
+ You can also put a
+ You can always manually disable getter/setter generation for any field by using the special
+ To put annotations on the generated method, you can use
+ NEW in lombok v1.12.0: javadoc on the field will now be copied to generated getters and setters. Normally, all text is copied, and
+ For generating the method names, the first character of the field, if it is a lowercase character, is title-cased, otherwise, it is left unmodified. Then, get/set/is is prefixed.
+
+ No method is generated if any method already exists with the same name (case insensitive) and same parameter count. For example,
+ For
+ Any variation on
+ Any annotations named
+ You can annotate a class with a
+ Using the
+
+ You can use
+ Lombok has always treated any annotation named
+ The null-check looks like
+ If a null-check is already present at the top, no additional null-check will be generated.
+
+ Lombok's detection scheme for already existing null-checks consists of scanning for if statements that look just like lombok's own. Any 'throws' statement as the 'then' part of the if statement, whether in braces or not, counts. The conditional of the if statement must look exactly like
+ While
+ A
+
+ Common use cases for when you want to opt out of the checked exception mechanism center around 2 situations:hashCode
and equals
implementations from the fields of your object.">
+ <@f.overview>
+ @EqualsAndHashCode
to let lombok generate implementations of the equals(Object other)
and hashCode()
methods. By default, it'll use all non-static, non-transient fields, but you can exclude more fields by naming them in the optional exclude
parameter to the annotation. Alternatively, you can specify exactly which fields you wish to be used by naming them in the of
parameter.
+ callSuper
to true, you can include the equals
and hashCode
methods of your superclass in the generated methods. For hashCode
, the result of super.hashCode()
is included in the hash algorithm, and for equals
, the generated method will return false if the super implementation thinks it is not equal to the passed in object. Be aware that not all equals
implementations handle this situation properly. However, lombok-generated equals
implementations do handle this situation properly, so you can safely call your superclass equals if it, too, has a lombok-generated equals
method.
+ callSuper
to true when you don't extend anything (you extend java.lang.Object
) is a compile-time error, because it would turn the generated equals()
and hashCode()
implementations into having the same behaviour as simply inheriting these methods from java.lang.Object
: only the same object will be equal to each other and will have the same hashCode. Not setting callSuper
to true when you extend another class generates a warning, because unless the superclass has no (equality-important) fields, lombok cannot generate an implementation for you that takes into account the fields declared by your superclasses. You'll need to write your own implementations, or rely on the callSuper
chaining facility.
+ final
and extends java.lang.Object
, lombok generates a canEqual
method which means JPA proxies can still be equal to their base class, but subclasses that add new state don't break the equals contract. The complicated reasons for why such a method is necessary are explained in this paper: How to Write an Equality Method in Java. If all classes in a hierarchy are a mix of scala case classes and classes with lombok-generated equals methods, all equality will 'just work'. If you need to write your own equals methods, you should always override canEqual
if you change equals
and hashCode
.
+ other
parameter of the equals
(and, if relevant, canEqual
) method, you can use onParam=@__({@AnnotationsHere})
. Be careful though! This is an experimental feature. For more details see the documentation on the onX feature.
+ lombok.equalsAndHashCode.doNotUseGetters
= [true
| false
] (default: false)
+ true
, lombok will access fields directly instead of using getters (if available) when generating equals
and hashCode
methods. The annotation parameter 'doNotUseGetters
', if explicitly specified, takes precedence over this setting.
+ lombok.equalsAndHashCode.flagUsage
= [warning
| error
] (default: not set)
+ @EqualsAndHashCode
as a warning or error if configured.
+ StackOverflowError
s. However, this behaviour is no different from e.g. ArrayList
.
+ NaN
(not a number) values for floats and doubles are considered equal, eventhough 'NaN == NaN' would return false. This is analogous to java.lang.Double
's equals method, and is in fact required to ensure that comparing an object to an exact copy of itself returns true
for equality.
+ hashCode
or equals
, regardless of return type, no methods will be generated, and a warning is emitted instead. These 2 methods need to be in sync with each other, which lombok cannot guarantee unless it generates all the methods, hence you always get a warning if one or both of the methods already exist. You can mark any method with @lombok.experimental.Tolerate
to hide them from lombok.
+ exclude
and of
generates a warning; the exclude
parameter will be ignored in that case.
+
+ @EqualsAndHashCode(doNotUseGetters = true)
+ @Getter(lazy=true)
was introduced in Lombok v0.10.
+ @f.history>
+
+ <@f.overview>
+ private final
variable, initialize it with the expression that's expensive to run, and annotate your field with @Getter(lazy=true)
. The field will be hidden from the rest of your code, and the expression will be evaluated no more than once, when the getter is first called. There are no magic marker values (i.e. even if the result of your expensive calculation is null
, the result is cached) and your expensive calculation need not be thread-safe, as lombok takes care of locking.
+ lombok.getter.lazy.flagUsage
= [warning
| error
] (default: not set)
+ @Getter(lazy=true)
as a warning or error if configured.
+ AtomicReference
. Do not try to directly access this AtomicReference
; if it points to itself, the value has been calculated, and it is null
. If the reference points to null
, then the value has not been calculated. This behaviour may change in future versions. Therefore, always use the generated getter to access your field!
+ @ToString
always call the getter even if you use doNotUseGetters=true
.
+ public int getFoo() {return foo;}
again.">
+ <@f.overview>
+ @Getter
and/or @Setter
, to let lombok generate the default getter/setter automatically.
+ A default getter simply returns the field, and is named getFoo
if the field is called foo
(or isFoo
if the field's type is boolean
). A default setter is named setFoo
if the field is called foo
, returns void
, and takes 1 parameter of the same type as the field. It simply sets the field to this value.
+ public
unless you explicitly specify an AccessLevel
, as shown in the example below. Legal access levels are PUBLIC
, PROTECTED
, PACKAGE
, and PRIVATE
.
+ @Getter
and/or @Setter
annotation on a class. In that case, it's as if you annotate all the non-static fields in that class with the annotation.
+ AccessLevel.NONE
access level. This lets you override the behaviour of a @Getter
, @Setter
or @Data
annotation on a class.
+ onMethod=@__({@AnnotationsHere})
; to put annotations on the only parameter of a generated setter method, you can use onParam=@__({@AnnotationsHere})
. Be careful though! This is an experimental feature. For more details see the documentation on the onX feature.
+ @return
is moved to the getter, whilst @param
lines are moved to the setter. Moved means: Deleted from the field's javadoc. It is also possible to define unique text for each getter/setter. To do that, you create a 'section' named GETTER
and/or SETTER
. A section is a line in your javadoc containing 2 or more dashes, then the text 'GETTER' or 'SETTER', followed by 2 or more dashes, and nothing else on the line. If you use sections, @return
and @param
stripping for that section is no longer done (move the @return
or @param
line into the section).
+ lombok.accessors.chain
= [true
| false
] (default: false)
+ true
, generated setters will return this
(instead of void
). An explicitly configured chain
parameter of an @Accessors
annotation takes precedence over this setting.
+ lombok.accessors.fluent
= [true
| false
] (default: false)
+ true
, generated getters and setters will not be prefixed with the bean-standard 'get
, is
or set
; instead, the methods will use the same name as the field (minus prefixes). An explicitly configured chain
parameter of an @Accessors
annotation takes precedence over this setting.
+ lombok.accessors.prefix
+= a field prefix (default: empty list)
+ +=
operator. Inherited prefixes from parent config files can be removed with the -=
operator. Lombok will strip any matching field prefix from the name of a field in order to determine the name of the getter/setter to generate. For example, if m
is one of the prefixes listed in this setting, then a field named mFoobar
will result in a getter named getFoobar()
, not getMFoobar()
. An explicitly configured prefix
parameter of an @Accessors
annotation takes precedence over this setting.
+ lombok.getter.noIsPrefix
= [true
| false
] (default: false)
+ true
, getters generated for boolean
fields will use the get
prefix instead of the defaultis
prefix, and any generated code that calls getters, such as @ToString
, will also use get
instead of is
+ lombok.setter.flagUsage
= [warning
| error
] (default: not set)
+ @Setter
as a warning or error if configured.
+ lombok.getter.flagUsage
= [warning
| error
] (default: not set)
+ @Getter
as a warning or error if configured.
+ getFoo()
will not be generated if there's already a method getFoo(String... x)
even though it is technically possible to make the method. This caveat exists to prevent confusion. If the generation of a method is skipped for this reason, a warning is emitted instead. Varargs count as 0 to N parameters. You can mark any method with @lombok.experimental.Tolerate
to hide them from lombok.
+ boolean
fields that start with is
immediately followed by a title-case letter, nothing is prefixed to generate the getter name.
+ boolean
will not result in using the is
prefix instead of the get
prefix; for example, returning java.lang.Boolean
results in a get
prefix, not an is
prefix.
+ @NonNull
(case insensitive) on the field are interpreted as: This field must not ever hold null. Therefore, these annotations result in an explicit null check in the generated setter. Also, these annotations (as well as any annotation named @Nullable
or @CheckForNull
) are copied to setter parameter and getter method.
+ @Getter
or @Setter
annotation. Doing so is equivalent to annotating all non-static fields in that class with that annotation. @Getter
/@Setter
annotations on fields take precedence over the ones on classes.
+ AccessLevel.NONE
access level simply generates nothing. It's useful only in combination with @Data
or a class-wide @Getter
or @Setter
.
+ @Getter
can also be used on enums. @Setter
can't, not for a technical reason, but for a pragmatic one: Setters on enums are an extremely bad idea.
+ @NonNull
was introduced in lombok v0.11.10.
+ @f.history>
+
+ <@f.overview>
+ @NonNull
on the parameter of a method or constructor to have lombok generate a null-check statement for you.
+ @NonNull
on a field as a signal to generate a null-check if lombok generates an entire method or constructor for you, via for example @Data
. Now, however, using lombok's own @lombok.NonNull
on a parameter results in the insertion of just the null-check statement inside your own method or constructor.
+ if (param == null) throw new NullPointerException("param");
and will be inserted at the very top of your method. For constructors, the null-check will be inserted immediately following any explicit this()
or super()
calls.
+ lombok.nonNull.exceptionType
= [NullPointerException
| IllegalArgumentException
] (default: NullPointerException
).
+ if
statement, by default, a java.lang.NullPointerException
will be thrown with the field name as the exception message. However, you can use IllegalArgumentException
in this configuration key to have lombok throw that exception, with 'fieldName is null' as exception message.
+ lombok.nonNull.flagUsage
= [warning
| error
] (default: not set)
+ @NonNull
as a warning or error if configured.
+ PARAMNAME == null
. The first statement in your method that is not such a null-check stops the process of inspecting for null-checks.
+ @Data
and other method-generating lombok annotations will trigger on any annotation named @NonNull
regardless of casing or package name, this feature only triggers on lombok's own @NonNull
annotation from the lombok
package.
+ @NonNull
on a primitive parameter results in a warning. No null-check will be generated.
+ @SneakyThrows
can be used to sneakily throw checked exceptions without actually declaring this in your method's throws
clause. This somewhat contentious ability should be used carefully, of course. The code generated by lombok will not ignore, wrap, replace, or otherwise modify the thrown checked exception; it simply fakes out the compiler. On the JVM (class file) level, all exceptions, checked or not, can be thrown regardless of the throws
clause of your methods, which is why this works.
+
+
+
+ Runnable
- whatever exception propagates out of your run()
method, checked or not, it will be passed to the Thread
's unhandled exception handler. Catching a checked exception and wrapping it in some sort of RuntimeException
is only obscuring the real cause of the issue.
+ new String(someByteArray, "UTF-8");
declares that it can throw an UnsupportedEncodingException
but according to the JVM specification, UTF-8 must always be available. An UnsupportedEncodingException
here is about as likely as a ClassNotFoundError
when you use a String object, and you don't catch those either!
+
+ Be aware that it is impossible to catch sneakily thrown checked types directly, as javac will not let you write a catch block for an exception type that no method call in the try body declares as thrown. This problem is not relevant in either of the use cases listed above, so let this serve as a warning that you should not use the @SneakyThrows
mechanism without some deliberation!
+
+ You can pass any number of exceptions to the @SneakyThrows
annotation. If you pass no exceptions, you may throw any exception sneakily.
+
lombok.sneakyThrows.flagUsage
= [warning
| error
] (default: not set)
+ @SneakyThrows
as a warning or error if configured.
+
+ Because @SneakyThrows
is an implementation detail and not part of your method signature, it is an error if you try to declare a checked exception as sneakily thrown when you don't call any methods that throw this exception. (Doing so is perfectly legal for throws
statements to accommodate subclasses). Similarly, @SneakyThrows
does not inherit.
+
+ For the nay-sayers in the crowd: Out of the box, Eclipse will offer a 'quick-fix' for uncaught exceptions that wraps the offending statement in a try/catch block with just e.printStackTrace()
in the catch block. This is so spectacularly non-productive compared to just sneakily throwing the exception onwards, that Roel and Reinier feel more than justified in claiming that the checked exception system is far from perfect, and thus an opt-out mechanism is warranted.
+
+ If you put @SneakyThrows
on a constructor, any call to a sibling or super constructor is excluded from the @SneakyThrows
treatment. This is a java restriction we cannot work around: Calls to sibling/super constructors MUST be the first statement in the constructor; they cannot be placed inside try/catch blocks.
+
+ @SneakyThrows
on an empty method, or a constructor that is empty or only has a call to a sibling / super constructor results in no try/catch block and a warning.
+
synchronized
done right: Don't expose your locks.">
+ <@f.overview>
+
+ @Synchronized
is a safer variant of the synchronized
method modifier. Like synchronized
, the annotation can be used on static and instance methods only. It operates similarly to the synchronized
keyword, but it locks on different objects. The keyword locks on this
, but the annotation locks on a field named $lock
, which is private.
+ If the field does not exist, it is created for you. If you annotate a static
method, the annotation locks on a static field named $LOCK
instead.
+
+ If you want, you can create these locks yourself. The $lock
and $LOCK
fields will of course not be generated if you already created them yourself. You can also choose to lock on another field, by specifying it as parameter to the @Synchronized
annotation. In this usage variant, the fields will not be created automatically, and you must explicitly create them yourself, or an error will be emitted.
+
+ Locking on this
or your own class object can have unfortunate side-effects, as other code not under your control can lock on these objects as well, which can cause race conditions and other nasty threading-related bugs.
+
lombok.synchronized.flagUsage
= [warning
| error
] (default: not set)
+ @Synchronized
as a warning or error if configured.
+
+ If $lock
and/or $LOCK
are auto-generated, the fields are initialized with an empty Object[]
array, and not just a new Object()
as most snippets showing this pattern in action use. Lombok does this because a new object is NOT serializable, but 0-size array is. Therefore, using @Synchronized
will not prevent your object from being serialized.
+
+ Having at least one @Synchronized
method in your class means there will be a lock field, but if you later remove all such methods, there will no longer be a lock field. That means your predetermined serialVersionUID
changes. We suggest you always add a serialVersionUID
to your classes if you intend to store them long-term via java's serialization mechanism. If you do so, removing all @Synchronized
annotations from your method will not break serialization.
+
+ If you'd like to know why a field is not automatically generated when you choose your own name for the lock object: Because otherwise making a typo in the field name will result in a very hard to find bug! +
+ @f.smallPrint> +@f.scaffold> diff --git a/website2/templates/features/ToString.html b/website2/templates/features/ToString.html new file mode 100644 index 00000000..6f230561 --- /dev/null +++ b/website2/templates/features/ToString.html @@ -0,0 +1,54 @@ +<#import "_features.html" as f> + +<@f.scaffold title="@ToString" logline="No need to start a debugger to see your fields: Just let lombok generate atoString
for you!">
+ <@f.overview>
+
+ Any class definition may be annotated with @ToString
to let lombok generate an implementation of the toString()
method. By default, it'll print your class name, along with each field, in order, separated by commas.
+
+ By setting the includeFieldNames
parameter to true you can add some clarity (but also quite some length) to the output of the toString()
method.
+
+ By default, all non-static fields will be printed. If you want to skip some fields, you can name them in the exclude
parameter; each named field will not be printed at all. Alternatively, you can specify exactly which fields you wish to be used by naming them in the of
parameter.
+
+ By setting callSuper
to true, you can include the output of the superclass implementation of toString
to the output. Be aware that the default implementation of toString()
in java.lang.Object
is pretty much meaningless, so you probably don't want to do this unless you are extending another class.
+
lombok.toString.includeFieldNames
= [true
| false
] (default: true)
+ fieldName = fieldValue
. If this setting is set to false
, lombok will omit the name of the field and simply deploy a comma-separated list of all the field values. The annotation parameter 'includeFieldNames
', if explicitly specified, takes precedence over this setting.
+ lombok.toString.doNotUseGetters
= [true
| false
] (default: false)
+ true
, lombok will access fields directly instead of using getters (if available) when generating toString
methods. The annotation parameter 'doNotUseGetters
', if explicitly specified, takes precedence over this setting.
+ lombok.toString.flagUsage
= [warning
| error
] (default: not set)
+ @ToString
as a warning or error if configured.
+
+ If there is any method named toString
with no arguments, regardless of return type, no method will be generated, and instead a warning is emitted explaining that your @ToString
annotation is doing nothing. You can mark any method with @lombok.experimental.Tolerate
to hide them from lombok.
+
+ Arrays are printed via Arrays.deepToString
, which means that arrays that contain themselves will result in StackOverflowError
s. However, this behaviour is no different from e.g. ArrayList
.
+
+ Attempting to exclude fields that don't exist or would have been excluded anyway (because they are static) results in warnings on the named fields. You therefore don't have to worry about typos. +
+ Having both exclude
and of
generates a warning; the exclude
parameter will be ignored in that case.
+
+ We don't promise to keep the output of the generated toString()
methods the same between lombok versions. You should never design your API so that other code is forced to parse your toString()
output anyway!
+
+ By default, any variables that start with a $ symbol are excluded automatically. You can only include them by using the 'of' parameter. +
+ If a getter exists for a field to be included, it is called instead of using a direct field reference. This behaviour can be suppressed:
+ @ToString(doNotUseGetters = true)
+
+ @ToString
can also be used on an enum definition.
+
+ @Builder
was introduced as experimental feature in lombok v0.12.0.
+
+ @Builder
gained @Singular
support and was promoted to the main lombok
package since lombok v1.16.0.
+
+ The @Builder
annotation produces complex builder APIs for your classes.
+
+ @Builder
lets you automatically produce the code required to have your class be instantiable with code such as:
+ Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build();
+
+ @Builder
can be placed on a class, or on a constructor, or on a static method. While the "on a class" and "on a constructor" mode are the most common use-case, @Builder
is most easily explained with the "static method" use-case.
+
+ A static method annotated with @Builder
(from now on called the target) causes the following 7 things to be generated:
+
FooBuilder
, with the same type arguments as the static method (called the builder).
+ build()
method which calls the static method, passing in each field. It returns the same type that the target returns.
+ toString()
implementation.
+ builder()
method, which creates a new instance of the builder.
+ @EqualsAndHashCode
on the builder class.
+
+ @Builder
can generate so-called 'singular' methods for collection parameters/fields. These take 1 element instead of an entire list, and add the element to the list. For example: Person.builder().job("Mythbusters").job("Unchained Reaction").build();
would result in the List<String> jobs
field to have 2 strings in it. To get this behaviour, the field/parameter needs to be annotated with @Singular
. The feature has its own documentation.
+
+ Now that the "static method" mode is clear, putting a @Builder
annotation on a constructor functions similarly; effectively, constructors are just static methods that have a special syntax to invoke them: Their 'return type' is the class they construct, and their type parameters are the same as the type parameters of the class itself.
+
+ Finally, applying @Builder
to a class is as if you added @AllArgsConstructor(access = AccessLevel.PACKAGE)
to the class and applied the @Builder
annotation to this all-args-constructor. This only works if you haven't written any explicit constructors yourself. If you do have an explicit constructor, put the @Builder
annotation on the constructor instead of on the class.
+
+ The name of the builder class is FoobarBuilder
, where Foobar is the simplified, title-cased form of the return type of the target - that is, the name of your type for @Builder
on constructors and types, and the name of the return type for @Builder
on static methods. For example, if @Builder
is applied to a class named com.yoyodyne.FancyList<T>
, then the builder name will be FancyListBuilder<T>
. If @Builder
is applied to a static method that returns void
, the builder will be named VoidBuilder
.
+
+ The configurable aspects of builder are: +
"build"
)
+ "builder"
)
+ @Builder(builderClassName = "HelloWorldBuilder", buildMethodName = "execute", builderMethodName = "helloWorld")
+ By annotating one of the parameters (if annotating a static method or constructor with @Builder
) or fields (if annotating a class with @Builder
) with the @Singular
annotation, lombok will treat that builder node as a collection, and it generates 2 'adder' methods instead of a 'setter' method. One which adds a single element to the collection, and one which adds all elements of another collection to the collection. No setter to just set the collection (replacing whatever was already added) will be generated. These 'singular' builders are very complicated in order to guarantee the following properties:
+
build()
, the produced collection will be immutable.
+ build()
does not modify any already generated objects, and, if build()
is later called again, another collection with all the elements added since the creation of the builder is generated.
+
+ @Singular
can only be applied to collection types known to lombok. Currently, the supported types are:
+
java.util
:
+ Iterable
, Collection
, and List
(backed by a compacted unmodifiable ArrayList
in the general case).
+ Set
, SortedSet
, and NavigableSet
(backed by a smartly sized unmodifiable HashSet
or TreeSet
in the general case).
+ Map
, SortedMap
, and NavigableMap
(backed by a smartly sized unmodifiable HashMap
or TreeMap
in the general case).
+ com.google.common.collect
:
+ ImmutableCollection
and ImmutableList
(backed by the builder feature of ImmutableList
).
+ ImmutableSet
and ImmutableSortedSet
(backed by the builder feature of those types).
+ ImmutableMap
, ImmutableBiMap
, and ImmutableSortedMap
(backed by the builder feature of those types).
+
+ If your identifiers are written in common english, lombok assumes that the name of any collection with @Singular
on it is an english plural and will attempt to automatically singularize that name. If this is possible, the add-one method will use this name. For example, if your collection is called statuses
, then the add-one method will automatically be called status
. You can also specify the singular form of your identifier explictly by passing the singular form as argument to the annotation like so: @Singular("axis") List<Line> axes;
.
+ If lombok cannot singularize your identifier, or it is ambiguous, lombok will generate an error and force you to explicitly specify the singular name.
+
+ The snippet below does not show what lombok generates for a @Singular
field/parameter because it is rather complicated. You can view a snippet here.
+
lombok.builder.flagUsage
= [warning
| error
] (default: not set)
+ @Builder
as a warning or error if configured.
+ lombok.singular.useGuava
= [true
| false
] (default: false)
+ true
, lombok will use guava's ImmutableXxx
builders and types to implement java.util
collection interfaces, instead of creating implementations based on Collections.unmodifiableXxx
. You must ensure that guava is actually available on the classpath and buildpath if you use this setting. Guava is used automatically if your field/parameter has one of the guava ImmutableXxx
types.
+ lombok.singular.auto
= [true
| false
] (default: true)
+ true
(which is the default), lombok automatically tries to singularize your identifier name by assuming that it is a common english plural. If false
, you must always explicitly specify the singular name, and lombok will generate an error if you don't (useful if you write your code in a language other than english).
+
+ @Singular support for java.util.NavigableMap/Set
only works if you are compiling with JDK1.8 or higher.
+
+ You cannot manually provide some or all parts of a @Singular
node; the code lombok generates is too complex for this. If you want to manually control (part of) the builder code associated with some field or parameter, don't use @Singular
and add everything you need manually.
+
+ The sorted collections (java.util: SortedSet
, NavigableSet
, SortedMap
, NavigableMap
and guava: ImmutableSortedSet
, ImmutableSortedMap
) require that the type argument of the collection has natural order (implements java.util.Comparable
). There is no way to pass an explicit Comparator
to use in the builder.
+
+ An ArrayList
is used to store added elements as call methods of a @Singular
marked field, if the target collection is from the java.util
package, even if the collection is a set or map. Because lombok ensures that generated collections are compacted, a new backing instance of a set or map must be constructed anyway, and storing the data as an ArrayList
during the build process is more efficient that storing it as a map or set. This behaviour is not externally visible, an implementation detail of the current implementation of the java.util
recipes for @Singular @Builder
.
+
close()
methods safely with no hassle.">
+ <@f.overview>
+
+ You can use @Cleanup
to ensure a given resource is automatically cleaned up before the code execution path exits your current scope. You do this by annotating any local variable declaration with the @Cleanup
annotation like so:
+ @Cleanup InputStream in = new FileInputStream("some/file");
+ As a result, at the end of the scope you're in, in.close()
is called. This call is guaranteed to run by way of a try/finally construct. Look at the example below to see how this works.
+
+ If the type of object you'd like to cleanup does not have a close()
method, but some other no-argument method, you can specify the name of this method like so:
+ @Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);
+ By default, the cleanup method is presumed to be close()
. A cleanup method that takes 1 or more arguments cannot be called via @Cleanup
.
+
lombok.cleanup.flagUsage
= [warning
| error
] (default: not set)
+ @Cleanup
as a warning or error if configured.
+
+ @f.confKeys>
+
+ <@f.smallPrint>
+
+ In the finally block, the cleanup method is only called if the given resource is not null
. However, if you use delombok
on the code, a call to lombok.Lombok.preventNullAnalysis(Object o)
is inserted to prevent warnings if static code analysis could determine that a null-check would not be needed. Compilation with lombok.jar
on the classpath removes that method call, so there is no runtime dependency.
+
+ If your code throws an exception, and the cleanup method call that is then triggered also throws an exception, then the original exception is hidden by the exception thrown by the cleanup call. You should not rely on this 'feature'. Preferably, lombok would like to generate code so that, if the main body has thrown an exception, any exception thrown by the close call is silently swallowed (but if the main body exited in any other way, exceptions by the close call will not be swallowed). The authors of lombok do not currently know of a feasible way to implement this scheme, but if java updates allow it, or we find a way, we'll fix it. +
+ You do still need to handle any exception that the cleanup method can generate! +
+ @f.smallPrint> +@f.scaffold> diff --git a/website2/templates/features/configuration.html b/website2/templates/features/configuration.html new file mode 100644 index 00000000..db3fc736 --- /dev/null +++ b/website2/templates/features/configuration.html @@ -0,0 +1,93 @@ +<#import "_features.html" as f> + +<@f.scaffold title="Configuration system" logline="Lombok, made to order: Configure lombok features in one place for your entire project or even your workspace."> + <@f.history> + The configuration system was introduced in lombok 1.14. + @f.history> + + <@f.overview> +
+ You can create lombok.config
files in any directory and put configuration directives in it. These apply to all source files in this directory and all child directories.
+ The configuration system is particularly useful for configurable aspects of lombok which tend to be the same across an entire project, such as the name of your log variable. The configuration system can also be used to tell lombok to flag any usage of some lombok feature you don't like as a warning or even an error.
+
+ Usually, a user of lombok puts a lombok.config
file with their preferences in a workspace or project root directory, with the special config.stopBubbling = true
key to tell lombok this is your root directory. You can then create lombok.config
files in any subdirectories (generally representing projects or source packages) with different settings.
+
+ An up to date list of all configuration keys supported by your version of lombok can be generated by running: +
java -jar lombok.jar config -g --verbose
+ lombok.config
file.
+ A sample of available configuration options (see the feature pages of the lombok features for their related config keys, as well as java -jar lombok.jar config -g
for the complete list):
+
lombok.accessors.chain
+ true
, generated setters will 'chain' by default (They will return this
instead of having a void
return type).
+ lombok.accessors.fluent
+ true
, generated setters and getters will simply be named the same as the field name, without a get
or set
prefix.
+ lombok.anyConstructor.suppressConstructorProperties
+ true
, lombok will not generate a @java.beans.ConstructorProperties
annotation when generating constructors. This is particularly useful for GWT and Android development.
+ lombok.log.fieldName
+ log
).
+ lombok.(featureName).flagUsage
+ warning
or error
. Some examples of values for (featureName) are: "experimental
" (flags use of any of the experimental features), "builder
", "sneakyThrows
", or "extensionMethod
".
+
+ Configuration files are hierarchical: Any configuration setting applies to all source files in that directory, and all source files in subdirectories, but configuration settings closer to the source file take precedence. For example, if you have in /Users/me/projects/lombok.config
the following:
+
lombok.log.fieldName = foobar
+ /Users/me/projects/MyProject/lombok.config
you have:
+ lombok.log.fieldName = xyzzy
+ @Log
annotations will use foobar
instead of the default log
as a field name to generate in all your projects, except for your project in /Users/me/projects/MyProject
, where xyzzy
is used instead.
+
+ To restore a configuration key set by a parent config file back to the default, the clear
option can be used. For example, if a parent configuration file has configured all use of val
to emit a warning, you can turn off the warnings for a subdirectory by including in it a lombok.config
file with:
+
clear lombok.val.flagUsage
+
+ Some configuration keys take lists. For lists, use +=
to add an entry. You can remove a single item from the list (useful to undo a parent configuration file's setting) with -=
. For example:
+
lombok.accessors.prefix += m_
+
+ Comments can be included in lombok.config
files; any line that starts with #
is considered a comment.
+
+ To stop lombok from looking at parent directories for more configuration files, the special key: +
config.stopBubbling = true
+
+ Lombok normally adds @javax.annotation.Generated
annotations to all generated nodes where possible. You can stop this with:
+
lombok.addGeneratedAnnotation = false
+
+ Lombok can add the @SuppressFBWarnings
annotation which is useful if you want to run FindBugs on your class files. To enable this feature, make sure findbugs is on the classpath when you compile, and add the following config key:
+
lombok.extern.findbugs.addSuppressFBWarnings = true
+ + This set of 3 annotations generate a constructor that will accept 1 parameter for certain fields, and simply assigns this parameter to the field. +
+ @NoArgsConstructor
will generate a constructor with no parameters. If this is not possible (because of final fields), a compiler error will result instead. For fields with constraints, such as @NonNull
fields, no check or assignment is generated, so be aware that these constraints may then not be fulfilled until those fields are properly initialized later. Certain java constructs, such as hibernate and the Service Provider Interface require a no-args constructor. This annotation is useful primarily in combination with either @Data
or one of the other constructor generating annotations.
+
+ @RequiredArgsConstructor
generates a constructor with 1 parameter for each field that requires special handling. All non-initialized final
fields get a parameter, as well as any fields that are marked as @NonNull
that aren't initialized where they are declared. For those fields marked with @NonNull
, an explicit null check is also generated. The constructor will throw a NullPointerException
if any of the parameters intended for the fields marked with @NonNull
contain null
. The order of the parameters match the order in which the fields appear in your class.
+
+ @AllArgsConstructor
generates a constructor with 1 parameter for each field in your class. Fields marked with @NonNull
result in null checks on those parameters.
+
+ Each of these annotations allows an alternate form, where the generated constructor is always private, and an additional static factory method that wraps around the private constructor is generated. This mode is enabled by supplying the staticName
value for the annotation, like so: @RequiredArgsConstructor(staticName="of")
. Such a static factory method will infer generics, unlike a normal constructor. This means your API users get write MapEntry.of("foo", 5)
instead of the much longer new MapEntry<String, Integer>("foo", 5)
.
+
+ To put annotations on the generated constructor, you can use onConstructor=@__({@AnnotationsHere})
, but be careful; this is an experimental feature. For more details see the documentation on the onX feature.
+
+ Static fields are skipped by these annotations. Also, a @java.beans.ConstructorProperties
annotation is added for all constructors with at least 1 argument, which allows bean editor tools to call the generated constructors. @ConstructorProperties
is now in Java 1.6, which means that if your code is intended for compilation on Java 1.5, a compiler error will occur. Running on a JVM 1.5 should be no problem (the annotation will be ignored). To suppress the generation of the @ConstructorProperties
annotation, add a parameter to your annotation: @AllArgsConstructor(suppressConstructorProperties=true)
. However, as java 1.5, which has already been end-of-lifed, fades into obscurity, this parameter will eventually be removed. It has also been marked deprecated for this reason.
+
+ Unlike most other lombok annotations, the existence of an explicit constructor does not stop these annotations from generating their own constructor. This means you can write your own specialized constructor, and let lombok generate the boilerplate ones as well. If a conflict arises (one of your constructors ends up with the same signature as one that lombok generates), a compiler error will occur. +
+ @f.overview> + + <@f.snippets name="Constructor" /> + + <@f.confKeys> +lombok.anyConstructor.suppressConstructorProperties
= [true
| false
] (default: false
)
+ true
, then lombok will skip adding a @java.beans.ConstructorProperties
to generated constructors. This is useful in android and GWT development where that annotation is not usually available.
+ lombok.
[allArgsConstructor
|requiredArgsConstructor
|noArgsConstructor
].flagUsage
= [warning
| error
] (default: not set)
+ @AllArgsConstructor
, @RequiredArgsConstructor
or @NoArgsConstructor
) as a warning or error if configured.
+ lombok.anyConstructor.flagUsage
= [warning
| error
] (default: not set)
+
+ Even if a field is explicitly initialized with null
, lombok will consider the requirement to avoid null as fulfilled, and will NOT consider the field as a 'required' argument. The assumption is that if you explicitly assign null
to a field that you've also marked as @NonNull
signals you must know what you're doing.
+
+ The @java.beans.ConstructorProperties
annotation is never generated for a constructor with no arguments. This also explains why @NoArgsConstructor
lacks the suppressConstructorProperties
annotation method. The @ConstructorProperties
annotation is also omitted for private constructors. The generated static factory methods also do not get @ConstructorProperties
, as this annotation can only be added to real constructors.
+
+ @XArgsConstructor
can also be used on an enum definition. The generated constructor will always be private, because non-private constructors aren't legal in enums. You don't have to specify AccessLevel.PRIVATE
.
+
+ While suppressConstructorProperties
has been marked deprecated in anticipation of a world where all java environments have the @ConstructorProperties
annotation available, first GWT 2.2 and Android 2.3.3, which do not (yet) have this annotation, will have to be ancient history before this annotation parameter will be removed.
+
+ The flagUsage
configuration keys do not trigger when a constructor is generated by @Data
, @Value
or any other lombok annotation.
+
@ToString
, @EqualsAndHashCode
, @Getter
on all fields, @Setter
on all non-final fields, and @RequiredArgsConstructor
!">
+
+ <@f.overview>
+
+ @Data
is a convenient shortcut annotation that bundles the features of @ToString
, @EqualsAndHashCode
, @Getter
/ @Setter
and @RequiredArgsConstructor
together: In other words, @Data
generates all the boilerplate that is normally associated with simple POJOs (Plain Old Java Objects) and beans: getters for all fields, setters for all non-final fields, and appropriate toString
, equals
and hashCode
implementations that involve the fields of the class, and a constructor that initializes all final fields, as well as all non-final fields with no initializer that have been marked with @NonNull
, in order to ensure the field is never null.
+
+ @Data
is like having implicit @Getter
, @Setter
, @ToString
, @EqualsAndHashCode
and @RequiredArgsConstructor
annotations on the class. However, the parameters of these annotations (such as callSuper
, includeFieldNames
and exclude
) cannot be set with @Data
. If you need to set non-default values for any of these parameters, just add those annotations explicitly; @Data
is smart enough to defer to those annotations.
+
+ All generated getters and setters will be public
. To override the access level, annotate the field or class with an explicit @Setter
and/or @Getter
annotation. You can also use this annotation (by combining it with AccessLevel.NONE
) to suppress generating a getter and/or setter altogether.
+
+ All fields marked as transient
will not be considered for hashCode
and equals
. All static fields will be skipped entirely (not considered for any of the generated methods, and no setter/getter will be made for them).
+
+ If the class already contains a method with the same name and parameter count as any method that would normally be generated, that method is not generated, and no warning or error is emitted. For example, if you already have a method with signature equals(AnyType param)
, no equals
method will be generated, even though technically it might be an entirely different method due to having different parameter types. The same rule applies to the constructor (any explicit constructor will prevent @Data
from generating one), as well as toString
, equals
, and all getters and setters. You can mark any constructor or method with @lombok.experimental.Tolerate
to hide them from lombok.
+
+ @Data
can handle generics parameters for fields just fine. In order to reduce the boilerplate when constructing objects for classes with generics, you can use the staticConstructor
parameter to generate a private constructor, as well as a static method that returns a new instance. This way, javac will infer the variable name. Thus, by declaring like so: @Data(staticConstructor="of") class Foo<T> { private T x;}
you can create new instances of Foo
by writing: Foo.of(5);
instead of having to write: new Foo<Integer>(5);
.
+
lombok.data.flagUsage
= [warning
| error
] (default: not set)
+ @Data
as a warning or error if configured.
+
+ See the small print of @ToString
, @EqualsAndHashCode
, @Getter / @Setter
and @RequiredArgsConstructor.
+
+ Any annotations named @NonNull
(case insensitive) on a field are interpreted as: This field must not ever hold null. Therefore, these annotations result in an explicit null check in the generated constructor for the provided field. Also, these annotations (as well as any annotation named @Nullable
) are copied to the constructor parameter, in both the true constructor and any static constructor. The same principle applies to generated getters and setters (see the documentation for @Getter / @Setter)
+
+ By default, any variables that start with a $ symbol are excluded automatically. You can include them by specifying an explicit annotation (@Getter
or @ToString
, for example) and using the 'of' parameter.
+
+ Normally, lombok adds support for all the lombok features directly to your IDE and compiler by plugging into them.
+ However, lombok doesn't cover all tools. For example, lombok cannot plug into javadoc, nor can it plug into the Google Widget Toolkit, both of which run on java sources. Delombok still allows you to use lombok with these tools by preprocessing your java code into java code with all of lombok's transformations already applied.
+
+ Delombok can of course also help understand what's happening with your source by letting you look at exactly what lombok is doing 'under the hood'. +
+ Delombok's standard mode of operation is that it copies an entire directory into another directory, recursively, skipping class files, and applying lombok transformations to any java source files it encounters. +
+ Delombok's output format can be configured with command line options (use --format-help
for a complete list). A few such options are automatically scanned from input if possible (such as indent). If delombok's formatting is not conforming to your preferred code style, have a look!
+
+ Delombok is included in lombok.jar
. To use it, all you need to run on the command line is:
+
java -jar lombok.jar delombok src -d src-delomboked+
src
directory into the src-delomboked
directory, which will be created if it doesn't already exist, but delomboked of course. Delombok on the command line has a few more options; use the --help
parameter to see more options.
+ + To let delombok print the transformation result of a single java file directly to standard output, you can use: +
java -jar lombok.jar delombok -p MyJavaFile.java+
+ lombok.jar
includes an ant task which can apply delombok for you. For example, to create javadoc for your project, your build.xml
file would look something like:
+
<target name="javadoc"> +<taskdef classname="lombok.delombok.ant.Tasks$Delombok" classpath="lib/lombok.jar" name="delombok" /> +<mkdir dir="build/src-delomboked" /> +<delombok verbose="true" encoding="UTF-8" to="build/src-delomboked" from="src"> + <format value="suppressWarnings:skip" /> +</delombok> +<mkdir dir="build/api" /> +<javadoc sourcepath="build/src-delomboked" defaultexcludes="yes" destdir="build/api" /> +</target>+
from
attribute, you can also nest <fileset>
nodes.
+
+
+ + Anthony Whitford has written a maven plugin for delomboking your source code. +
+ +
+ Delombok tries to preserve your code as much as it can, but comments may move around a little bit, especially comments that are in the middle of a syntax node. For example, any comments appearing in the middle of a list of method modifiers, such as public /*comment*/ static ...
will move towards the front of the list of modifiers. In practice, any java source parsing tool will not be affected.
+ To keep any changes to your code style to a minimum, delombok just copies a source file directly without changing any of it if the source file contains no lombok transformations.
+
+ @Accessors
was introduced as experimental feature in lombok v0.11.0.
+
+ The @Accessors
annotation is used to configure how lombok generates and looks for getters and setters.
+
+ By default, lombok follows the bean specification for getters and setters: The getter for a field named pepper
is getPepper
for example. However, some might like to break with the bean specification in order to end up with nicer looking APIs. @Accessors
lets you do this.
+
+ Some programmers like to use a prefix for their fields, i.e. they write fPepper
instead of pepper
. We strongly discourage doing this, as you can't unit test the validity of your prefixes, and refactor scripts may turn fields into local variables or method names. Furthermore, your tools (such as your editor) can take care of rendering the identifier in a certain way if you want this information to be instantly visible. Nevertheless, you can list the prefixes that your project uses via @Accessors
as well.
+
+ @Accessors
therefore has 3 options:
+
fluent
– A boolean. If true, the getter for pepper
is just pepper()
, and the setter is pepper(T newValue)
. Furthermore, unless specified, chain
defaults to true. chain
– A boolean. If true, generated setters return this
instead of void
.fluent=true
, then Default: true.
+ prefix
– A list of strings. If present, fields must be prefixed with any of these prefixes. Each field name is compared to each prefix in the list in turn, and if a match is found, the prefix is stripped out to create the base name for the field. It is legal to include an empty string in the list, which will always match. For characters which are letters, the character following the prefix must not be a lowercase letter, i.e. pepper
is not a match even to prefix p
, but pEpper
would be (and would mean the base name of this field is epper
).
+
+ The @Accessors
annotation is legal on types and fields; the annotation that applies is the one on the field if present, otherwise the one on the class. When a @Accessors
annotation on a field is present, any @Accessors
annotation also present on that field's type is ignored.
+
lombok.accessors.chain
= [true
| false
] (default: false)
+ true
, any class that either doesn't have an @Accessors
annotation, or it does, but that annotation does not have an explicit value for the chain
parameter, will act as if @Accessors(chain = true)
is present.
+ lombok.accessors.fluent
= [true
| false
] (default: false)
+ true
, any class that either doesn't have an @Accessors
annotation, or it does, but that annotation does not have an explicit value for the fluent
parameter, will act as if @Accessors(fluent = true)
is present.
+ lombok.accessors.prefix
+= a field prefix (default: empty list)
+ +=
operator. Inherited prefixes from parent config files can be removed with the -=
operator. Any class that either doesn't have an @Accessors
annotation, or it does, but that annotation does not have an explicit value for the prefix
parameter, will act as if @Accessors(prefix = {prefixes listed in configuration})
is present.
+ lombok.accessors.flagUsage
= [warning
| error
] (default: not set)
+ @Accessors
as a warning or error if configured.
+
+ The nearest @Accessors
annotation is also used for the various methods in lombok that look for getters, such as @EqualsAndHashCode
.
+
+ If a prefix list is provided and a field does not start with one of them, that field is skipped entirely by lombok, and a warning will be generated. +
+ @f.smallPrint> +@f.scaffold> diff --git a/website2/templates/features/experimental/Delegate.html b/website2/templates/features/experimental/Delegate.html new file mode 100644 index 00000000..265c754a --- /dev/null +++ b/website2/templates/features/experimental/Delegate.html @@ -0,0 +1,59 @@ +<#import "../_features.html" as f> + +<@f.scaffold title="@Delegate" logline="Don't lose your composition."> + <@f.history> +
+ @Delegate
was introduced as feature in lombok v0.10 (the experimental package did not exist yet).
+ It was moved to the experimental package in lombok v1.14; the old version from the main lombok package is now deprecated.
+
@Delegate
generate delegates for whatever you didn't manually implement, but due to issues with generics erasure this also can't be made to work without caveats.
+
+ Any field or no-argument method can be annotated with @Delegate
to let lombok generate delegate methods that forward the call to this field (or the result of invoking this method).
+
+ Lombok delegates all public
methods of the field's type (or method's return type), as well as those of its supertypes except for all methods declared in java.lang.Object
.
+
+ You can pass any number of classes into the @Delegate
annotation's types
parameter. If you do that, then lombok will delegate all public
methods in those types (and their supertypes, except java.lang.Object
) instead of looking at the field/method's type.
+
+ All public non-Object
methods that are part of the calculated type(s) are copied, whether or not you also wrote implementations for those methods. That would thus result in duplicate method errors. You can avoid these by using the @Delegate(excludes=SomeType.class)
parameter to exclude all public methods in the excluded type(s), and their supertypes.
+
+ To have very precise control over what is delegated and what isn't, write private inner interfaces with method signatures, then specify these private inner interfaces as types in @Delegate(types=PrivateInnerInterfaceWithIncludesList.class, excludes=SameForExcludes.class)
.
+
lombok.delegate.flagUsage
= [warning
| error
] (default: not set)
+ @Delegate
as a warning or error if configured.
+
+ When passing classes to the annotation's types
or excludes
parameter, you cannot include generics. This is a limitation of java. Use private inner interfaces or classes that extend the intended type including the generics parameter to work around this problem.
+
+ When passing classes to the annotation, these classes do not need to be supertypes of the field. See the example. +
+ @Delegate
cannot be used on static fields or methods.
+
+ @Delegate
cannot be used when the calculated type(s) to delegate / exclude themselves contain @Delegate
annotations; in other words, @Delegate
will error if you attempt to use it recursively.
+
+ @ExtensionMethod
was introduced as experimental feature in lombok v0.11.2.
+
+ You can make a class containing a bunch of public
, static
methods which all take at least 1 parameter. These methods will extend the type of the first parameter, as if they were instance methods, using the @ExtensionMethod
feature.
+
+ For example, if you create public static String toTitleCase(String in) { ... }
, you can use the @ExtensionMethod
feature to make it look like the java.lang.String
class has a method named toTitleCase
, which has no arguments. The first argument of the static method fills the role of this
in instance methods.
+
+ All methods that are public
, static
, and have at least 1 argument whose type is not primitive, are considered extension methods, and each will be injected into the namespace of the type of the first parameter as if they were instance methods. As in the above example, a call that looks like: foo.toTitleCase()
is replaced with ClassContainingYourExtensionMethod.toTitleCase(foo);
. Note that it is actually not an instant NullPointerException
if foo
is null - it is passed like any other parameter.
+
+ You can pass any number of classes to the @ExtensionMethod
annotation; they will all be searched for extension methods. These extension methods apply for any code that is in the annotated class.
+
+ Lombok does not (currently) have any runtime dependencies which means lombok does not (currently) ship with any useful extension methods so you'll have to make your own. However, here's one that might spark your imagination:
+
public class ObjectExtensions { + public static <T> or(T object, T ifNull) { + return object != null ? object : ifNull; + } +}
@ExtensionMethod(ObjectExtensions.class)
to your class definition, you can write:String x = null; +System.out.println(x.or("Hello, World!"));
NullPointerException
; it will actually output Hello, World!
+
+ @f.overview>
+
+ <@f.snippets name="experimental/ExtensionMethod" />
+
+ <@f.confKeys>
+ lombok.extensionMethod.flagUsage
= [warning
| error
] (default: not set)
+ @ExtensionMethod
as a warning or error if configured.
+ + Calls are rewritten to a call to the extension method; the static method itself is not inlined. Therefore, the extension method must be present both at compile and at runtime. +
+ Generics is fully applied to figure out extension methods. i.e. if the first parameter of your extension method is List<? extends String>
, then any expression that is compatible with that will have your extension method, but other kinds of lists won't. So, a List<Object>
won't get it, but a List<String>
will.
+
+ @FieldDefaults was introduced as experimental feature in lombok v0.11.4. +
+ @f.history> + + <@f.experimental> +
+ The @FieldDefaults
annotation can add an access modifier (public
, private
, or protected
) to each field in the annotated class or enum. It can also add final
to each field in the annotated class or enum.
+
+ To add final
to each field, use @FieldDefaults(makeFinal=true)
. Any non-final field which must remain nonfinal can be annotated with @NonFinal
(also in the lombok.experimental
package).
+
+ To add an access modifier to each field, use @FieldDefaults(level=AccessLevel.PRIVATE)
. Any field that does not already have an access modifier (i.e. any field that looks like package private access) is changed to have the appropriate access modifier. Any package private field which must remain package private can be annotated with @PackagePrivate
(also in the lombok.experimental
package).
+
lombok.fieldDefaults.flagUsage
= [warning
| error
] (default: not set)
+ @FieldDefaults
as a warning or error if configured.
+
+ Like other lombok handlers that touch fields, any field whose name starts with a dollar ($
) symbol is skipped entirely. Such a field will not be modified at all.
+
+ @Helper
was introduced as an experimental feature in lombok v1.16.6.
+
+ This annotation lets you put methods in methods. You might not know this, but you can declare classes inside methods, and the methods in this class can access any (effectively) final local variable or parameter defined and set before the declaration. Unfortunately, to actually call any methods you'd have to make an instance of this method local class first, but that's where @Helper
comes in and helps you out! Annotate a method local class with @Helper
and it's as if all the methods in that helper class are methods that you can call directly, just as if java had allowed methods to exist inside methods.
+
+ Normally you'd have to declare an instance of your helper, for example: HelperClass h = new HelperClass();
directly after declaring your helper class, and then call methods in your helper class with h.helperMethod();
. With @Helper
, both of these things are no longer needed: You do not need to waste a line of code declaring an instance of the helper, and you don't need to prefix all your calls to helper methods with nameOfHelperInstance.
+
lombok.helper.flagUsage
= [warning
| error
] (default: not set)
+ @Helper
as a warning or error if configured.
+
+ @Helper
requires that the helper class has a no-args constructor. A compiler error will be generated if this is not the case.
+
+ Currently, the instance of your helper that's made under the hood is called $Foo
, where Foo
is the name of your helper. We might change this in the future; please don't rely on this variable existing. We might even replace this later with a sibling method instead.
+
+ Please don't rely on this
making any sense in the helper method code. You can refer to the real 'this' by using the syntax NameOfMyClass.this
.
+
+ ANY unqualified method call in code that exists below the declaration of the helper method with the same name as any method in the helper is assumed to be a call to the helper. If the arguments don't end up being compatible, you get a compiler error. +
+ Unless you're using JDK8 or higher (which introduced the concept of 'effectively final'), you'll have to declare local variables and parameters as final
if you wish to refer to them in your method local class. This is a java limitation, not something specific to lombok's @Helper
.
+
+ @UtilityClass
was introduced as an experimental feature in lombok v1.16.2.
+
+ A utility class is a class that is just a namespace for functions. No instances of it can exist, and all its members are static. For example, java.lang.Math
and java.util.Collections
are well known utility classes. This annotation automatically turns the annotated class into one.
+
+ A utility class cannot be instantiated. By marking your class with @UtilityClass
, lombok will automatically generate a private constructor that throws an exception, flags as error any explicit constructors you add, and marks the class final
. If the class is an inner class, the class is also marked static
.
+
+ All members of a utility class are automatically marked as static
. Even fields and inner classes.
+
lombok.utilityClass.flagUsage
= [warning
| error
] (default: not set)
+ @UtilityClass
as a warning or error if configured.
+
+ There isn't currently any way to create non-static members, or to define your own constructor. If you want to instantiate the utility class, even only as an internal implementation detail, @UtilityClass
cannot be used.
+
+ @Wither was introduced as experimental feature in lombok v0.11.4. +
+ @f.history> + + <@f.experimental> +@Wither
is an appropriate name for this feature.
+
+ The next best alternative to a setter for an immutable property is to construct a clone of the object, but with a new value for this one field. A method to generate this clone is precisely what @Wither
generates: a withFieldName(newValue)
method which produces a clone except for the new value for the associated field.
+
+ For example, if you create public class Point { private final int x, y; }
, setters make no sense because the fields are final. @Wither
can generate a withX(int newXValue)
method for you which will return a new point with the supplied value for x
and the same value for y
.
+
+ Like @Setter
, you can specify an access level in case you want the generated wither to be something other than public
:
@Wither(level = AccessLevel.PROTECTED)
. Also like @Setter
, you can also put a @Wither
annotation on a type, which means a 'wither' is generated for each field (even non-final fields).
+
+ To put annotations on the generated method, you can use onMethod=@__({@AnnotationsHere})
; to put annotations on the only parameter of a generated wither method, you can use onParam=@__({@AnnotationsHere})
. Be careful though! This is an experimental feature. For more details see the documentation on the onX feature.
+
+ NEW in lombok v1.12.0: javadoc on the field will now be copied to generated withers. Normally, all text is copied, and @param
is moved to the wither, whilst @return
lines are stripped from the wither's javadoc. Moved means: Deleted from the field's javadoc. It is also possible to define unique text for the wither's javadoc. To do that, you create a 'section' named WITHER
. A section is a line in your javadoc containing 2 or more dashes, then the text 'WITHER', followed by 2 or more dashes, and nothing else on the line. If you use sections, @return
and @param
stripping / copying for that section is no longer done (move the @param
line into the section).
+
lombok.wither.flagUsage
= [warning
| error
] (default: not set)
+ @Wither
as a warning or error if configured.
+ + Withers cannot be generated for static fields because that makes no sense. +
+ Withers can be generated for abstract classes, but this generates an abstract method with the appropriate signature. +
+ When applying @Wither
to a type, static fields and fields whose name start with a $ are skipped.
+
+ For generating the method names, the first character of the field, if it is a lowercase character, is title-cased, otherwise, it is left unmodified. Then, with
is prefixed.
+
+ No method is generated if any method already exists with the same name (case insensitive) and same parameter count. For example, withX(int x)
will not be generated if there's already a method withX(String... x)
even though it is technically possible to make the method. This caveat exists to prevent confusion. If the generation of a method is skipped for this reason, a warning is emitted instead. Varargs count as 0 to N parameters.
+
+ For boolean
fields that start with is
immediately followed by a title-case letter, nothing is prefixed to generate the wither name.
+
+ Any annotations named @NonNull
(case insensitive) on the field are interpreted as: This field must not ever hold null. Therefore, these annotations result in an explicit null check in the generated wither. Also, these annotations (as well as any annotation named @Nullable
or @CheckForNull
) are copied to wither parameter.
+
+ Experimental features are available in your normal lombok installation, but are not as robustly supported as lombok's main features. In particular, experimental features: +
+ Features that receive positive community feedback and which seem to produce clean, flexible code will eventually become accepted as a core feature and move out of the experimental package. +
+lombok.experimental.flagUsage
= [warning
| error
] (default: not set)
+ @Value
has proven its value and has been moved to the main package.
+ @main.feature>
+ <@main.feature title="@Builder: promoted" code="/features/Builder">
+ @Builder
is a solid base to build APIs on, and has been moved to the main package.
+ @main.feature>
+ + onX was introduced as experimental feature in lombok v0.11.8. +
+ @f.history> + + <@f.experimental> ++ This feature is considered 'workaround status' - it exists in order to allow users of lombok that cannot work without this feature to have access to it anyway. If we find a better way to implement this feature, or some future java version introduces an alternative strategy, this feature can disappear without a reasonable deprecation period. Also, this feature may not work in future versions of javac. Use at your own discretion. +
+ Most annotations that make lombok generate methods or constructors can be configured to also make lombok put custom annotations on elements in the generated code. +
+ @Getter
, @Setter
, and @Wither
support the onMethod
option, which will put the listed annotations on the generated method.
+
+ @AllArgsConstructor
, @NoArgsConstructor
, and @RequiredArgsConstructor
support the onConstructor
option which will put the listed annotations on the generated constructor.
+
+ @Setter
and @Wither
support onParam
in addition to onMethod
; annotations listed will be put on the only parameter that the generated method has. @EqualsAndHashCode
also supports onParam
; the listed annotation(s) will be placed on the single parameter of the generated equals
method, as well as any generated canEqual
method.
+
+ The syntax is a little strange; to use any of the 3 onX
features, you must wrap the annotations to be applied to the constructor / method / parameter in @__(@AnnotationGoesHere)
. To apply multiple annotations, use @__({@Annotation1, @Annotation2})
. The annotations can themselves obviously have parameters as well.
+
lombok.onX.flagUsage
= [warning
| error
] (default: not set)
+ onX
as a warning or error if configured.
+
+ The reason of the weird syntax is to make this feature work in javac 7 compilers; the @__
type is an annotation reference to the annotation type __
(double underscore) which doesn't actually exist; this makes javac 7 delay aborting the compilation process due to an error because it is possible an annotation processor will later create the __
type. Instead, lombok applies the annotations and removes the references so that the error will never actually occur. The point is: The __
type must not exist, otherwise the feature does not work. In the rare case that the __
type does exist (and is imported or in the package), you can simply add more underscores. Technically any non-existent type would work, but to maintain consistency and readability and catch erroneous use, lombok considers it an error if the 'wrapper' annotation is anything but a series of underscores.
+
+ To reiterate: This feature can disappear at any time; if you use this feature, be prepared to adjust your code when we find a nicer way of implementing this feature, or, if a future version of javac forces us to remove this feature entirely with no alternative. +
+ The onX
parameter is not legal on any type-wide variant. For example, a @Getter
annotation on a class does not support onMethod
.
+
close()
methods safely with no hassle.
+ @main.feature>
+
+ <@main.feature title="@Getter/@Setter" code="getter-setter">
+ Never write public int getFoo() {return foo;}
again.
+ @main.feature>
+
+ <@main.feature title="@ToString" code="to-string">
+ No need to start a debugger to see your fields: Just let lombok generate a toString
for
+ you!
+ @main.feature>
+
+ <@main.feature title="@EqualsAndHashCode" code="equals-and-hashcode">
+ Equality made easy: Generates hashCode
and equals
implementations from the
+ fields of your object..
+ @main.feature>
+
+ <@main.feature title="@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor" code="constructor">
+ Constructors made to order: Generates constructors that take no arguments, one argument per final /
+ non-nullfield, or one argument for every field.
+ @main.feature>
+
+ <@main.feature title="@Data" code="data">
+ All together now: A shortcut for @ToString
, @EqualsAndHashCode
,
+ @Getter
on all fields, and @Setter
on all non-final fields, and
+ @RequiredArgsConstructor
!
+ @main.feature>
+
+ <@main.feature title="@Value" code="value">
+ Immutable classes made very easy.
+ @main.feature>
+
+ <@main.feature title="@Builder" code="builder">
+ ... and Bob's your uncle: No-hassle fancy-pants APIs for object creation!
+ @main.feature>
+
+ <@main.feature title="@SneakyThrows" code="sneaky-throws">
+ To boldly throw checked exceptions where no one has thrown them before!
+ @main.feature>
+
+ <@main.feature title="@Synchronized" code="sync">
+ synchronized
done right: Don't expose your locks.
+ @main.feature>
+
+ <@main.feature title="@Getter(lazy=true)" code="getter-lazy">
+ Laziness is a virtue!
+ @main.feature>
+
+ <@main.feature title="@Log" code="log">
+ Captain's Log, stardate 24435.7: "What was that line again?"
+ @main.feature>
+ @Getter
back into the actual getter. It then removes the annotation. This is useful for all sorts of reasons; you can check out what's happening under the hood, if the unthinkable happens and you want to stop using lombok, you can easily remove all traces of it in your source, and you can use delombok to preprocess your source files for source-level tools such as javadoc and GWT. More information about how to run delombok, including instructions for build tools can be found at the delombok page.
+
+ The various @Log
variants were added in lombok v0.10.
+ NEW in lombok 0.10: You can annotate any class with a log annotation to let lombok generate a logger field.
+ The logger is named log
and the field's type depends on which logger you have selected.
+
+ You put the variant of @Log
on your class (whichever one applies to the logging system you use); you then have a static final log
field, initialized to the name of your class, which you can then use to write log statements.
+
+ There are six choices available:
+
@CommonsLog
+ private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
+ @Log
+ private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
+ @Log4j
+ private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);
+ @Log4j2
+ private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
+ @Slf4j
+ private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
+ @XSlf4j
+ private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
+
+ By default, the topic (or name) of the logger will be the class name of the class annotated with the @Log
annotation. This can be customised by specifying the topic
parameter. For example: @XSlf4j(topic="reporting")
.
+
lombok.log.fieldName
= an identifier (default: log
).
+ log
', but you can change it to a different name with this setting.
+ lombok.log.fieldIsStatic
= [true
| false
] (default: true)
+ static
field. By setting this key to false
, the generated field will be an instance field instead.
+ lombok.log.flagUsage
= [warning
| error
] (default: not set)
+ lombok.log.apacheCommons.flagUsage
= [warning
| error
] (default: not set)
+ @lombok.extern.apachecommons.CommonsLog
as a warning or error if configured.
+ lombok.log.javaUtilLogging.flagUsage
= [warning
| error
] (default: not set)
+ @lombok.extern.java.Log
as a warning or error if configured.
+ lombok.log.log4j.flagUsage
= [warning
| error
] (default: not set)
+ @lombok.extern.log4j.Log4j
as a warning or error if configured.
+ lombok.log.log4j2.flagUsage
= [warning
| error
] (default: not set)
+ @lombok.extern.log4j.Log4j2
as a warning or error if configured.
+ lombok.log.slf4j.flagUsage
= [warning
| error
] (default: not set)
+ @lombok.extern.slf4j.Slf4j
as a warning or error if configured.
+ lombok.log.xslf4j.flagUsage
= [warning
| error
] (default: not set)
+ @lombok.extern.slf4j.XSlf4j
as a warning or error if configured.
+
+ If a field called log
already exists, a warning will be emitted and no code will be generated.
+
+ A future feature of lombok's diverse log annotations is to find calls to the logger field and, if the chosen logging framework supports it and the log level can be compile-time determined from the log call, guard it with an if
statement. This way if the log statement ends up being ignored, the potentially expensive calculation of the log string is avoided entirely. This does mean that you should NOT put any side-effects in the expression that you log.
+
+ NEW in Lombok 0.10: You can use val
as the type of a local variable declaration instead of actually writing the type. When you do this, the type will be inferred from the initializer expression. The local variable will also be made final. This feature works on local variables and on foreach loops only, not on fields. The initializer expression is required.
+
+ val
is actually a 'type' of sorts, and exists as a real class in the lombok
package. You must import it for val to work (or use lombok.val
as the type). The existence of this type on a local variable declaration triggers both the adding of the final
keyword as well as copying the type of the initializing expression which overwrites the 'fake' val
type.
+
+ WARNING: This feature does not currently work in NetBeans. +
+ @f.overview> + + <@f.snippets name="val" /> + + <@f.confKeys> +lombok.val.flagUsage
= [warning
| error
] (default: not set)
+ val
as a warning or error if configured.
+
+ For compound types, the most common superclass is inferred, not any shared interfaces. For example, bool ? new HashSet() : new ArrayList()
is an expression with a compound type: The result is both AbstractCollection
as well as Serializable
. The type inferred will be AbstractCollection
, as that is a class, whereas Serializable
is an interface.
+
+ In ambiguous cases, such as when the initializer expression is null
, java.lang.Object
is inferred.
+
+ @Value
was introduced as experimental feature in lombok v0.11.4.
+
+ @Value
no longer implies @Wither
since lombok v0.11.8.
+
+ @Value
promoted to the main lombok
package since lombok v0.12.0.
+
+ @Value
is the immutable variant of @Data
; all fields are made private
and final
by default, and setters are not generated. The class itself is also made final
by default, because immutability is not something that can be forced onto a subclass. Like @Data
, useful toString()
, equals()
and hashCode()
methods are also generated, each field gets a getter method, and a constructor that covers every argument (except final
fields that are initialized in the field declaration) is also generated.
+
+ In practice, @Value
is shorthand for: final @ToString @EqualsAndHashCode @AllArgsConstructor @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @Getter
, except that explicitly including an implementation of any of the relevant methods simply means that part won't be generated and no warning will be emitted. For example, if you write your own toString
, no error occurs, and lombok will not generate a toString
. Also, any explicit constructor, no matter the arguments list, implies lombok will not generate a constructor. If you do want lombok to generate the all-args constructor, add @AllArgsConstructor
to the class. You can mark any constructor or method with @lombok.experimental.Tolerate
to hide them from lombok.
+
+ It is possible to override the final-by-default and private-by-default behaviour using either an explicit access level on a field, or by using the @NonFinal
or @PackagePrivate
annotations.
+ It is possible to override any default behaviour for any of the 'parts' that make up @Value
by explicitly using that annotation.
+
lombok.value.flagUsage
= [warning
| error
] (default: not set)
+ @Value
as a warning or error if configured.
+ lombok.val.flagUsage
= [warning
| error
] (default: not set)
+ val
as a warning or error if configured.
+
+ Look for the documentation on the 'parts' of @Value
: @ToString
, @EqualsAndHashCode
, @AllArgsConstructor
, @FieldDefaults
, and @Getter
.
+
+ For classes with generics, it's useful to have a static method which serves as a constructor, because inference of generic parameters via static methods works in java6 and avoids having to use the diamond operator. While you can force this by applying an explicit @AllArgsConstructor(staticConstructor="of")
annotation, there's also the @Value(staticConstructor="of")
feature, which will make the generated all-arguments constructor private, and generates a public static method named of
which is a wrapper around this private constructor.
+
+ @Value
was an experimental feature from v0.11.4 to v0.11.9 (as @lombok.experimental.Value
). It has since been moved into the core package. The old annotation is still around (and is an alias). It will eventually be removed in a future version, though.
+
+ It is not possible to use @FieldDefaults
to 'undo' the private-by-default and final-by-default aspect of fields in the annotated class. Use @NonFinal
and @PackagePrivate
on the fields in the class to override this behaviour.
+