aboutsummaryrefslogtreecommitdiff
path: root/website/templates/features/experimental/SuperBuilder.html
blob: 5676b60c97b74834d770993416a5666253b09410 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<#import "../_features.html" as f>

<@f.scaffold title="@SuperBuilder" logline="Bob now knows his ancestors: Builders with fields from superclasses, too. ">
	<@f.history>
		<p>
			<code>@SuperBuilder</code> was introduced as experimental feature in lombok v1.18.2.
		</p><p>
			<code>@SuperBuilder</code>'s <code>toBuilder</code> feature and limited support for customization was added with lombok v1.18.4.
		</p>
	</@f.history>
	
	<@f.overview>
		<p>
			The <code>@SuperBuilder</code> annotation produces complex builder APIs for your classes.
			In contrast to <a href="/features/Builder"><code>@Builder</code></a>, <code>@SuperBuilder</code> also works with fields from superclasses.
			However, it only works for types, and customization possibilities are limited.
			Most importantly, it requires that <em>all superclasses</em> also have the <code>@SuperBuilder</code> annotation.
		</p><p>
			<code>@SuperBuilder</code> lets you automatically produce the code required to have your class be instantiable with code such as:<br />
			<code>Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build();</code>
		</p><p>
			<code>@SuperBuilder</code> can generate so-called 'singular' methods for collection parameters/fields. For details, see <a href="/features/Builder#singular">the <code>@Singular</code> documentation in <code>@Builder</code></a>.
		</p><p>
			<code>@SuperBuilder</code> generates a private constructor on the class that takes a builder instance as a parameter. This constructor sets the fields of the new instance to the values from the builder.
		</p><p>
			<code>@SuperBuilder</code> is not compatible with <code>@Builder</code>.
		</p><p>
			You can use <code>@SuperBuilder(toBuilder = true)</code> to also generate an instance method in your class called <code>toBuilder()</code>; it creates a new builder that starts out with all the values of this instance.
			Using <code>toBuilder</code> requires that all superclasses also have <code>toBuilder = true</code>.
			You can put the <code>@Builder.ObtainVia</code> annotation on the fields to indicate alternative means by which the value for that field/parameter is obtained from this instance.
			For example, you can specify a method to be invoked: <code>@Builder.ObtainVia(method = "calculateFoo")</code>.
		</p><p>
			To ensure type-safety, <code>@SuperBuilder</code> generates two inner builder classes for each annotated class, one abstract and one concrete class named <code><em>Foobar</em>Builder</code> and <code><em>Foobar</em>BuilderImpl</code> (where <em>Foobar</em> is the name of the annotated class).
		</p><p>
			Customizing the code generated by <code>@SuperBuilder</code> is limited to adding new methods or annotations to the builder classes, and providing custom implementations of <code>builder()</code> and <code>build()</code>.
			You have to make sure that the builder class declaration headers match those that would have been generated by lombok. Due to the heavy generics usage, we strongly advice to copy the builder class definition header from the uncustomized delomboked code.  
		</p><p>
			The configurable aspects of builder are:
			<ul>
				<li>
					The <em>build()</em> method's name (default: <code>"build"</code>)
				</li><li>
					The <em>builder()</em> method's name (default: <code>"builder"</code>)
				</li><li>
					If you want <code>toBuilder()</code> (default: no)
				</li>
			</ul>
			Example usage where all options are changed from their defaults:<br />
			<code>@SuperBuilder(buildMethodName = "execute", builderMethodName = "helloWorld", toBuilder = true)</code><br />
		</p>
	</@f.overview>
	
	<@f.confKeys>
		<dt>
			<code>lombok.builder.className</code> = [a java identifier with an optional star to indicate where the return type name goes] (default: <code>*Builder</code>)
		</dt><dd>
			This is the name of the generated builder class; any star in the name is replaced with the relevant return type. Note that the parent class must also have the same setting (the entire type hierarchy annoated with <code>@SuperBuilder</code> needs the same setting).
		</dd><dt>
			<code>lombok.superBuilder.flagUsage</code> = [<code>warning</code> | <code>error</code>] (default: not set)
		</dt><dd>
			Lombok will flag any usage of <code>@SuperBuilder</code> as a warning or error if configured.
		</dd><dt>
			<code>lombok.singular.useGuava</code> = [<code>true</code> | <code>false</code>] (default: false)
		</dt><dd>
			If <code>true</code>, lombok will use guava's <code>ImmutableXxx</code> builders and types to implement <code>java.util</code> collection interfaces, instead of creating implementations based on <code>Collections.unmodifiableXxx</code>. 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 <code>ImmutableXxx</code> types.
		</dd><dt>
			<code>lombok.singular.auto</code> = [<code>true</code> | <code>false</code>] (default: true)
		</dt><dd>
			If <code>true</code> (which is the default), lombok automatically tries to singularize your identifier name by assuming that it is a common english plural. If <code>false</code>, 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).
		</dd>
	</@f.confKeys>

	<@f.smallPrint>
		<p>
			The generated builder code heavily relies on generics to avoid class casting when using the builder.
		</p><p>
			For remarks on <code>@Singular</code>, see <a href="/features/Builder#small-print">the <code>@Builder</code> documentation's</a> small print.
		</p><p>
			Various well known annotations about nullity cause null checks to be inserted and will be copied to parameter of the builder's 'setter' method. See <a href="/features/GetterSetter#small-print">Getter/Setter documentation's small print</a> for more information.
		</p>
	</@f.smallPrint>
</@f.scaffold>