From 599b6aab677439ae1bdea2cdca3233d0b763fd3f Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Mon, 17 Oct 2016 23:09:21 +0200 Subject: Updated just about all of the pages to the template-based redesign. Added ajaxified loading for feature pages. --- website2/templates/features/EqualsAndHashCode.html | 52 ++++++++ website2/templates/features/GetterLazy.html | 31 +++++ website2/templates/features/GetterSetter.html | 70 ++++++++++ website2/templates/features/NonNull.html | 43 +++++++ website2/templates/features/SneakyThrows.html | 44 +++++++ website2/templates/features/Synchronized.html | 34 +++++ website2/templates/features/ToString.html | 54 ++++++++ website2/templates/features/_features.html | 80 ++++++++++++ website2/templates/features/builder.html | 142 +++++++++++++++++++++ website2/templates/features/cleanup.html | 35 +++++ website2/templates/features/configuration.html | 93 ++++++++++++++ website2/templates/features/constructor.html | 57 +++++++++ website2/templates/features/data.html | 41 ++++++ website2/templates/features/delombok.html | 61 +++++++++ .../templates/features/experimental/Accessors.html | 75 +++++++++++ .../templates/features/experimental/Delegate.html | 59 +++++++++ .../features/experimental/ExtensionMethod.html | 67 ++++++++++ .../features/experimental/FieldDefaults.html | 48 +++++++ .../templates/features/experimental/Helper.html | 52 ++++++++ .../features/experimental/UtilityClass.html | 42 ++++++ .../templates/features/experimental/Wither.html | 66 ++++++++++ .../templates/features/experimental/index.html | 81 ++++++++++++ website2/templates/features/experimental/onX.html | 57 +++++++++ website2/templates/features/index.html | 87 +++++++++++++ website2/templates/features/log.html | 98 ++++++++++++++ website2/templates/features/val.html | 31 +++++ website2/templates/features/value.html | 50 ++++++++ 27 files changed, 1650 insertions(+) create mode 100644 website2/templates/features/EqualsAndHashCode.html create mode 100644 website2/templates/features/GetterLazy.html create mode 100644 website2/templates/features/GetterSetter.html create mode 100644 website2/templates/features/NonNull.html create mode 100644 website2/templates/features/SneakyThrows.html create mode 100644 website2/templates/features/Synchronized.html create mode 100644 website2/templates/features/ToString.html create mode 100644 website2/templates/features/_features.html create mode 100644 website2/templates/features/builder.html create mode 100644 website2/templates/features/cleanup.html create mode 100644 website2/templates/features/configuration.html create mode 100644 website2/templates/features/constructor.html create mode 100644 website2/templates/features/data.html create mode 100644 website2/templates/features/delombok.html create mode 100644 website2/templates/features/experimental/Accessors.html create mode 100644 website2/templates/features/experimental/Delegate.html create mode 100644 website2/templates/features/experimental/ExtensionMethod.html create mode 100644 website2/templates/features/experimental/FieldDefaults.html create mode 100644 website2/templates/features/experimental/Helper.html create mode 100644 website2/templates/features/experimental/UtilityClass.html create mode 100644 website2/templates/features/experimental/Wither.html create mode 100644 website2/templates/features/experimental/index.html create mode 100644 website2/templates/features/experimental/onX.html create mode 100644 website2/templates/features/index.html create mode 100644 website2/templates/features/log.html create mode 100644 website2/templates/features/val.html create mode 100644 website2/templates/features/value.html (limited to 'website2/templates/features') diff --git a/website2/templates/features/EqualsAndHashCode.html b/website2/templates/features/EqualsAndHashCode.html new file mode 100644 index 00000000..91a9cb70 --- /dev/null +++ b/website2/templates/features/EqualsAndHashCode.html @@ -0,0 +1,52 @@ +<#import "_features.html" as f> + +<@f.scaffold title="@EqualsAndHashCode" logline="Equality made easy: Generates hashCode and equals implementations from the fields of your object."> + <@f.overview> +

+ Any class definition may be annotated with @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. +

+ By setting 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.
+

+ Setting 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. +

+ NEW in Lombok 0.10: Unless your class is 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. +

+ NEW in Lombok 1.14.0: To put annotations on the 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. +

+ + + <@f.snippets name="EqualsAndHashCode" /> + + <@f.confKeys> +
+ lombok.equalsAndHashCode.doNotUseGetters = [true | false] (default: false) +
+ If set to 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) +
+ Lombok will flag any usage of @EqualsAndHashCode as a warning or error if configured. +
+ + + <@f.smallPrint> +

+ Arrays are 'deep' compared/hashCoded, which means that arrays that contain themselves will result in StackOverflowErrors. However, this behaviour is no different from e.g. ArrayList. +

+ 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 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. +

+ If there is any method named either 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. +

+ 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 exclude and of generates a warning; the exclude parameter will be ignored in that case. +

+ 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:
+ @EqualsAndHashCode(doNotUseGetters = true) +

+ + diff --git a/website2/templates/features/GetterLazy.html b/website2/templates/features/GetterLazy.html new file mode 100644 index 00000000..b1f374a8 --- /dev/null +++ b/website2/templates/features/GetterLazy.html @@ -0,0 +1,31 @@ +<#import "_features.html" as f> + +<@f.scaffold title="@Getter(lazy=true)" logline="Laziness is a virtue!"> + <@f.history> + @Getter(lazy=true) was introduced in Lombok v0.10. + + + <@f.overview> +

+ 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 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. +

+ + + <@f.snippets name="GetterLazy" /> + + <@f.confKeys> +
+ lombok.getter.lazy.flagUsage = [warning | error] (default: not set) +
+ Lombok will flag any usage of @Getter(lazy=true) as a warning or error if configured. +
+ + + <@f.smallPrint> +

+ 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 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! +

+ Other Lombok annotations such as @ToString always call the getter even if you use doNotUseGetters=true. +

+ + diff --git a/website2/templates/features/GetterSetter.html b/website2/templates/features/GetterSetter.html new file mode 100644 index 00000000..7ceaa3ba --- /dev/null +++ b/website2/templates/features/GetterSetter.html @@ -0,0 +1,70 @@ +<#import "_features.html" as f> + +<@f.scaffold title="@Getter and @Setter" logline="Never write public int getFoo() {return foo;} again."> + <@f.overview> +

+ You can annotate any field with @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. +

+ The generated getter/setter method will be public unless you explicitly specify an AccessLevel, as shown in the example below. Legal access levels are PUBLIC, PROTECTED, PACKAGE, and PRIVATE. +

+ You can also put a @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. +

+ You can always manually disable getter/setter generation for any field by using the special AccessLevel.NONE access level. This lets you override the behaviour of a @Getter, @Setter or @Data annotation on a class. +

+ To put annotations on the generated method, you can use 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. +

+ 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 @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). +

+ + + <@f.snippets name="GetterSetter" /> + + <@f.confKeys> +
+ lombok.accessors.chain = [true | false] (default: false) +
+ If set to 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) +
+ If set to 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) +
+ This is a list property; entries can be added with the += 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) +
+ If set to 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) +
+ Lombok will flag any usage of @Setter as a warning or error if configured. +
+ lombok.getter.flagUsage = [warning | error] (default: not set) +
+ Lombok will flag any usage of @Getter as a warning or error if configured. +
+ + + <@f.smallPrint> +

+ 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, 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. +

+ For boolean fields that start with is immediately followed by a title-case letter, nothing is prefixed to generate the getter name. +

+ Any variation on 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. +

+ 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 setter. Also, these annotations (as well as any annotation named @Nullable or @CheckForNull) are copied to setter parameter and getter method. +

+ You can annotate a class with a @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. +

+ Using the 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. +

+ + diff --git a/website2/templates/features/NonNull.html b/website2/templates/features/NonNull.html new file mode 100644 index 00000000..60879085 --- /dev/null +++ b/website2/templates/features/NonNull.html @@ -0,0 +1,43 @@ +<#import "_features.html" as f> + +<@f.scaffold title="@NonNull" logline="or: How I learned to stop worrying and love the NullPointerException."> + <@f.history> + @NonNull was introduced in lombok v0.11.10. + + + <@f.overview> +

+ You can use @NonNull on the parameter of a method or constructor to have lombok generate a null-check statement for you. +

+ Lombok has always treated any annotation named @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. +

+ The null-check looks like 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. +

+ If a null-check is already present at the top, no additional null-check will be generated. +

+ + + <@f.snippets name="NonNull" /> + + <@f.confKeys> +
+ lombok.nonNull.exceptionType = [NullPointerException | IllegalArgumentException] (default: NullPointerException). +
+ When lombok generates a null-check 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) +
+ Lombok will flag any usage of @NonNull as a warning or error if configured. +
+ + + <@f.smallPrint> +

+ 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 PARAMNAME == null. The first statement in your method that is not such a null-check stops the process of inspecting for null-checks. +

+ While @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. +

+ A @NonNull on a primitive parameter results in a warning. No null-check will be generated. +

+ + diff --git a/website2/templates/features/SneakyThrows.html b/website2/templates/features/SneakyThrows.html new file mode 100644 index 00000000..5a2d5bbd --- /dev/null +++ b/website2/templates/features/SneakyThrows.html @@ -0,0 +1,44 @@ +<#import "_features.html" as f> + +<@f.scaffold title="@SneakyThrows" logline="To boldly throw checked exceptions where no one has thrown them before!"> + <@f.overview> +

+ @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. +

+ Common use cases for when you want to opt out of the checked exception mechanism center around 2 situations:
+

+

+ 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. +

+ + + <@f.snippets name="SneakyThrows" /> + + <@f.confKeys> +
+ lombok.sneakyThrows.flagUsage = [warning | error] (default: not set) +
+ Lombok will flag any usage of @SneakyThrows as a warning or error if configured. +
+ + + <@f.smallPrint> +

+ 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. +

+ + diff --git a/website2/templates/features/Synchronized.html b/website2/templates/features/Synchronized.html new file mode 100644 index 00000000..113add0e --- /dev/null +++ b/website2/templates/features/Synchronized.html @@ -0,0 +1,34 @@ +<#import "_features.html" as f> + +<@f.scaffold title="@Synchronized" logline="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. +

+ + + <@f.snippets name="Synchronized" /> + + <@f.confKeys> +
+ lombok.synchronized.flagUsage = [warning | error] (default: not set) +
+ Lombok will flag any usage of @Synchronized as a warning or error if configured. +
+ + + <@f.smallPrint> +

+ 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! +

+ + 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 a toString 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. +

+ + + <@f.snippets name="ToString" /> + + <@f.confKeys> +
+ lombok.toString.includeFieldNames = [true | false] (default: true) +
+ Normally lombok generates a fragment of the toString response for each field in the form of 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) +
+ If set to 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) +
+ Lombok will flag any usage of @ToString as a warning or error if configured. +
+ + + <@f.smallPrint> +

+ 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 StackOverflowErrors. 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. +

+ + diff --git a/website2/templates/features/_features.html b/website2/templates/features/_features.html new file mode 100644 index 00000000..bcfdee63 --- /dev/null +++ b/website2/templates/features/_features.html @@ -0,0 +1,80 @@ +<#import "/_scaffold.html" as main> + +<#macro featureSection> +
+ <#nested> +
+ + +<#macro history> +
+ <#nested> +
+ + +<#macro overview> +
+

Overview

+ <#nested> +
+ + +<#macro experimental> +
+

Experimental

+ + Experimental because: + <#nested> +
+ + +<#macro snippets name> +
+
+

With Lombok

+ +
${usages.pre(name)?no_esc}
+
+
+
+

Vanilla Java

+ +
${usages.post(name)?no_esc}
+
+
+ + +<#macro confKeys> +
+

Supported configuration keys:

+
+ <#nested> +
+
+ + +<#macro smallPrint> +
+

Small print

+ +
+ <#nested> +
+
+ + +<#macro scaffold title logline load=[]> + <#assign load2=load + ["/js/history.js"]> + <@main.scaffold load2> + + + diff --git a/website2/templates/features/builder.html b/website2/templates/features/builder.html new file mode 100644 index 00000000..6da47d15 --- /dev/null +++ b/website2/templates/features/builder.html @@ -0,0 +1,142 @@ +<#import "_features.html" as f> + +<@f.scaffold title="@Builder" logline="... and Bob's your uncle: No-hassle fancy-pants APIs for object creation!"> + <@f.history> +

+ @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. +

+ + + <@f.overview> +

+ 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: +

+ Each listed generated element will be silently skipped if that element already exists (disregarding parameter counts and looking only at names). This includes the builder itself: If that class already exists, lombok will simply start injecting fields and methods inside this already existing class, unless of course the fields / methods to be injected already exist. You may not put any other method (or constructor) generating lombok annotation on a builder class though; for example, you can not put @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: +

+ Example usage where all options are changed from their defaults:
+ @Builder(builderClassName = "HelloWorldBuilder", buildMethodName = "execute", builderMethodName = "helloWorld")
+

+ + + <@f.featureSection> +

@Singular

+ +

+ 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: +

+

+ @Singular can only be applied to collection types known to lombok. Currently, the supported types are: +

+

+ 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. +

+ + + <@f.snippets name="Builder" /> + + <@f.confKeys> +
+ lombok.builder.flagUsage = [warning | error] (default: not set) +
+ Lombok will flag any usage of @Builder as a warning or error if configured. +
+ lombok.singular.useGuava = [true | false] (default: false) +
+ If 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) +
+ If 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). +
+ + + <@f.smallPrint> +

+ @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. +

+ + diff --git a/website2/templates/features/cleanup.html b/website2/templates/features/cleanup.html new file mode 100644 index 00000000..e868c40d --- /dev/null +++ b/website2/templates/features/cleanup.html @@ -0,0 +1,35 @@ +<#import "_features.html" as f> + +<@f.scaffold title="@Cleanup" logline="Automatic resource management: Call your 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. +

+ + + <@f.snippets name="Cleanup" /> + + <@f.confKeys> +
+ lombok.cleanup.flagUsage = [warning | error] (default: not set) +
+ Lombok will flag any usage of @Cleanup as a warning or error if configured. + + + + <@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! +

+ + 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.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 +
+ The output of the config tool is itself a valid lombok.config file.
+ The config tool can also be used to display the complete lombok configuration used for any given directory or source file by supplying these as arguments. +

+ 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 +
+ If set to true, generated setters will 'chain' by default (They will return this instead of having a void return type). +
+ lombok.accessors.fluent +
+ If set to true, generated setters and getters will simply be named the same as the field name, without a get or set prefix. +
+ lombok.anyConstructor.suppressConstructorProperties +
+ If 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 +
+ The name of the generated log field (default: log). +
+ lombok.(featureName).flagUsage +
+ Allows you to forcibly stop or discourage use of a lombok feature. Legal values for this key are 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 +
+ and in /Users/me/projects/MyProject/lombok.config you have: +
+ lombok.log.fieldName = xyzzy +
+ Then the various @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. +

+ + + <@f.featureSection> +

Global config keys

+ +

+ To stop lombok from looking at parent directories for more configuration files, the special key: +

+ config.stopBubbling = true +
+ can be included. We suggest you put this in the root of your workspace directory. +

+ 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 +
+

+ + diff --git a/website2/templates/features/constructor.html b/website2/templates/features/constructor.html new file mode 100644 index 00000000..241926c0 --- /dev/null +++ b/website2/templates/features/constructor.html @@ -0,0 +1,57 @@ +<#import "_features.html" as f> + +<@f.scaffold title="@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor" + logline="Constructors made to order: Generates constructors that take no arguments, one argument per final / non-null field, or one argument for every field."> + + <@f.overview> +

+ 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.snippets name="Constructor" /> + + <@f.confKeys> +
+ lombok.anyConstructor.suppressConstructorProperties = [true | false] (default: false