Groovy语言规范之程序结构
来源:互联网 发布:java变量的三要素 编辑:程序博客网 时间:2024/06/03 07:50
前言:
官方关于Programm Structure的介绍:Programm Structure
下文将会介绍Groovy的程序结构。
1.包名 Package names
这里的包名同Java中的包名发挥着同样的角色。包名允许我们分隔代码从而避免冲突。Groovy类必须在定义之前指定他们的包,并且假设默认的包名存在。
定义包的方式和Java非常相似
// defining a package named com.yoursitepackage com.yoursite
你可以调用Foo类使用com.yoursite.com.Foo,当然下面也将介绍import声明的方式引用类。
2.导包 Imports
为了引用任意一个类,而不需要包名。Groovy遵从了Java的方式允许使用import声明来解决类的导入。
例如,Groovy提供了几个builder类,例如MarkupBuilder。MarkupBuilder类在groovy.xml包中,所有你可以使用该类,通过以下方式的导入:
// importing the class MarkupBuilderimport groovy.xml.MarkupBuilder// using the imported class to create an objectdef xml = new MarkupBuilder()assert xml != null
2.1. 默认导入 Default imports
默认导入时Groovy语言默认导入的。例如下面的代码:
new Date()
同样的代码在Java中则需要导包声明:java.util.Date。Groovy默认为你导入了这些类。
Groovy默认添加了以下导入:
import java.lang.*import java.util.*import java.io.*import java.net.*import groovy.lang.*import groovy.util.*import java.math.BigIntegerimport java.math.BigDecimal
之所以这样做,是因为这些类非常常用。通过默认导入,减少了代码量。
2.2. 简单导包 Simple import
简单导包是你使用类的全路径进行导包。例如下面:
// importing the class MarkupBuilderimport groovy.xml.MarkupBuilder// using the imported class to create an objectdef xml = new MarkupBuilder()assert xml != null
2.3. 星号导入 Star import
像Java一样,Groovy提供了一个特殊的方式导入包下的所有的类通过使用*,也就是所谓的星号导包。实行星号导包前的导入方式:
import groovy.xml.MarkupBuilderimport groovy.xml.StreamingMarkupBuilderdef markupBuilder = new MarkupBuilder()assert markupBuilder != nullassert new StreamingMarkupBuilder() != null
使用星号导包后:
import groovy.xml.*def markupBuilder = new MarkupBuilder()assert markupBuilder != nullassert new StreamingMarkupBuilder() != null
2.4.静态导包 Static import
在Groovy的静态导包允许你导入类之后可以向静态方法一样在你自己的类中。和Java的静态导入相似,但是在Java1.4之上才能正常工作。
用法和Java基本相似,不再赘述:
import static Boolean.FALSEassert !FALSE //use directly, without Boolean prefix!
2.5.静态导包别名 Static import aliasing
这种用法比较类似于C语言中的typedef的用法。
使用as关键字的静态导包为命名空间问题提供了一个简洁的解决方案。加入你想要获得一个Calendar实例,使用getInstance()方法。它是静态方法,所以你可以使用静态导入。如果采用静态发导入,在调用时将不带类名因此容易误导使用者。我们可以使用别名的形式进行导入,以增强阅读性。
import static Calendar.getInstance as nowassert now().class == Calendar.getInstance().class
这样变得非常简洁易读。
2.6.静态星号导入 Static star import
星号静态导入和规则的星号导入很相似。将会导入该类的所有的静态的方法。
例如,下面的例子:
import static java.lang.Math.*assert sin(0) == 0.0assert cos(0) == 1.0
2.7 别名导入 Import aliasing
使用别名,我们可以使用自定义的名称来指向一个完全的类。同上,可以通过as关键字来实现。
考虑以下类,假设由第三方的类库提供的:
package thirdpartylibpublic class MultiplyTwo { def static multiply(def value) { return value * 3 //intentionally wrong. }}
假如我们这样使用这个库:
def result = new MultiplyTwo().multiply(2)
现在假设有这样一种情况,在使用了这个第三方库并且贯穿了你所有的代码,我们发现它没有给出一个正确的结果。我们怎样在一处修改,而不是修改源码,而不改变其他使用的地方?Groovy提供了简洁的方案。
使用简单的别名导入,我们可以修复这个bug像这样:
import thirdpartylib.MultiplyTwo as OrigMultiplyTwoclass MultiplyTwo extends OrigMultiplyTwo { def multiply(def value) { return value * 2 // fixed here }}// nothing to change below heredef multiplylib = new MultiplyTwo()// assert passes as wellassert 4 == new MultiplyTwo().multiply(2)
这就是通过as关键字重命名导入的类解决了这个问题。
别名导入在解决星号导入时的命名冲突同样有用。
3.脚本vs类 Script versus classes
3.1. public static void main vs 脚本 public static void main vs script
Groovy同时支持class和script(即类和脚本)。使用一下代码作为例子:
Main.groovy
class Main { //定义一个Main类,名字是任意的 static void main(String... args) { println 'Groovy world!' }}
你会发现以上是Java中的典型代码,代码嵌入类中执行。而Groovy是的这些变得更加容易,以下代码是等价的:
Main.groovy
println 'Groovy world!'
你可以把脚本想象成是一个不用声明的类。
3.2 脚本类 Script class
脚本总是会被编译成类。Groovy编译器会为你编译这个类,会把脚本体复制进run方法。上面的例子会被编译如下:
Main.groovy
import org.codehaus.groovy.runtime.InvokerHelperclass Main extends Script { //Main类继承了groovy.lang.Script类 def run() { //groovy.lang.Script需要run方法返回一个值 println 'Groovy world!' } static void main(String[] args) { //自动生成 InvokerHelper.runScript(Main, args) }}
如果脚本是一个文件,文件的基本名称会被用于生成脚本类。在这个例子中,如果文件名是Main.groovy,之后脚本类的会被命名为Main。
3.3. 方法Methods
定义方法在脚本中是可以的,如下:
int fib(int n) { n < 2 ? 1 : fib(n-1) + fib(n-2)}assert fib(10)==89
你可以将方法和代码混合。生成的脚本类会将所有的方法带入脚本类,并且嵌入所有的脚步体到run方法中:
println 'Hello' //脚步开始处 int power(int n) { 2**n } //一个没有脚本体的方法 println "2^6==${power(6)}"//脚本
以上代码会被转化成:
import org.codehaus.groovy.runtime.InvokerHelperclass Main extends Script { int power(int n) { 2** n}//power方法被复制进了自动生成的脚本类里面 def run() { println 'Hello' //脚本被复制到了这里面 println "2^6==${power(6)}" } static void main(String[] args) { InvokerHelper.runScript(Main, args) }}
尽管Groovy通过你的脚本创建了一个类,不过这个类对用户来说依然是易懂的。特别的,脚本被编译成字节码,行号被保留。这就意味着如果脚本中出现了一个异常,异常记录将会返回相应的原始脚本的行号,而不是你自动生成类的行号。
3.4. 变量Variables
变量在脚本中不需要类型声明。这就意味着,如下脚本:
int x = 1int y = 2assert x+y == 3
等同于:
x = 1y = 2assert x+y == 3
然而,二者之间在语义学上是不同的,表现如下:
- 如果声明变量如同第一个例子,它是本地变量。将会被声明在run方法,在脚本外部不可用。特别的,这种变量在脚本的其他方法中不可见。
- 如果变量没有被声明,变量会被绑定到脚本。并且对其他方法可见,你使用脚本与其他程序交互需要传递数据在脚本和程序之间,这种声明是非常有用的。
如果你希望变量变成一个类的字段而不是在Binding中,你可以使用@Field annotation.
- Groovy语言规范之程序结构
- 日积月累--Groovy语言规范之语法
- 日积月累--Groovy语言规范之操作符
- Groovy语言规范中文版之面向对象
- Groovy语言规范中文版之闭包
- 4.C语言之程序结构
- 《go语言圣经》之程序结构
- 无线标记语言(WML)基础之程序结构
- C语言之函数和程序结构
- Gradle 入门之 Groovy 语言详解
- JVM语言之Groovy第一篇
- JVM语言之Groovy第二篇
- Gradle构建之Groovy语言基础
- Groovy语言
- Groovy语言
- Groovy语言
- 《PL/SQL 语言开发参考手册》之二:PL/SQL 程序结构
- 黑马程序员_C语言学习笔记之基本程序结构
- HTML5 New Feature Series: Web Workers
- 如何校验服务器PUSH证书是否有效?
- Kosaraju算法查找有向图的强连通分支
- ViewPager+Fragment ViewPager中切换界面Fragment 初始化问题解决方案
- android Textview 实现展开收缩功能(字符宽度)(StaticLayout)
- Groovy语言规范之程序结构
- Java 打印
- oracle学习笔记 学习路线分析
- 使用Eclipse基于Maven的Spring MVC 调试心得(二)--- Spring配置
- python数字图像处理(1):环境安装和配置
- .net 工程log4net的使用
- VirtualBox 安装CentOs7后无法联网问题
- 大数据量下高并发同步的讲解
- CentOS6/5下vsftpd(虚拟用户)的配置