classSomeClass{staticvoidmain(args){def some =newSomeClass()assert'hi'== some.publicUntyedMethod()assert'ho'== some.publicTypedMethod()combineMethod()}voidpublicVoidMethod(){}defpubicVoidMethod(){return'hi'}
String publicTypedMethod(){return'ho'}protectedstaticfinalvoidcombineMethod(){}}
方法参数声明
classSomeClass{staticmethod(arg){
println 'untyped'}staticmethod(String arg){
println 'typed'}staticmethod(arg1, Number arg2){
println 'mixed'}}
高级方法参数使用
classSummer{defsumWithDefaults(a,b,c =0){return a + b + cs
}defsumWithList(List args){return args.inject(0){
sum,i ->
sum += i
}}defsumWithOptionals(a, b, object[] optionals){return a + b +sumWithList(optionals.toList())}defsumNamed(Map args){['a','b','c'].each{
args.get(it,0)}return args.a + args.b + args.c
}}
构造函数
位置参数
classVendorWithCtor{
String name, product
VendorWithCtor(name,product){this.name = name
this.product = product
}}def first =newVendorWithCtor('canoo','ULC')// Normal constructor usedef second =['Canoo','ULC']as VendorWithCtor // Coercion with as
VendorWithCtor third =['Canoo','ULC']// Corecion in assignment
java.awt.Dimension area
area = [200,100]
assert area.width == 200
assert area.height == 100
属性获取设置器
classMyBean{def a
def b
defgetA(){return a
}defgetB(){return b
}defsetA(a){this.a = a
}defsetB(b){this.b = b
}}def mb =newMyBean()
mb.a =10
mb.b =30
属性获取方法,Groovy方式直接.属性名就可以了.
Java
Groovy
getPropertyName
propertyName
setPropertyName(value)
propertyName = value
属性获取器和@语法的使用区别
classMrBean{
String firstName, lastName
String getName(){return"$firstName $lastName"}}def bean =newMrBean(firstName:'Rowan')
bean.lastName ='Atkinson'//advanced accessors with groovyclassDoubleBean{public value //visible valuevoidsetValue(value){this.value = value //inner field access}defgetValue(){
value *2//inner field access}}def bean2 =newDoubleBean(value:100)assert200== bean2.value //Property access use getter methodassert100== bean2.@value // Outer field access directly access
GPaths查询对象
invoke example for Gpath
classBook{
String name
List authors
}classAuthor{
String name
Address addr
}classAddress{
String province
String city
}def addr1 =newAddress(province:'Guangdong',city:'Shenzhen')def addr2 =newAddress(province:'Gunagdong',city:'Guangzhou')def addr3 =newAddress(province:'Hunan',city:'Changsha')def addr4 =newAddress(province:'Hubei',city:'Wuhan')def books =[newBook(name:'A glance at Java',authors:[newAuthor(name:'Tom',addr:addr1)]),newBook(name:'Deep into Groovy',authors:[newAuthor(name:'Tom',addr:addr1),newAuthor(name:'Mike',addr:addr3)]),newBook(name:'A compare of Struts and Grails',authors:[newAuthor(name:'Wallace',addr:addr4),newAuthor(name:'Bill',addr:addr2)]),newBook(name:'learning from Groovy to Grails',authors:[newAuthor(name:'Wallace',addr:addr3)])]//目标是找到作者是"Tom"的书籍的书名//Java风格def booksOfTomOldWay =[]
books.each {def book = it
def aus = it.authors
aus.each {
au->if(au.name =='Tom')
booksOfTomOldWay << book.name
}}
println booksOfTomOldWay
//Groovy风格 非常简练,也符合一个正常的思考顺序.def booksOfTom = books.grep{
it.authors.any{
it.name =='Tom'}}.name
println booksOfTom
//类似Java的方式classHelloWorld{staticvoidmain(String[] args){//Using a simple printn statement to print output to console.println('hello world);}}//如果用Groovy脚本的方式:
println 'hello world'
导入
import groovy.xml.MarkupBuilder
def xml =newMarkupBuilder()
def i =12def j =12.5def a ='a'def s1 ="aaa"def s2 ='aaaaaaa'
数据类型
内置数据类型
byte
short
int
long
float
double
char
boolean
String
数字类(Number)
Byte
Short
Integer
Long
Float
Double
BigInteger
BIgDecimal
变量
变量的声明有两种:
一种是类似Java的方式声明,一种是利用def关键字,变量的类型在赋值的时候去确定。
String a ="hello"def a ='hello'//def a =1println(a.getClass())
a =newString("1112234")println(a.getClass())
//利用def的方式,变量的类型还可以随时动态的切换
运算符
算术运算符
关系运算符
逻辑运算符
位运算符
赋值运算符
主要介绍一下Groovy比Java多出的一些特性
范围运算符
def range =0..5println(range.class)println(range)
输出
class groovy.lang.IntRange
[0, 1, 2, 3, 4, 5]
流程控制
循环
while
while(condition){//execution}
for
for(;;){//excution}//for infor(var in range){//}//for 语句也可以用于循环访问map,将输出一个键值def e =["a":12,"b":31,"c":12,"d":32]for(a in e){println(a)}
class Empire{
private String name //必须制定getter和setter,因为是private的
int age //提供默认的getter 和setter
Empire(String name,int age){
this.name = name
this.age = age
}
def getName(){
return name
}
}
Empire empire = new Empire("China",5000)
println empire.getName() //属性getter
println empire.name //属性
println empire.age
继承&扩展
interfaceFLY{deffly()}classAnimal{private String name
private String category
Animal(String name, String category){this.name = name
this.category = category
}
String getName(){return name
}
String getCategory(){return category
}voidsetName(String name){this.name = name
}voidsetCategory(String category){this.category = category
}}classDoveextendsAnimalimplementsFLY{Dove(String name, String category){super(name, category)}@Overridedeffly(){
println "I believe i can fly"}}
Dove d =newDove("Dove","Bird")
println d.name
println d.category
d.fly()
Dove f =newDove("","")
f.name ="lala"
f.category ="prettyBird"
println f.name
println f.category
traitNameimplementsFlyingAbility, SwimmingAbility{public String name
abstractdefprintName()}classPersonimplementsName{public String name
@OverridedefprintName(){
println Name__name
}}//1.解决钻石问题(多重继承引发的歧义问题),同时能够实现多重继承的好处//2.对trait的理解就是嵌入实现类中,而不是继承的那种上下文的关系
Person p =newPerson()
p.Name__name ="hefuduo"
p.name ="LeoHe"
p.swim()
p.fly()
Groovy闭包
闭包是一个短的匿名代码块。它通常跨越几行代码。一个方法甚至可以将代码块作为参数。它们是匿名的。
下面是一个简单闭包的例子,它是什么样子。
def close ={
println "hello groovy"}
close.call()
@interfaceOnlyIf{
Class value()}@OnlyIf({ number<=6})voidVersion6(){
result <<'Number greater than 6'}@OnlyIf({ number>=6})voidVersion7(){
result <<'Number greater than 6'}
def text ='This Tutorial focuses on $TutorialName. In this tutorial you will learn
about $Topic'
def binding =["TutorialName":"Groovy","Topic":"Templates"]def engine =newgroovy.text.SimpleTemplateEngine()def template = engine.createTemplate(text).make(binding)
println template
Public interfaceGroovyInterceptable{
Public object invokeMethod(String methodName, Object args)
Public object getproperty(String propertyName)
Public object setProperty(String propertyName, Object newValue)
Public MetaClass getMetaClass()
Public voidsetMetaClass(MetaClass metaClass)}
// public final class Integer extends Number
Number num = new Integer(1);
List<Number> list = new ArrayList<>();
list.add(new Integer(3));
ArrayList<Number> list = new ArrayList<Integer>(); //type mismatch 这两个根本就不是一个类型
List<? extends Number> list = new ArrayList<Number>();
list.add(new Integer(1)); //error
Random rondom =newRandom(25);byte[] bytes =newbyte[24];
rondom.nextBytes(bytes);
我们来看一下内部的原理。
首先是初始化Random对象的时候,传入了一个seed
/**
* Construct a random generator with the given {@code seed} as the
* initial state. Equivalent to {@code Random r = new Random(); r.setSeed(seed);}.
*
* <p>This constructor is mainly useful for <i>predictability</i> in tests.
* The default constructor is likely to provide better randomness.
*/publicRandom(long seed){setSeed(seed);}//看一下setSeed源码/**
* Modifies the seed using a linear congruential formula presented in <i>The
* Art of Computer Programming, Volume 2</i>, Section 3.2.1.
*/publicsynchronizedvoidsetSeed(long seed){this.seed =(seed ^ multiplier)&((1L <<48)-1);
haveNextNextGaussian =false;}//multiplier这个是一个静态常量privatestaticfinallong multiplier = 0x5deece66dL;//再看一下nextBytes的实现publicvoidnextBytes(byte[] buf){int rand =0, count =0, loop =0;while(count < buf.length){if(loop ==0){
rand =nextInt();
loop =3;}else{
loop--;}
buf[count++]=(byte) rand;
rand >>=8;}}//这里面用到了nextInt,再跟踪一下代码/**
* Returns a pseudo-random uniformly distributed {@code int}.
*/publicintnextInt(){returnnext(32);}//继续跟到nextprotectedsynchronizedintnext(int bits){
seed =(seed * multiplier + 0xbL)&((1L <<48)-1);return(int)(seed >>>(48- bits));}//其实这个就是最基本的实现了//原理上就是通过种子数的操作,重新生成一个处理后返回,然后种子数继续用,所以如果知道你的种子数,那么这个随机数就是可预测的了。