You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2023/01/26 07:18:28 UTC
[groovy] 01/02: Minor improvements to 'Differences with Java' documentation page
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit d17f5000978910102e772ef3a3f3258da1b61f62
Author: Alex Golub <a1...@gmail.com>
AuthorDate: Wed Jan 25 20:13:32 2023 +0200
Minor improvements to 'Differences with Java' documentation page
---
src/spec/doc/core-differences-java.adoc | 98 +++++++++++++++-------------
src/spec/test/DifferencesFromJavaTest.groovy | 18 ++---
2 files changed, 61 insertions(+), 55 deletions(-)
diff --git a/src/spec/doc/core-differences-java.adoc b/src/spec/doc/core-differences-java.adoc
index 55b17b6bb2..9a4bce77ab 100644
--- a/src/spec/doc/core-differences-java.adoc
+++ b/src/spec/doc/core-differences-java.adoc
@@ -126,7 +126,7 @@ include::../test/DifferencesFromJavaTest.groovy[tags=packageprivate_field,indent
== ARM blocks
-Java 7 introduced ARM (Automatic Resource Management) blocks like this:
+Java 7 introduced ARM (Automatic Resource Management) blocks (also know as try-with-resources) blocks like this:
[source,java]
----
@@ -298,18 +298,22 @@ Luckily, Java auto boxes and unboxes primitives when they are passed as paramete
// a few shell blocks use "ruby" code style as it is more forgiving than Java or Groovy
// it's not straight code after all, but might as well be a little pretty
-[source,ruby]
+[source,java]
----
-jshell> class Main {
- ...> float f1 = 1.0f;
- ...> Float f2 = 2.0f;
- ...> float add(Float a1, float a2) { return a1 + a2; }
- ...> Float calc() { return add(f1, f2); } // <1>
- ...> }
-| created class Main
+public class Main {
+
+ float f1 = 1.0f;
+ Float f2 = 2.0f;
-jshell> new Main().calc()
-$2 ==> 3.0
+ float add(Float a1, float a2) { return a1 + a2; }
+
+ Float calc() { return add(f1, f2); } // <1>
+
+ public static void main(String[] args) {
+ Float calcResult = new Main().calc();
+ System.out.println(calcResult); // => 3.0
+ }
+}
----
<1> The `add` method expects wrapper then primitive type arguments,
but we are supplying parameters with a primitive then wrapper type.
@@ -317,53 +321,51 @@ Similarly, the return type from `add` is primitive, but we need the wrapper type
Groovy does the same:
-[source,ruby]
+[source,groovy]
----
-groovy:000> class Main {
-groovy:001> float f1 = 1.0f
-groovy:002> Float f2 = 2.0f
-groovy:003> float add(Float a1, float a2) { a1 + a2 }
-groovy:004> Float calc() { add(f1, f2) }
-groovy:005> }
-===> true
-groovy:000> new Main().calc()
-===> 3.0
+class Main {
+
+ float f1 = 1.0f
+ Float f2 = 2.0f
+
+ float add(Float a1, float a2) { a1 + a2 }
+
+ Float calc() { add(f1, f2) }
+}
+
+assert new Main().calc() == 3.0
----
Groovy, also supports primitives and object types, however, it goes a little further
in pushing OO purity; it tries hard to treat _everything_ as an object.
-Any primitive typed variable or field can be treated like an object and it
-will be link:core-object-orientation.html#_primitive_types[autowrapped] as needed.
+Any primitive typed variable or field can be treated like an object, and it
+will be link:core-object-orientation.html#_primitive_types[auto-wrapped] as needed.
While primitive types might be used under the covers,
-their use should be indistinguishable from normal object use whenever possible
+their use should be indistinguishable from normal object use whenever possible,
and they will be boxed/unboxed as needed.
Here is a little example using Java trying to (incorrectly for Java) dereference a primitive `float`:
-[source,ruby]
+[source,java]
----
-jshell> class Main {
- ...> public float z1 = 0.0f;
- ...> }
-| created class Main
+class Main {
+
+ public float z1 = 0.0f;
-jshell> new Main().z1.equals(1.0f)
-| Error:
-| float cannot be dereferenced
-| new Main().z1.equals(1.0f)
-| ^------------------^
+ public static void main(String[] args){
+ new Main().z1.equals(1.0f); // DOES NOT COMPILE, Cannot resolve method 'equals(float)'
+ }
+}
----
The same example using Groovy compiles and runs successfully:
-[source,ruby]
+[source,groovy]
----
-groovy:000> class Main {
-groovy:001> float z1 = 0.0f
-groovy:002> }
-===> true
-groovy:000> new Main().z1.equals(1.0f)
-===> false
+class Main {
+ float z1 = 0.0f
+}
+assert !(new Main().z1.equals(1.0f))
----
Because of Groovy's additional use of un/boxing, it does not follow
@@ -463,8 +465,10 @@ https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html[conversions].
| float | N | C | C | C | C | C | - | Y
| double | N | C | C | C | C | C | C | -
|============================================================================================
-^*^ 'Y' indicates a conversion Java can make, 'C' indicates a conversion Java can make when there is an explicit cast,
-'T` indicates a conversion Java can make but data is truncated, 'N' indicates a conversion Java can't make.
+* 'Y' indicates a conversion Java can make +
+* 'C' indicates a conversion Java can make when there is an explicit cast +
+* 'T` indicates a conversion Java can make but data is truncated +
+* 'N' indicates a conversion Java can't make
Groovy expands greatly on this.
@@ -492,9 +496,11 @@ Groovy expands greatly on this.
| Double | T | T | D | T | D | T | T | D | D | T | D | T | D | D | T | B | - | Y
| BigDecimal | T | T | D | D | D | D | D | D | D | D | D | D | D | T | D | T | D | -
|=================================================================================================================================================================================================================
-^*^ 'Y' indicates a conversion Groovy can make, 'D' indicates a conversion Groovy can make when compiled dynamically or
-explicitly cast, 'T' indicates a conversion Groovy can make but data is truncated, 'B' indicates a boxing/unboxing
-operation, 'N' indicates a conversion Groovy can't make.
+* 'Y' indicates a conversion Groovy can make +
+* 'D' indicates a conversion Groovy can make when compiled dynamically or explicitly cast +
+* 'T' indicates a conversion Groovy can make but data is truncated +
+* 'B' indicates a boxing/unboxing operation +
+* 'N' indicates a conversion Groovy can't make.
The truncation uses <<{core-semantics}#the-groovy-truth,Groovy Truth>> when converting to `boolean`/`Boolean`. Converting
from a number to a character casts the `Number.intvalue()` to `char`. Groovy constructs `BigInteger` and `BigDecimal`
diff --git a/src/spec/test/DifferencesFromJavaTest.groovy b/src/spec/test/DifferencesFromJavaTest.groovy
index 0b9d83f178..5e12d2bcf6 100644
--- a/src/spec/test/DifferencesFromJavaTest.groovy
+++ b/src/spec/test/DifferencesFromJavaTest.groovy
@@ -162,25 +162,25 @@ assert (x.'this$0').is(y)
import org.codehaus.groovy.runtime.typehandling.GroovyCastException;
// tag::type_depends_on_quoting_AND_whether_we_actually_interpolate[]
-assert 'c'.getClass()==String
-assert "c".getClass()==String
-assert "c${1}".getClass() in GString
+assert 'c'.class == String
+assert "c".class == String
+assert "c${1}".class in GString
// end::type_depends_on_quoting_AND_whether_we_actually_interpolate[]
// tag::single_char_strings_are_autocasted[]
-char a='a'
-assert Character.digit(a, 16)==10 : 'But Groovy does boxing'
-assert Character.digit((char) 'a', 16)==10
+char a = 'a'
+assert Character.digit(a, 16) == 10: 'But Groovy does boxing'
+assert Character.digit((char) 'a', 16) == 10
try {
- assert Character.digit('a', 16)==10
+ assert Character.digit('a', 16) == 10
assert false: 'Need explicit cast'
} catch(MissingMethodException e) {
}
// end::single_char_strings_are_autocasted[]
// tag::chars_c_vs_groovy_cast[]
// for single char strings, both are the same
-assert ((char) "c").class==Character
-assert ("c" as char).class==Character
+assert ((char) "c").class == Character
+assert ("c" as char).class == Character
// for multi char strings they are not
try {