aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buildScripts/website.ant.xml6
-rw-r--r--usage_examples/EqualsAndHashCodeExample_post.jpage16
-rw-r--r--usage_examples/GetterLazyExample_post.jpage25
-rw-r--r--usage_examples/GetterLazyExample_pre.jpage13
-rw-r--r--usage_examples/valExample_post.jpage21
-rw-r--r--usage_examples/valExample_pre.jpage20
-rw-r--r--website/features/EqualsAndHashCode.html8
-rw-r--r--website/features/GetterLazy.html65
-rw-r--r--website/features/GetterSetter.html9
-rw-r--r--website/features/Log.html9
-rw-r--r--website/features/ToString.html2
-rw-r--r--website/features/index.html4
-rw-r--r--website/features/val.html65
13 files changed, 253 insertions, 10 deletions
diff --git a/buildScripts/website.ant.xml b/buildScripts/website.ant.xml
index 1d14097c..ef12026e 100644
--- a/buildScripts/website.ant.xml
+++ b/buildScripts/website.ant.xml
@@ -112,6 +112,9 @@ such as converting the changelog into HTML, and creating javadoc.
<param name="transformationName" value="GetterSetter" />
</antcall>
<antcall target="-integrateSnippet">
+ <param name="transformationName" value="GetterLazy" />
+ </antcall>
+ <antcall target="-integrateSnippet">
<param name="transformationName" value="ToString" />
</antcall>
<antcall target="-integrateSnippet">
@@ -135,6 +138,9 @@ such as converting the changelog into HTML, and creating javadoc.
<antcall target="-integrateSnippet">
<param name="transformationName" value="Log" />
</antcall>
+ <antcall target="-integrateSnippet">
+ <param name="transformationName" value="val" />
+ </antcall>
</target>
<target name="-website-dist">
diff --git a/usage_examples/EqualsAndHashCodeExample_post.jpage b/usage_examples/EqualsAndHashCodeExample_post.jpage
index 312bb92f..189a520e 100644
--- a/usage_examples/EqualsAndHashCodeExample_post.jpage
+++ b/usage_examples/EqualsAndHashCodeExample_post.jpage
@@ -15,8 +15,9 @@ public class EqualsAndHashCodeExample {
@Override public boolean equals(Object o) {
if (o == this) return true;
if (o == null) return false;
- if (o.getClass() != this.getClass()) return false;
+ if (!(o instanceof EqualsAndHashCodeExample)) return false;
EqualsAndHashCodeExample other = (EqualsAndHashCodeExample) o;
+ if (!other.canEqual(this)) return false;
if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
if (Double.compare(this.score, other.score) != 0) return false;
if (!Arrays.deepEquals(this.tags, other.tags)) return false;
@@ -33,6 +34,10 @@ public class EqualsAndHashCodeExample {
return result;
}
+ public boolean canEqual(Object other) {
+ return other instanceof EqualsAndHashCodeExample;
+ }
+
public static class Square extends Shape {
private final int width, height;
@@ -44,9 +49,10 @@ public class EqualsAndHashCodeExample {
@Override public boolean equals(Object o) {
if (o == this) return true;
if (o == null) return false;
- if (o.getClass() != this.getClass()) return false;
- if (!super.equals(o)) return false;
+ if (!(o instanceof Square)) return false;
Square other = (Square) o;
+ if (!other.canEqual(this)) return false;
+ if (!super.equals(o)) return false;
if (this.width != other.width) return false;
if (this.height != other.height) return false;
return true;
@@ -60,5 +66,9 @@ public class EqualsAndHashCodeExample {
result = (result*PRIME) + this.height;
return result;
}
+
+ public boolean canEqual(Object other) {
+ return other instanceof Square;
+ }
}
}
diff --git a/usage_examples/GetterLazyExample_post.jpage b/usage_examples/GetterLazyExample_post.jpage
new file mode 100644
index 00000000..76101db1
--- /dev/null
+++ b/usage_examples/GetterLazyExample_post.jpage
@@ -0,0 +1,25 @@
+public class GetterLazyExample {
+ private int[] $lombok$lazy1v;
+ private volatile boolean $lombok$lazy1i;
+ private final Object $lombok$lazyLock = new Object[0];
+
+ public int[] getCached() {
+ if (!this.$lombok$lazy1i) {
+ synchronized (this.$lombok$lazyLock) {
+ if (!this.$lombok$lazy1i) {
+ this.$lombok$lazy1v = expensive();
+ this.$lombok$lazy1i = true;
+ }
+ }
+ }
+ return this.$lombok$lazy1v;
+ }
+
+ private int[] expensive() {
+ double[] result = new double[1000000];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = Math.asin(i);
+ }
+ return result;
+ }
+}
diff --git a/usage_examples/GetterLazyExample_pre.jpage b/usage_examples/GetterLazyExample_pre.jpage
new file mode 100644
index 00000000..a6ca0966
--- /dev/null
+++ b/usage_examples/GetterLazyExample_pre.jpage
@@ -0,0 +1,13 @@
+import lombok.Getter;
+
+public class GetterLazyExample {
+ @Getter(lazy=true) private final int[] cached = expensive();
+
+ private int[] expensive() {
+ double[] result = new double[1000000];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = Math.asin(i);
+ }
+ return result;
+ }
+}
diff --git a/usage_examples/valExample_post.jpage b/usage_examples/valExample_post.jpage
new file mode 100644
index 00000000..e0f983d9
--- /dev/null
+++ b/usage_examples/valExample_post.jpage
@@ -0,0 +1,21 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ValExample {
+ public String example() {
+ final ArrayList<String> example = new ArrayList<String>();
+ example.add("Hello, World!");
+ String foo = example.get(0);
+ return foo.toLowerCase();
+ }
+
+ public void example2() {
+ final HashMap<Integer, String> map = new HashMap<Integer, String>();
+ map.put(0, "zero");
+ map.put(5, "five");
+ for (final Map.Entry<Integer, String> entry : map.entrySet()) {
+ System.out.printf("%d: %s\n", entry.getKey(), entry.getValue());
+ }
+ }
+}
diff --git a/usage_examples/valExample_pre.jpage b/usage_examples/valExample_pre.jpage
new file mode 100644
index 00000000..8b9dadc3
--- /dev/null
+++ b/usage_examples/valExample_pre.jpage
@@ -0,0 +1,20 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class ValExample {
+ public String example() {
+ val example = new ArrayList<String>();
+ example.add("Hello, World!");
+ val foo = example.get(0);
+ return foo.toLowerCase();
+ }
+
+ public void example2() {
+ val map = new HashMap<Integer, String>();
+ map.put(0, "zero");
+ map.put(5, "five");
+ for (val entry : map.entrySet()) {
+ System.out.printf("%d: %s\n", entry.getKey(), entry.getValue());
+ }
+ }
+}
diff --git a/website/features/EqualsAndHashCode.html b/website/features/EqualsAndHashCode.html
index c5128d10..dbe45218 100644
--- a/website/features/EqualsAndHashCode.html
+++ b/website/features/EqualsAndHashCode.html
@@ -28,10 +28,16 @@
</p><p>
Setting <code>callSuper</code> to <em>true</em> when you don't extend anything (you extend <code>java.lang.Object</code>) is a compile-time error, because it would turn
the generated <code>equals()</code> and <code>hashCode()</code> implementations into having the same behaviour as simply inheriting these methods from <code>java.lang.Object</code>:
- only the same object will be equal to each other and will have the same hashCode. Obviously, inheriting <code>java.lang.Object</code> is the right strategy if you want this behaviour.
+ only the same object will be equal to each other and will have the same hashCode.
Not setting <code>callSuper</code> to <em>true</em> 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
<code>callSuper</code> chaining facility.
+ </p><p>
+ <em>NEW in Lombok 0.10: </em>Unless your class is <code>final</code> and extends <code>java.lang.Object</code>, lombok generates a <code>canEqual</code> 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: (TODO: Find link to Venners/Spoon/Odersky). 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 <code>canEqual</code>
+ if you change <code>equals</code> and <code>hashCode</code>.
</p>
</div>
<div class="snippets">
diff --git a/website/features/GetterLazy.html b/website/features/GetterLazy.html
new file mode 100644
index 00000000..a91e782c
--- /dev/null
+++ b/website/features/GetterLazy.html
@@ -0,0 +1,65 @@
+<!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>@Getter(lazy=true)</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>@Getter and @Setter</h1>
+ <div class="byline">Laziness is a virtue!</div>
+ <div class="overview">
+ <h3>Overview</h3>
+ <p>
+ <em>NEW IN Lombok 0.10: </em>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 <code>private final</code> variable,
+ initialize it with the expression that's expensive to run, and annotate your field with <code>@Getter(lazy=true)</code>. 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 <code>null</code>, the result is cached) and your expensive calculation need not be thread-safe, as lombok
+ takes care of locking.
+ </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>
+ Lombok actually creates a few fields all prefixed with <code>$lombok$</code> to cache the value. You should not rely on the exact type, name, and structure
+ of these fields as future implementations may change them. To access the lazily initialized value, <em>always</em> use the generated getter.
+ </p><p>
+ Other Lombok annotations such as <code>@ToString</code> always call the getter even if you use <code>doNotUseGetters=true</code>.
+ </p>
+ </div>
+ </div>
+ <div class="footer">
+ <a href="index.html">Back to features</a> | <a href="GetterSetter.html">Previous feature (@Getter / @Setter)</a> | <a href="ToString.html">Next feature (@ToString)</a><br />
+ <a href="../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009-2010 Reinier Zwitserloot and Roel Spilker, 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/GetterSetter.html b/website/features/GetterSetter.html
index ea1af150..fd4ed17d 100644
--- a/website/features/GetterSetter.html
+++ b/website/features/GetterSetter.html
@@ -60,15 +60,18 @@
</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 setter. Also, these
- annotations (as well as any annotation named <code>@Nullable</code> or <code>@CheckForNull</code>) are copied to setter parameter and getter method
+ annotations (as well as any annotation named <code>@Nullable</code> or <code>@CheckForNull</code>) are copied to setter parameter and getter method.
+ </p><p>
+ You can annotate a class with a <code>@Getter</code> or <code>@Setter</code> annotation. Doing so is equivalent to annotating all non-static fields
+ in that class with that annotation. <code>@Getter</code>/<code>@Setter</code> annotations on fields take precedence over the ones on classes.
</p><p>
Using the <code>AccessLevel.NONE</code> access level simply generates nothing. It's useful only in combination with
- <a href="Data.html"><code>@Data</code></a>.
+ <a href="Data.html"><code>@Data</code></a> or a class-wide <code>@Getter</code> or <code>@Setter</code>.
</p>
</div>
</div>
<div class="footer">
- <a href="index.html">Back to features</a> | <span class="disabled">Previous feature</span> | <a href="ToString.html">Next feature (@ToString)</a><br />
+ <a href="index.html">Back to features</a> | <span class="disabled">Previous feature</span> | <a href="GetterLazy.html">Next feature (@Getter(lazy=true))</a><br />
<a href="../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009-2010 Reinier Zwitserloot and Roel Spilker, 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/Log.html b/website/features/Log.html
index 6912b6ed..c5d7771c 100644
--- a/website/features/Log.html
+++ b/website/features/Log.html
@@ -15,7 +15,7 @@
<div class="overview">
<h3>Overview</h3>
<p>
- You can annotate any field with <code>@Log</code> to let lombok generate a logger field automatically.<br />
+ <em>NEW in lombok 0.10: </em>You can annotate any field with <code>@Log</code> to let lombok generate a logger field automatically.<br />
The logger is named <code>log</code> and field's type depends on which logger you have selected.
</p><p>
There are four <code>@Log</code> choices available:<br />
@@ -50,11 +50,16 @@
<h3>Small print</h3><div class="smallprint">
<p>
If a field called <code>log</code> already exists, a warning will be emitted and no code will be generated.
+ </p><p>
+ A future feature of lombok's <code>@Log</code> 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 <code>if</code> 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 <em>NOT</em> put any side-effects in the expression that you log.
</p>
</div>
</div>
<div class="footer">
- <a href="index.html">Back to features</a> | <a href="SneakyThrows.html">Previous feature (@SneakyThrows)</a> | <span class="disabled">Next feature</span><br />
+ <a href="index.html">Back to features</a> | <a href="SneakyThrows.html">Previous feature (@SneakyThrows)</a> | <a href="val.html">Next feature (val)</a><br />
<a href="../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009-2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans, 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/ToString.html b/website/features/ToString.html
index 23041f48..e350c265 100644
--- a/website/features/ToString.html
+++ b/website/features/ToString.html
@@ -66,7 +66,7 @@
</div>
</div>
<div class="footer">
- <a href="index.html">Back to features</a> | <a href="GetterSetter.html">Previous feature (@Getter / @Setter)</a> | <a href="EqualsAndHashCode.html">Next feature (@EqualsAndHashCode)</a><br />
+ <a href="index.html">Back to features</a> | <a href="GetterLazy.html">Previous feature (@Getter(lazy=true))</a> | <a href="EqualsAndHashCode.html">Next feature (@EqualsAndHashCode)</a><br />
<a href="../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2009 Reinier Zwitserloot and Roel Spilker, 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/index.html b/website/features/index.html
index d216ddb4..edc173fb 100644
--- a/website/features/index.html
+++ b/website/features/index.html
@@ -15,6 +15,8 @@
<dl>
<dt><a href="GetterSetter.html"><code>@Getter</code> / <code>@Setter</code></a></dt>
<dd>Never write <code>public int getFoo() {return foo;}</code> again.</dd>
+ <dt><a href="GetterLazy.html"><code>@Getter(lazy=true)</code></a></dt>
+ <dd>Laziness is a virtue!</dd>
<dt><a href="ToString.html"><code>@ToString</code></a></dt>
<dd>No need to start a debugger to see your fields: Just let lombok generate a <code>toString</code> for you!</dd>
<dt><a href="EqualsAndHashCode.html"><code>@EqualsAndHashCode</code></a></dt>
@@ -32,6 +34,8 @@
<dd>To boldly throw checked exceptions where no one has thrown them before!</dd>
<dt><a href="Log.html"><code>@Log</code></a></dt>
<dd>Captain's Log, stardate 24435.7: &quot;What was that line again?&quot;</dd>
+ <dt><a href="val.html"><code>val</code></a></dt>
+ <dd>Finally! hassle-free final local variables.</dd>
</dl>
</div>
<div class="pointer">
diff --git a/website/features/val.html b/website/features/val.html
new file mode 100644
index 00000000..a3ce58e0
--- /dev/null
+++ b/website/features/val.html
@@ -0,0 +1,65 @@
+<!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>@Data</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>val</h1>
+ <div class="byline">Finally! hassle-free final local variables.</div>
+ <div class="overview">
+ <h3>Overview</h3>
+ <p>
+ <em>NEW in Lombok 0.10: </em>You can use <code>val</code> 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.
+ </p><p>
+ <em>WARNING: This feature does not currently work in NetBeans. We're working on fixing that.</em>
+ </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>
+ For compound types, the most common superclass is inferred, not any shared interfaces. For example, <code>bool ? new HashSet() : new ArrayList()</code>
+ is an expression with a compound type: The result is both <code>AbstractCollection</code> as well as <code>Serializable</code>. The type inferred will be
+ <code>AbstractCollection</code>, as that is a class, whereas <code>Serializable</code> is an interface.
+ </p><p>
+ In ambiguous cases, such as when the initializer expression is <code>null</code>, <code>java.lang.Object</code> is inferred.
+ </p>
+ </div>
+ </div>
+ <div class="footer">
+ <a href="index.html">Back to features</a> | <a href="Log.html">Previous feature (@Log)</a> | <span class="disabled">Next feature</span><br />
+ <a href="../credits.html" class="creditsLink">credits</a> | <span class="copyright">Copyright &copy; 2010 Reinier Zwitserloot and Roel Spilker, 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>