preface

After more than a week of trying to write a Gradle tutorial, I decided to start with the basics of Groovy. Although I can now use Kotlin directly, most of it is Groovy.

Since there are many Groovy tutorials out there, I’m not going to cover them all. Here are 11 differences between Java and Kotlin that I hope you’ll enjoy

Introduction to the

Groovy is an example of:

  • Based on Java
  • It has static typing and static compilation
  • Concise and efficient
  • Support the DSL
  • It can be both object-oriented and pure scripting

Dynamic language.

If you’re a Java user, congratulations, you can seamlessly access Groovy. If you’re still a Kotlin user, congratulations again, you’re basically ready to take off. Here we go.

1. The semicolon can be omitted

Like Kotlin, the semicolon in Groovy can be omitted:

class Student { static void main(String[] args){ println "Hello World!" }}Copy the code

Java requires the end of a line of code; At the end.

2. Weak type definition

Unlike Java, Groovy has two ways of defining variables:

  1. Strong type definition
  2. Weak type definition

Strongly typed means that when we declare variables, we also declare their types, like this:

private String name
Copy the code

Weak type definitions require the keyword def:

 Student {
    static void main(String[] args){
        // Weak type definition
        def name1 = "JiuXinDev"
        println name1
        // Strong type definition
        String name2 = "Chen88"
        println name2
    }	
}
Copy the code

Def gives us the right not to declare variable types at first, but at run time, which is completely different from compile time static typing in Java.

Var and val in Kotlin also don’t declare variable types, so is it the same as def in Groovy?

The answer is no, because Kotlin is statically typed, but Kotlin has type inference capabilities, so its type is determined at compile time.

Scope of 3.

For those of you who have studied Kotlin, you should be familiar with ranges. Groovy’s counterpart is Range, which we can use like this:

class Student {
    static void main(String[] args){
        def range = new IntRange(0.10); println range; }}Copy the code

The output

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Copy the code

Groovy can be used with.. The Range operator is more convenient to use:

class Student { static void main(String[] args){ def r1 = 0.. 10; println r1; def r2 = 10.. 0; println r2; def r3 = 'a'.. 'z'; println r3; }}Copy the code

Output:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]
Copy the code

You can manipulate not only numbers but also characters, combining strings and lists to make it more elegant.

4. The string

Strings in Groovy can use single, double, and triple quotes.

Single quotes

Single quotes are used the same way as in Java:

 Student {
    static void main(String[] args){
        String name = 'JiuXinDev';
        int age = 25;
        println "name: " + name + ", age: "+ age; }}Copy the code

Output:

name: JiuXinDev, age: 25
Copy the code

Double quotation marks

Double quotes have an interpolation function compared to single quotes, which is the same as Kotlin strings:

 Student {
    static void main(String[] args){
        String name = 'JiuXinDev'
        int age = 25
        println "name: $name, age: $age"}}Copy the code

Output:

name: JiuXinDev, age: 25
Copy the code

This is done by inserting ${variable} into a string.

Three quotes

There aren’t many quotes around, which helps us keep the output formatted:

class Student {
    static void main(String[] args){
        String str = The sky incense array broke Chang 'an, the city with golden armour. ' ' '; println str; }}Copy the code

Output:

Sky incense array broken Chang 'an, the city with golden armour.Copy the code

The use of line breaks is avoided.

String index

Like Kotlin, Groovy has a range operator that uses.. To represent, for example, 0 to 10, you can use 0.. 10 said. Code:

class Student {
    static void main(String[] args){
        String str = "Hello World";
        println str[1];
        println str[0.4.]; }}Copy the code

Output:

e
Hello
Copy the code

In addition to the above features, Groovy provides several other methods for strings, which you can check out on the Groovy website.

5. Access control

Like Java, Groovy has three access modifiers, public, private, and protected.

Without default modifiers, Java’s default access is package access, and Groovy’s default access, like Kotlin’s, is public, including classes, methods, and member variables.

6. Equality judgment

The == operator in Groovy is equivalent to using equals, which can be overridden.

class Name{
    String name;

    static void main(String[] args){
        def n = new Name()
        n.name = "JiuXinDev"
        def b = new Name()
        b.name = "JiuXinDev"
        assert n == b / / by
        assert n.is(b) / / not through
    }

    @Override
    boolean equals(Object obj) {
        return obj instanceof Name && name == obj.name
    }
}
Copy the code

Other articles say that null pointer exceptions can be avoided using the == operation, but I didn’t throw an exception using equals directly on Groovy version 3.0.6.

7. A Null

Safe call operator? .

By using the secure call operator? . Combine a NULL check and a method call into one operation:

class Name{
    static void main(String[] args){
        String s = nullprintln s? .length() } }Copy the code

The expression s.length() is equivalent to if(s! = null) s.length(), but since s is null, output is null. Of course, this caller can also access member variables.

Elvis operator

Elvis operator? The: is a special ternary operator that allows you to simplify ternary expressions:

class Student {
    static void main(String[] args){
        String a = null
        // def result = a ! = null ? a : "name"
        defresultA = a ? :"name"
        println resultA
        
        String b = "haha"
        def resultB = b.length() > 5? :"JiuXinDev"
        println resultB
    }
}
Copy the code

For an assignment, def result = a! = null ? A: “name” simplifies to def resultA = a? : “name”.

Everything can be converted to Boolean

Any object that is null, Void, or equal to 0 or null is resolved to false, and vice versa.

So String can be determined by STR! = null && str.length() > 0 STR.

Method 8.

Methods can also use the def modifier.

The return value

When we declare a return value type, but no return statement is displayed, the last line is used as the return statement by default.

class Student {
    static void main(String[] args){
        println getNum(5);
    }	
    
    static def getNum(int a){
        if(a > 2) {1;
        }else {
            0; }}}Copy the code

The method parameters

When you use def as an argument, you can omit def:

class Student { static void main(String[] args){ println getNum(5); } static def getNum(a){ if(a > 2){ 1; }else { 0; }}}Copy the code

When you have multiple parameters, you need to ensure that the parameter names are different.

We can also set parameters to default, like this:

class Student { static void main(String[] args){ println getMax(5); } static def getMax(a,b=2){ if(a > b){ 1; }else { 0; }}}Copy the code

I read the W3C says that if you use non-default and default parameters, you must note that the default parameters should be defined at the end of the parameter list. I defined default parameters directly in the header and non-default parameters in the tail without any problems.

Not adding specific types of parameters can make the code look more concise, but for later maintenance students, may not be at all friendly, so it is necessary to specify the development specification.

Omit the parentheses

In top-level expressions, parentheses can be omitted, such as the println method we have used many times before.

class Student {
    static void main(String[] args){
        println 2;
        println 2*2
        // println doSomeThing 2; Run failed
        println doSomeThing(2) * doSomeThing(2);
        println doSomeThing(2);
        // Use closures
        callSomeThing {
            println "Hello World!";
        };
    }
    
    static int doSomeThing(int value){
        return value + value;
    }
    
    static voidcallSomeThing(Closure c){ c.call(); }}Copy the code

After println, you can call 2, 2*2, functions, etc., but you can’t use an expression that omits the parentheses, such as doSomeThing 2. Another common scenario in addition to normal methods is to use closures, which I’ll cover below.

List of 9.

Lists are used in much the same way as In Java, but Groovy adds some of its own apis, such as:

class Student {
    static void main(String[] args){
        def list1 = [2.3.4.6.9.12];
        def list2 = [2.7];
        // combine the two sets to create a new set
        println list1.plus(list2);
        // minus the part of the first set that intersects the second set
        println list1.minus(list2);
        // Value by index
        println list1[1];
        // Use the range modifier
        println list1[1.3.];
        // Add new values to the list by <<
        list1 << 99
        println list1
    }
}
Copy the code

While this code involves the plus, minus, range, and << operators, I’ve already commented the method instructions in a similar style to Kotlin’s list.

Characteristics of 10.

In addition to interfaces and classes, there’s something new in Groovy called features, which you can think of as classes with default implementations and states, or classes with multiple inheritance capabilities that require the implements keyword, which implements interfaces.

class Student {
    static void main(String[] args){
        def developer = new SeniorDevelop();
        developer.drinkWater();
        developer.name = "Xiao li"; developer.writeCode(); }}interface Person{
    void drinkWater();
}

trait Man implements Person{
    void drinkWater(){
        println "8 glasses of water a day"; }}trait Coder{
    String name = "Wang";
    
    void writeCode(){
        println "200 lines of code a day."; }}class SeniorDevelop implements Man.Coder{
    void writeCode(){
        println getName() + "Write 500 lines of code a day."; }}Copy the code

SeniorDevelop implements feature Man and Coder, and can copy features’ methods and use features’ properties. Output:

Li can write 500 lines of code a dayCopy the code

11. The closure

Functional programming in Groovy is called closures.

The first closure

A closure is an anonymous code block:

class Name{
    static void main(String[] args){
        def printHelloWorld = { println "Hello World!" }
        // 1. Use the closure name directly ()
        printHelloWorld()
        // 2. Use the call method closure name. Call ()
        printHelloWorld.call()
    }
}
Copy the code

There are two methods of calling, one directly, and the other using the Call method.

Join the parameter

What if there are parameters?

class Name {
    static void main(String[] args) {
        def greet = { name -> println "Hello, this is $name" }
        greet("QiDian")
        greet.call("JiuXin")}}Copy the code

In the case of parameters, we need to declare the parameters and then enclose the arguments in parentheses at the call point.

The introduction of the variable

You can also introduce variables in closures, including local variables in methods and variables in classes:

class Name {
    static void main(String[] args) {
        def company = "YueWen"
        def greet = { name -> println "Hello, this is $name, it is from $company" }
        greet("QiDian")}}Copy the code

Output:

Hello, this is QiDian, it is from YueWen
Copy the code

Used as a parameter

Closures can be passed as arguments:

class Name {
    static void main(String[] args) {
        def clo = { String name, int level ->
            int salary = level * 10000
            println "$name salary is $salary yuan!"
        }
        calculateSalary(clo)
    }

    static void calculateSalary(Closure closure) {
        closure.call("Chen".3)}}Copy the code

That is, if you know what parameters are in the closure.

With the method

The with method in Groovy is similar to the Apply method in Kotlin, which uses closures:

class Name {
    String firstName;
    String secondName

    static void main(String[] args) {
        def name = new Name()
        name.with {
            firstName = "Take"
            secondName = "The wind"
            println "$firstName $secondName"}}}Copy the code

For the closure in the with method, we can either use the firstName member variable directly or use the public method inside.

entrust

The with method above makes it possible to call member variables and methods in an object because it changes the delegate policy.

There are three important concepts of delegates in closures, and they are this \ owner \ delegate. The difference is:

  • this: The class outside the closure definition or the class object.
  • owner: the class or class object outside the closure definition or the closure object outside
  • delegate: can be any object, defaultowner

Let’s use a simple demo:

class Name {
    static void main(String[] args) {
        def staticClo = {
            println "staticMethod this: " + this.toString()
            println "staticMethod owner: " + owner.toString()
            println "staticMethod delegate: " + delegate.toString()
        }
        staticClo.call()

        def name = new Name()
        name.with {}
        name.doSomeThing()
    }

    def clo = {
        println "class this: " + this.toString()
        println "class owner: " + owner.toString()
        println "class delegate: " + delegate.toString()

        def innerClo = {
            println "innerClo this: " + this.toString()
            println "innerClo owner: " + owner.toString()
            println "innerClo delegate: " + delegate.toString()
        }
        innerClo.call()
    }

    void doSomeThing(){
        clo.call()
    }
}
Copy the code

Output:

staticMethod this: class Name
staticMethod owner: class Name
staticMethod delegate: class Name
class this: Name@6ef888f6
class owner: Name@6ef888f6
class delegate: Name@6ef888f6
innerClo this: Name@6ef888f6
innerClo owner: Name$_closure1@5223e5ee
innerClo delegate: Name$_closure1@5223e5ee
Copy the code

In static methods, the closure’s this, owner, and delegate are all the same and refer to the class Name. In member variables, this, owner, and delegate also refer to the current Name object. Finally, we define a closure inside the closure, where this refers to the Name object and owner and delegate refer to the external closure object.

The delegate and owner are the same by default, but we can change the delegate:

class Person {
    String name
    String level

    def clo = {
        println "$name - $level"
    }

    static void main(String[] args) {
        def p1 = new Person()
        p1.name = "XiaoWang"
        p1.level = "1"

        def p2 = new Person()
        p2.clo.delegate = p1
        p2.clo.resolveStrategy = Closure.DELEGATE_FIRST
        p2.clo.call()
    }
}
Copy the code

Output:

XiaoWang - 1
Copy the code

We didn’t set any strings for p2’s name and level, just because we changed the delegate to the closure CLO. Just changing the delegate doesn’t work. We also need to change the delegate policy.

  1. OWNER_FIRST: the default policy, called firstownerMethods and properties in, without, calldelegate.
  2. DELEGATE_FIRST: Call firstdelegateMethods and properties in, no, call againowner.
  3. OWNER_ONLY: only obtainedownerMethods and properties in.
  4. DELEGATE_ONLY: Obtains onlydelegateMethods and properties in.
  5. TO_SELF: Needs to be customizedClosureSubclass, custom resolution policy.

We change OWNER_FIRST to DELEGATE_FIRST, so that the delegate of the closure CLO in P2 points to P1, and p1’s member variables name and level are used in preference.

conclusion

Overall, the Groovy language is like a cross between Java and Kotlin, and it’s not particularly expensive to learn.

Wonderful content

If you think this article is good, “like” is the biggest encouragement to the author ~

Technology more than, the article has material, concern public number nine heart said, a high quality good article every week, and nine hearts in Dachang road side by side.

Citation:

Syntax Style Guide w3c Groovy Tutorial