You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by ke...@apache.org on 2015/09/01 20:33:40 UTC

incubator-groovy git commit: document primitive autowrapping (closes #94)

Repository: incubator-groovy
Updated Branches:
  refs/heads/master ba5c6271c -> 8d8eda980


document primitive autowrapping (closes #94)


Project: http://git-wip-us.apache.org/repos/asf/incubator-groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-groovy/commit/8d8eda98
Tree: http://git-wip-us.apache.org/repos/asf/incubator-groovy/tree/8d8eda98
Diff: http://git-wip-us.apache.org/repos/asf/incubator-groovy/diff/8d8eda98

Branch: refs/heads/master
Commit: 8d8eda9805ae00c2681683622351a33df07e7da9
Parents: ba5c627
Author: Keegan Witt <ke...@gmail.com>
Authored: Fri Aug 21 00:51:35 2015 -0400
Committer: Keegan Witt <ke...@gmail.com>
Committed: Tue Sep 1 14:33:35 2015 -0400

----------------------------------------------------------------------
 src/spec/doc/core-differences-java.adoc   | 13 +++++++
 src/spec/doc/core-object-orientation.adoc | 45 ++++++++++++++++++++++++
 src/spec/test/PrimitiveTest.groovy        | 47 ++++++++++++++++++++++++++
 3 files changed, 105 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/8d8eda98/src/spec/doc/core-differences-java.adoc
----------------------------------------------------------------------
diff --git a/src/spec/doc/core-differences-java.adoc b/src/spec/doc/core-differences-java.adoc
index 32aa8ac..0bae774 100644
--- a/src/spec/doc/core-differences-java.adoc
+++ b/src/spec/doc/core-differences-java.adoc
@@ -260,6 +260,19 @@ with exception.
 include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=chars_c_vs_groovy_cast,indent=0]
 ----
 
+== Primitives and wrappers
+
+Because Groovy uses Objects for everything, it link:core-object-orientation.html#_primitive_types[autowraps] references
+to primitives. Because of this, it does not follow Java's behavior of widening taking priority over boxing.
+Here's an example using `int`
+
+[source,groovy]
+----
+include::{projectdir}/src/spec/test/PrimitiveTest.groovy[tags=widening_vs_boxing,indent=0]
+----
+<1> This is the method that Java would call, since widening has precedence over unboxing.
+<2> This is the method Groovy actually calls, since all primitive references use their wrapper class.
+
 == Behaviour of `==`
 
 In Java `==` means equality of primitive types or identity for objects.  In

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/8d8eda98/src/spec/doc/core-object-orientation.adoc
----------------------------------------------------------------------
diff --git a/src/spec/doc/core-object-orientation.adoc b/src/spec/doc/core-object-orientation.adoc
index 583052b..72d8f29 100644
--- a/src/spec/doc/core-object-orientation.adoc
+++ b/src/spec/doc/core-object-orientation.adoc
@@ -35,6 +35,51 @@ Groovy supports the same primitive types as those defined by the {jls}[Java Lang
 * `boolean` type (exactly `true` or `false`)
 * `char` type (16 bit, usable as a numeric type, representing an UTF-16 code)
 
+While Groovy declares and stores primitive fields and variables as primitives, because it uses Objects for
+everything, it autowraps references to primitives. Just like Java, the wrappers it uses are
+
+[cols="1,1" options="header"]
+.primitive wrappers
+|====
+| Primitive type
+| Wrapper class
+
+| boolean
+| Boolean
+
+| char
+| Character
+
+| short
+| Short
+
+| int
+| Integer
+
+| long
+| Long
+
+| float
+| Float
+
+| double
+| Double
+|====
+
+Here's an example using `int`
+
+[source,groovy]
+----
+include::{projectdir}/src/spec/test/PrimitiveTest.groovy[tags=primitive_references,indent=0]
+----
+
+Now you may be concerned that this means every time you use a mathematical operator on a reference to a primitive
+that you'll incur the cost of unboxing and reboxing the primitive. But this is not the case, as Groovy will compile
+your operators into their link:core-operators.html#_operator-overloading[method equivalents] and uses those instead.
+Additionally, Groovy will automatically unbox to a primitive when calling a Java method that takes a primitive
+parameter and automatically box primitive method return values from Java. However, be aware there are some
+link:core-differences-java.html#_primitives_and_wrappers[differences] from Java's method resolution.
+
 === Class
 
 Groovy classes are very similar to Java classes, being compatible to those ones at JVM level. They may have methods and fields/properties, which can have the same modifiers (public, protected, private, static, etc) as Java classes.

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/8d8eda98/src/spec/test/PrimitiveTest.groovy
----------------------------------------------------------------------
diff --git a/src/spec/test/PrimitiveTest.groovy b/src/spec/test/PrimitiveTest.groovy
new file mode 100644
index 0000000..2b469b1
--- /dev/null
+++ b/src/spec/test/PrimitiveTest.groovy
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2003-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+class PrimitiveTest extends GroovyTestCase {
+
+    void testPrimitiveReferences() {
+        assertScript '''
+            // tag::primitive_references[]
+            class Foo {
+              static int i
+            }
+
+            assert Foo.class.getDeclaredField('i').type == int.class
+            assert Foo.i != int.class && Foo.i.class == Integer.class
+            // end::primitive_references[]
+        '''
+    }
+
+    void testPrimitiveWideningVsBoxing() {
+        assertScript '''
+            // tag::widening_vs_boxing[]
+            int i
+            m(i)
+
+            void m(long l) {           //<1>
+              println "in m(long)"
+            }
+
+            void m(Integer i) {        //<2>
+              println "in m(Integer)"
+            }
+            // end::widening_vs_boxing[]
+        '''
+    }
+}