aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buildScripts/website.ant.xml9
-rw-r--r--doc/changelog.markdown1
-rw-r--r--usage_examples/experimental/FieldDefaultsExample_post.jpage12
-rw-r--r--usage_examples/experimental/FieldDefaultsExample_pre.jpage18
-rw-r--r--usage_examples/experimental/ValueExample_post.jpage140
-rw-r--r--usage_examples/experimental/ValueExample_pre.jpage19
-rw-r--r--usage_examples/experimental/WitherExample_post.jpage21
-rw-r--r--usage_examples/experimental/WitherExample_pre.jpage14
-rw-r--r--website/features/experimental/ExtensionMethod.html2
-rw-r--r--website/features/experimental/FieldDefaults.html84
-rw-r--r--website/features/experimental/Value.html87
-rw-r--r--website/features/experimental/Wither.html100
-rw-r--r--website/features/experimental/index.html6
13 files changed, 512 insertions, 1 deletions
diff --git a/buildScripts/website.ant.xml b/buildScripts/website.ant.xml
index 0531129d..12cae011 100644
--- a/buildScripts/website.ant.xml
+++ b/buildScripts/website.ant.xml
@@ -151,6 +151,15 @@ such as converting the changelog into HTML, and creating javadoc.
<antcall target="-integrateSnippet">
<param name="transformationName" value="experimental/ExtensionMethod" />
</antcall>
+ <antcall target="-integrateSnippet">
+ <param name="transformationName" value="experimental/FieldDefaultsExample" />
+ </antcall>
+ <antcall target="-integrateSnippet">
+ <param name="transformationName" value="experimental/WitherExample" />
+ </antcall>
+ <antcall target="-integrateSnippet">
+ <param name="transformationName" value="experimental/ValueExample" />
+ </antcall>
</target>
<target name="-website-dist">
diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index bbda9dfe..4ff9b39f 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -2,6 +2,7 @@ Lombok Changelog
----------------
### v0.11.3 (Edgy Guinea Pig)
+* FEATURE: {Experimental} `@Value`, `@Wither` and `@FieldDefaults` are now available. These are a lot like `@Data` but geared towards immutable classes. [Documentation on @Value](http://projectlombok.org/features/experimental/Value.html), [Documentation on @Wither](http://projectlombok.org/features/experimental/Wither.html) and [Documentation on @FieldDefaults](http://projectlombok.org/features/experimental/FieldDefaults.html).
* BUGFIX: Eclipse would throw an OOME if using `@ExtensionMethod`. [Issue #390](http://code.google.com/p/projectlombok/issues/detail?id=390)
* BUGFIX: {Netbeans} `@Cleanup` and `@Synchronized` cause far fewer issues in the netbeans editor. [Issue #393](http://code.google.com/p/projectlombok/issues/detail?id=393)
* BUGFIX: {Installer} Erroneous messages about the installer complaining about needing root access when installing or removing lombok from eclipse installs has been fixed. The installer edge of this problem was actually already fixed in v0.11.2. [Issue #363](http://code.google.com/p/projectlombok/issues/detail?id=363)
diff --git a/usage_examples/experimental/FieldDefaultsExample_post.jpage b/usage_examples/experimental/FieldDefaultsExample_post.jpage
new file mode 100644
index 00000000..95c17a4b
--- /dev/null
+++ b/usage_examples/experimental/FieldDefaultsExample_post.jpage
@@ -0,0 +1,12 @@
+public class FieldDefaultsExample {
+ public final int a;
+ private final int b;
+ private int c;
+ final int d;
+
+ FieldDefaultsExample() {
+ a = 0;
+ b = 0;
+ d = 0;
+ }
+}
diff --git a/usage_examples/experimental/FieldDefaultsExample_pre.jpage b/usage_examples/experimental/FieldDefaultsExample_pre.jpage
new file mode 100644
index 00000000..a0a38f7a
--- /dev/null
+++ b/usage_examples/experimental/FieldDefaultsExample_pre.jpage
@@ -0,0 +1,18 @@
+import lombok.AccessLevel;
+import lombok.experimental.FieldDefaults;
+import lombok.experimental.NonFinal;
+import lombok.experimental.PackagePrivate;
+
+@FieldDefaults(makeFinal = true, level=AccessLevel.PRIVATE)
+public class FieldDefaultsExample {
+ public final int a;
+ int b;
+ @NonFinal int c;
+ @PackagePrivate int d;
+
+ FieldDefaultsExample() {
+ a = 0;
+ b = 0;
+ d = 0;
+ }
+}
diff --git a/usage_examples/experimental/ValueExample_post.jpage b/usage_examples/experimental/ValueExample_post.jpage
new file mode 100644
index 00000000..47de72a5
--- /dev/null
+++ b/usage_examples/experimental/ValueExample_post.jpage
@@ -0,0 +1,140 @@
+import java.util.Arrays;
+
+public final class ValueExample {
+ private final String name;
+ private int age;
+ private final double score;
+ protected final String[] tags;
+
+ @java.beans.ConstructorProperties({"name", "age", "score", "tags"})
+ public ValueExample(String name, int age, double score, String[] tags) {
+ this.name = name;
+ this.age = age;
+ this.score = score;
+ this.tags = tags;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public int getAge() {
+ return this.age;
+ }
+
+ public double getScore() {
+ return this.score;
+ }
+
+ public String[] getTags() {
+ return this.tags;
+ }
+
+ public ValueExample withName(String name) {
+ return this.name == name ? this : new ValueExample(name, age, score, tags);
+ }
+
+ public ValueExample withScore(double score) {
+ return this.score == score ? this : new ValueExample(name, age, score, tags);
+ }
+
+ public ValueExample withTags(String[] tags) {
+ return this.tags == tags ? this : new ValueExample(name, age, score, tags);
+ }
+
+ @java.lang.Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (!(o instanceof ValueExample)) return false;
+ final ValueExample other = (ValueExample)o;
+ final Object this$name = this.getName();
+ final Object other$name = other.getName();
+ if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
+ if (this.getAge() != other.getAge()) return false;
+ if (Double.compare(this.getScore(), other.getScore()) != 0) return false;
+ if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;
+ return true;
+ }
+
+ @java.lang.Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ final Object $name = this.getName();
+ result = result * PRIME + ($name == null ? 0 : $name.hashCode());
+ result = result * PRIME + this.getAge();
+ final long $score = Double.doubleToLongBits(this.getScore());
+ result = result * PRIME + (int)($score >>> 32 ^ $score);
+ result = result * PRIME + Arrays.deepHashCode(this.getTags());
+ return result;
+ }
+
+ @java.lang.Override
+ public String toString() {
+ return "ValueExample(name=" + getName() + ", age=" + getAge() + ", score=" + getScore() + ", tags=" + Arrays.deepToString(getTags()) + ")";
+ }
+
+ ValueExample withAge(int age) {
+ return this.age == age ? this : new ValueExample(name, age, score, tags);
+ }
+
+ public static final class Exercise<T> {
+ private final String name;
+ private final T value;
+
+ private Exercise(String name, T value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public static <T> Exercise<T> of(String name, T value) {
+ return new Exercise<T>(name, value);
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public T getValue() {
+ return this.value;
+ }
+
+ public Exercise<T> withName(String name) {
+ return this.name == name ? this : new Exercise<T>(name, value);
+ }
+
+ public Exercise<T> withValue(T value) {
+ return this.value == value ? this : new Exercise<T>(name, value);
+ }
+
+ @java.lang.Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (!(o instanceof ValueExample.Exercise)) return false;
+ final Exercise<?> other = (Exercise<?>)o;
+ final Object this$name = this.getName();
+ final Object other$name = other.getName();
+ if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
+ final Object this$value = this.getValue();
+ final Object other$value = other.getValue();
+ if (this$value == null ? other$value != null : !this$value.equals(other$value)) return false;
+ return true;
+ }
+
+ @java.lang.Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ final Object $name = this.getName();
+ result = result * PRIME + ($name == null ? 0 : $name.hashCode());
+ final Object $value = this.getValue();
+ result = result * PRIME + ($value == null ? 0 : $value.hashCode());
+ return result;
+ }
+
+ @java.lang.Override
+ public String toString() {
+ return "ValueExample.Exercise(name=" + getName() + ", value=" + getValue() + ")";
+ }
+ }
+} \ No newline at end of file
diff --git a/usage_examples/experimental/ValueExample_pre.jpage b/usage_examples/experimental/ValueExample_pre.jpage
new file mode 100644
index 00000000..d9550c25
--- /dev/null
+++ b/usage_examples/experimental/ValueExample_pre.jpage
@@ -0,0 +1,19 @@
+import lombok.AccessLevel;
+import lombok.experimental.NonFinal;
+import lombok.experimental.Value;
+import lombok.experimental.Wither;
+import lombok.ToString;
+
+@Value public class ValueExample {
+ String name;
+ @Wither(AccessLevel.PACKAGE) @NonFinal int age;
+ double score;
+ protected String[] tags;
+
+ @ToString(includeFieldNames=true)
+ @Value(staticConstructor="of")
+ public static class Exercise<T> {
+ String name;
+ T value;
+ }
+}
diff --git a/usage_examples/experimental/WitherExample_post.jpage b/usage_examples/experimental/WitherExample_post.jpage
new file mode 100644
index 00000000..bb5952af
--- /dev/null
+++ b/usage_examples/experimental/WitherExample_post.jpage
@@ -0,0 +1,21 @@
+import lombok.NonNull;
+
+public class WitherExample {
+ private final int age;
+ private @NonNull final String name;
+
+ public WitherExample(String name, int age) {
+ if (name == null) throw new NullPointerException();
+ this.name = name;
+ this.age = age;
+ }
+
+ public WitherExample withAge(int age) {
+ return this.age == age ? this : new WitherExample(age, name);
+ }
+
+ protected WitherExample withName(@NonNull String name) {
+ if (name == null) throw new java.lang.NullPointerException("name");
+ return this.name == name ? this : new WitherExample(age, name);
+ }
+} \ No newline at end of file
diff --git a/usage_examples/experimental/WitherExample_pre.jpage b/usage_examples/experimental/WitherExample_pre.jpage
new file mode 100644
index 00000000..5db799fc
--- /dev/null
+++ b/usage_examples/experimental/WitherExample_pre.jpage
@@ -0,0 +1,14 @@
+import lombok.AccessLevel;
+import lombok.NonNull;
+import lombok.experimental.Wither;
+
+public class WitherExample {
+ @Wither private final int age;
+ @Wither(AccessLevel.PROTECTED) @NonNull private final String name;
+
+ public WitherExample(String name, int age) {
+ if (name == null) throw new NullPointerException();
+ this.name = name;
+ this.age = age;
+ }
+}
diff --git a/website/features/experimental/ExtensionMethod.html b/website/features/experimental/ExtensionMethod.html
index 773904bb..0025d795 100644
--- a/website/features/experimental/ExtensionMethod.html
+++ b/website/features/experimental/ExtensionMethod.html
@@ -90,7 +90,7 @@ System.out.println(x.or("Hello, World!"));</pre>
</div>
</div>
<div class="footer">
- <a href="index.html">Back to experimental features</a> | <a href="Accessors.html">Previous feature (@Accessors)</a> | <span class="disabled">Next feature</a><br />
+ <a href="index.html">Back to experimental features</a> | <a href="Accessors.html">Previous feature (@Accessors)</a> | <a href="FieldDefaults.html">Next feature (@FieldDefaults)</a><br />
<a href="../../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009-2012 The Project Lombok Authors, licensed under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.</span>
</div>
<div style="clear: both;"></div>
diff --git a/website/features/experimental/FieldDefaults.html b/website/features/experimental/FieldDefaults.html
new file mode 100644
index 00000000..94c23a27
--- /dev/null
+++ b/website/features/experimental/FieldDefaults.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" type="text/css" href="../../logi/reset.css" />
+ <link rel="stylesheet" type="text/css" href="../features.css" />
+ <link rel="shortcut icon" href="../../favicon.ico" type="image/x-icon" />
+ <meta name="description" content="Spice up your java" />
+ <title>EXPERIMENTAL - @FieldDefaults</title>
+</head><body><div id="pepper">
+ <div class="minimumHeight"></div>
+ <div class="meat">
+ <div class="header"><a href="../../index.html">Project Lombok</a></div>
+ <h1>@FieldDefaults</h1>
+ <div class="byline">New default field modifiers for the 21st century.</div>
+ <div class="since">
+ <h3>Since</h3>
+ <p>
+ @FieldDefaults was introduced as experimental feature in lombok v0.11.4.
+ </p>
+ </div>
+ <div class="experimental">
+ <h3>Experimental</h3>
+ <p>
+ Experimental because:
+ <ul>
+ <li>New feature; unsure if this busts enough boilerplate</li>
+ <li>Would be nice if you could stick this on the package-info.java package to set the default for all classes in that package</li>
+ <li>Part of the work on @Value, which is experimental</li>
+ </ul>
+ Current status: <em>positive</em> - Currently we feel this feature may move out of experimental status with no or minor changes soon.
+ </div>
+ <div class="overview">
+ <h3>Overview</h3>
+ <p>
+ The <code>@FieldDefaults</code> annotation can add an access modifier (<code>public</code>, <code>private</code>, or <code>protected</code>)
+ to each field in the annotated class or enum. It can also add <code>final</code> to each field in the annotated class or enum.
+ </p>
+ </p><p>
+ To add <code>final</code> to each field, use <code>@FieldDefaults(makeFinal=true)</code>. Any non-final field which must remain nonfinal
+ can be annotated with <code>@NonFinal</code> (also in the <code>lombok.experimental</code> package).
+ </p><p>
+ To add an access modifier to each field, use <code>@FieldDefaults(level=AccessLevel.PRIVATE)</code>. 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 <code>@PackagePrivate</code> (also in the <code>lombok.experimental</code> package).
+ </p>
+ </div>
+ <div class="snippets">
+ <div class="pre">
+ <h3>With Lombok</h3>
+ <div class="snippet">@HTML_PRE@</div>
+ </div>
+ <div class="sep"></div>
+ <div class="post">
+ <h3>Vanilla Java</h3>
+ <div class="snippet">@HTML_POST@</div>
+ </div>
+ </div>
+ <div style="clear: left;"></div>
+ <div class="overview">
+ <h3>Small print</h3><div class="smallprint">
+ <p>
+ Like other lombok handlers that touch fields, any field whose name starts with a dollar (<code>$</code>) symbol is skipped entirely.
+ Such a field will not be modified at all.
+ </p>
+ </div>
+ </div>
+ <div class="footer">
+ <a href="index.html">Back to experimental features</a> | <a href="ExtensionMethod.html">Previous feature (@ExtensionMethod)</a> | <a href="Wither.html">Next feature (@Wither)</a><br />
+ <a href="../../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009-2012 The Project Lombok Authors, licensed under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.</span>
+ </div>
+ <div style="clear: both;"></div>
+ </div>
+</div>
+<script type="text/javascript">
+ var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+ document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-9884254-1");
+ pageTracker._trackPageview();
+ } catch(err) {}
+</script>
+</body></html>
diff --git a/website/features/experimental/Value.html b/website/features/experimental/Value.html
new file mode 100644
index 00000000..464f0966
--- /dev/null
+++ b/website/features/experimental/Value.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" type="text/css" href="../../logi/reset.css" />
+ <link rel="stylesheet" type="text/css" href="../features.css" />
+ <link rel="shortcut icon" href="../../favicon.ico" type="image/x-icon" />
+ <meta name="description" content="Spice up your java" />
+ <title>EXPERIMENTAL - @ExtensionMethod</title>
+</head><body><div id="pepper">
+ <div class="minimumHeight"></div>
+ <div class="meat">
+ <div class="header"><a href="../../index.html">Project Lombok</a></div>
+ <h1>@Value</h1>
+ <div class="byline">Immutable classes made very easy.</div>
+ <div class="since">
+ <h3>Since</h3>
+ <p>
+ @Value was introduced as experimental feature in lombok v0.11.4.
+ </p>
+ </div>
+ <div class="experimental">
+ <h3>Experimental</h3>
+ <p>
+ Experimental because:
+ <ul>
+ <li>Various choices still have to be vetted as being the correct 'least surprise' choice: Should the class be made final by default, etc.</li>
+ <li>Dependent on @Wither which is experimental.</li>
+ </ul>
+ Current status: <em>positive</em> - Currently we feel this feature may move out of experimental status with no or minor changes soon.
+ </div>
+ <div class="overview">
+ <h3>Overview</h3>
+ <p>
+ <code>@Value</code> is the immutable variant of <a href="../Data.html"><code>@Data</code></a>; all fields are made <code>private</code> and <code>final</code> by default, and instead of setters, each field gets a so-called 'wither',
+ which is a method that produces a clone with each field having the same value, except for the field you want a new value for. The class itself is also made <code>final</code> by default, because immutability is not something that can
+ be forced onto a subclass. Like <code>@Data</code>, useful <code>toString()</code>, <code>equals()</code> and <code>hashCode()</code> methods are also generated, each field gets a getter method, and a constructor that covers every
+ argument (except <code>final</code> fields that are initialized in the field declaration) is also generated.
+ </p><p>
+ In practice, <code>@Value</code> is shorthand for: <code>final @ToString @EqualsAndHashCode @AllArgsConstructor @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @Getter @Wither</code>.
+ </p><p>
+ 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 <code>@NonFinal</code> or <code>@PackagePrivate</code> annotations.<br />
+ It is possible to override any default behaviour for any of the 'parts' that make up <code>@Value</code> by explicitly using that annotation.
+ </p>
+ </div>
+ <div class="snippets">
+ <div class="pre">
+ <h3>With Lombok</h3>
+ <div class="snippet">@HTML_PRE@</div>
+ </div>
+ <div class="sep"></div>
+ <div class="post">
+ <h3>Vanilla Java</h3>
+ <div class="snippet">@HTML_POST@</div>
+ </div>
+ </div>
+ <div style="clear: left;"></div>
+ <div class="overview">
+ <h3>Small print</h3><div class="smallprint">
+ <p>
+ Look for the documentation on the 'parts' of <code>@Value</code>: <a href="../ToString.html"><code>@ToString</code></a>, <a href="../EqualsAndHashCode.html"><code>@EqualsAndHashCode</code></a>,
+ <a href="../Constructor.html"><code>@AllArgsConstructor</code></a>, <a href="FieldDefaults.html"><code>@FieldDefaults</code></a>, <a href="../GetterSetter.html"><code>@Getter</code></a>,
+ <a href="Wither.html"><code>@Wither</code></a>.
+ </p><p>
+ 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 <code>@AllArgsConstructor</code> annotation, there's also the <code>@Value(staticConstructor="of")</code> feature, which will make the generated all-arguments constructor
+ private, and generates a public static method named <code>of</code> which is a wrapper around this private constructor.
+ </p>
+ </div>
+ </div>
+ <div class="footer">
+ <a href="index.html">Back to experimental features</a> | <a href="Wither.html">Previous feature (@Wither)</a> | <span class="disabled">Next feature</span><br />
+ <a href="../../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009-2012 The Project Lombok Authors, licensed under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.</span>
+ </div>
+ <div style="clear: both;"></div>
+ </div>
+</div>
+<script type="text/javascript">
+ var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+ document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-9884254-1");
+ pageTracker._trackPageview();
+ } catch(err) {}
+</script>
+</body></html>
diff --git a/website/features/experimental/Wither.html b/website/features/experimental/Wither.html
new file mode 100644
index 00000000..34d6d0d9
--- /dev/null
+++ b/website/features/experimental/Wither.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <link rel="stylesheet" type="text/css" href="../../logi/reset.css" />
+ <link rel="stylesheet" type="text/css" href="../features.css" />
+ <link rel="shortcut icon" href="../../favicon.ico" type="image/x-icon" />
+ <meta name="description" content="Spice up your java" />
+ <title>EXPERIMENTAL - @ExtensionMethod</title>
+</head><body><div id="pepper">
+ <div class="minimumHeight"></div>
+ <div class="meat">
+ <div class="header"><a href="../../index.html">Project Lombok</a></div>
+ <h1>@Wither</h1>
+ <div class="byline">Immutable 'setters' - methods that create a clone but with one changed field.</div>
+ <div class="since">
+ <h3>Since</h3>
+ <p>
+ @Wither was introduced as experimental feature in lombok v0.11.4.
+ </p>
+ </div>
+ <div class="experimental">
+ <h3>Experimental</h3>
+ <p>
+ Experimental because:
+ <ul>
+ <li>Still not sure that <code>@Wither</code> is an appropriate name for this feature.</li>
+ <li>Should there be an option to supply a way of cloning the input somehow?</li>
+ <li>Should the way that the clone is created by configurable?</li>
+ <li>Should we replace @Wither entirely with a builder class?</li>
+ </ul>
+ Current status: <em>neutral</em> - More feedback requires on the items in the above list before promotion to the main package is warranted.
+ </div>
+ <div class="overview">
+ <h3>Overview</h3>
+ <p>
+ 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 <code>@Wither</code> generates: a <code>withFieldName(newValue)</code> method which produces a clone
+ except for the new value for the associated field.
+ </p><p>
+ For example, if you create <code>public class Point { private final int x, y; }</code>, setters make no sense because the fields
+ are final. <code>@Wither</code> can generate a <code>withX(int newXValue)</code> method for you which will return a new point with the supplied
+ value for <code>x</code> and the same value for <code>y</code>.
+ </p><p>
+ Like <a href="../GetterSetter.html"><code>@Setter</code></a>, you can specify an access level in case you want the generated wither to be something other than <code>public</code>:<br />
+ <code>@Wither(level = AccessLevel.PROTECTED)</code>. Also like <a href="../GetterSetter.html"><code>@Setter</code></a>, you can also put a <code>@Wither</code> annotation on a type, which means
+ a 'wither' is generated for each field (even non-final fields).
+ </p>
+ </div>
+ <div class="snippets">
+ <div class="pre">
+ <h3>With Lombok</h3>
+ <div class="snippet">@HTML_PRE@</div>
+ </div>
+ <div class="sep"></div>
+ <div class="post">
+ <h3>Vanilla Java</h3>
+ <div class="snippet">@HTML_POST@</div>
+ </div>
+ </div>
+ <div style="clear: left;"></div>
+ <div class="overview">
+ <h3>Small print</h3><div class="smallprint">
+ <p>
+ Withers cannot be generated for static fields because that makes no sense.
+ </p><p>
+ When applying <code>@Wither</code> to a type, static fields and fields whose name start with a $ are skipped.
+ </p><p>
+ 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, <code>with</code> is prefixed.
+ </p><p>
+ No method is generated if any method already exists with the same name (case insensitive) and same parameter count. For example, <code>withX(int x)</code>
+ will not be generated if there's already a method <code>withX(String... x)</code> 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.
+ </p><p>
+ For <code>boolean</code> fields that start with <code>is</code> immediately followed by a title-case letter, nothing is prefixed to generate the wither name.
+ </p><p>
+ Any annotations named <code>@NonNull</code> (case insensitive) on the field are interpreted as: This field must not ever hold
+ <em>null</em>. Therefore, these annotations result in an explicit null check in the generated wither. Also, these
+ annotations (as well as any annotation named <code>@Nullable</code> or <code>@CheckForNull</code>) are copied to wither parameter.
+ </p>
+ </div>
+ </div>
+ <div class="footer">
+ <a href="index.html">Back to experimental features</a> | <a href="FieldDefaults.html">Previous feature (@FieldDefaults)</a> | <a href="Value.html">Next feature (@Value)</a><br />
+ <a href="../../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009-2012 The Project Lombok Authors, licensed under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.</span>
+ </div>
+ <div style="clear: both;"></div>
+ </div>
+</div>
+<script type="text/javascript">
+ var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+ document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-9884254-1");
+ pageTracker._trackPageview();
+ } catch(err) {}
+</script>
+</body></html>
diff --git a/website/features/experimental/index.html b/website/features/experimental/index.html
index 9b25d710..6f180065 100644
--- a/website/features/experimental/index.html
+++ b/website/features/experimental/index.html
@@ -26,6 +26,12 @@
<dd>A more fluent API for getters and setters.</dd>
<dt><a href="ExtensionMethod.html"><Code>@ExtensionMethod</code></a></dt>
<dd>Annoying API? Fix it yourself: Add new methods to existing types!</dd>
+ <dt><a href="FieldDefaults.html"><Code>@FieldDefaults</code></a></dt>
+ <dd>New default field modifiers for the 21st century.</dd>
+ <dt><a href="Wither.html"><Code>@Wither</code></a></dt>
+ <dd>Immutable 'setters' - methods that create a clone but with one changed field.</dd>
+ <dt><a href="Value.html"><Code>@Value</code></a></dt>
+ <dd>Immutable classes made very easy.</dd>
</dl>
</div>
<div class="footer">