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:
- Strong type definition
- 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 outsidedelegate
: 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.
- OWNER_FIRST: the default policy, called first
owner
Methods and properties in, without, calldelegate
. - DELEGATE_FIRST: Call first
delegate
Methods and properties in, no, call againowner
. - OWNER_ONLY: only obtained
owner
Methods and properties in. - DELEGATE_ONLY: Obtains only
delegate
Methods and properties in. - TO_SELF: Needs to be customized
Closure
Subclass, 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