ITPUB论坛 » 动态语言 » Java帝国的王储——Groovy !之学习


2007-11-19 09:57 shiren1118
Java帝国的王储——Groovy !之学习

让我们来回顾一下主流语言的发展历程:机器语言(由01组成) -> 汇编语言 -> ... -> C语言 -> C++ -> Java -> ?

不知道大家有没有发现在语言发展过程中,存在这么一个规律:能成为未来主流语言的,必与当前主流语言属同一‘语系’,换句话说,由王子继承王位。

在C语言之前,似乎还处于‘春秋战国’,各种编程语言混战,于20世纪70年代,C语言成为‘秦始皇’,各种软件甚至操作系统也改用C语言编写。但可惜C语言是面向过程的,程序代码一多,逻辑流程就容易混乱,再加上全局变量和可运算指针的添乱,使程序员调试程序万般辛苦。

20世纪80年代,C++应运而生,它继承了C语言(包括C语言的语法),并添加了类等特性,使C++成为一种面向对象的语言。但C++的多继承,人工内存管理,从C语言那里继承的可运算指针等问题同样使程序员万般痛苦。

20世纪90年代,正当人们饱受煎熬的时候,Java诞生了,她去除了C++中的糟粕,保留了C++中的精华(包括语法),并添加了一些自己的特性,比如垃圾回收器,接口等。我听很多由C++转Java的朋友说过这么一句话:用Java写程序简直是一种享受。可惜Java的那优美的语法使之失去了‘轻盈’的身躯,程序员需要写相对比较多的代码来完成同样的功能。此外Java代码即使编译为class文件,也能被“高质量”反编译为Java文件获得源码。

21世纪初,Groovy( [url]http://groovy.codehaus.org[/url]  背后有ThoughtWorks, Big Sky, G2One等公司的支持)横空出世,她几乎兼容Java的所有语法,并能无需转换直接利用Java所写的类及接口,在Spring2中可以透明地注入 Groovy对象(与注入Java对象没有任何区别),且拥有自己的一些‘敏捷’特性,如动态类型,Closure,Mixins等,以及对应J2EE中如JSP, Servlet的Groovy敏捷版--GSP以及Groovlet等,不但如此她还拥有Ruby最引以为傲的Ruby on Rails的对应实现版本但非克隆--Grails( [url]http://grails.org[/url]  背后有Oracle的支持),此外Groovy代码编译为class文件后,即使不混淆,反编译后获得的Java源代码也“极难”读懂(换句话说,如果您能读懂这些反编译得来的源码,那您早就用不着hack人家的class文件了),原因是Groovy自身就是用Java编写的,class文件烙有 Groovy的印迹。?指代谁至今还不太明了,但Groovy至少已经具备了继承王位的必要条件--语言本身是利用当前主流语言所编写,并与当前主流语言的语法相似,且能够结束当前主流语言的弊病。

综上所述,选择Java世界中动态语言Groovy(Groovy = Java + Python + Ruby + Smalltalk),至少是明智的,不仅因为她是JVM上JCP全票通过的官方标准语言,更因为她身上具有王储的特质。Groovy之于Java犹如 Java之于C++。另外,由于Groovy本身就是用Java写的,所以对Groovy的‘投资’能够得到保值。因为Groovy的程序能运行于 JDK1.4+之上,所以Groovy的新特性(比如Groovy1.1中新添加的Annotations以及static import)不会像Java中的新特性(比如Java5中的Generics以及Annotations等)那样无法在旧版JDK上使用,这就起到了保值作用。如果说Java实现了跨平台,那么Groovy不仅实现了跨平台而且实现了跨Java平台。

[[i] 本帖最后由 shiren1118 于 2007-11-19 10:01 编辑 [/i]]

2007-11-19 10:03 shiren1118
Groovy跻身TIOBE排名35 !
Groovy面世至今已有4年了,其间风波不断,但Groovy Team毅然挺过了那段灰色的岁月,迎来了金色的2007年。
即将发布的Groovy1.1Final将为2007年划上一个完美的句号,我坚信2008年将是Groovy & Grails年!

2007-11-19 10:07 shiren1118
1.闭包
先解释一下闭包的概念:
闭包是很多动态语言提供的一个很方便的功能,它有点像Java中的内部类,
不同的是闭包中只有一个方法,但这个方法可以有任意个参数。
下面看一个闭包的最简单的例子:

def closure={ param -> println "hello ${param}" }  
closure.call("world!")

def是一个关键字,相当于JavaScript中的Var,用来定义一个对象。
closure为闭包的名字。在大括号里面,参数和处理参数的语句用->隔开。
param是这个闭包的参数,参数的数目是任意的,不同的参数之间用","隔开。
下面处理这些参数的语句就可以直接调用这些参数了。

所有的闭包都是继承自groovy.lang.Closure类,闭包也是一个普通的类,
只是在Groovy中,这个语法比较特别。所以闭包也可以当作一个返回值。
或者当作一个参数传入一个方法。

闭包的返回值:
调用闭包的call方法,会有一个返回值,可以调用return来指定,如果不指定的话,
则返回闭包中最后一条有返回值的语句。

闭包可以调用的对象:
在方法里面,可以调用方法内的局部变量
作为类变量,可以调用类变量

关于0个参数以及对象it:
参数可以是任意个,没有参数就不需要"->"了。没有参数的话,但是传入了一个参数,
这个参数可以通过一个无类型的对象"it"来访问。比如上面的例子我们可以这么写:

def closure2={ println "hello ${it}" }  
closure2.call("world!")

关于闭包的调用:
定义以后就可以调用这个闭包,有两种方式,
closure.call("world!")
closure("world!")
这两种是没有任何区别的,第二个是第一个的简写

2007-11-19 10:08 shiren1118
2.集合的本地化语法
这个比闭包更容易理解,Groovy对collections, lists, maps, arrays的声明和使用
提供了语言级的支持,可以直接声明一个list和map,无需调用new方法创建一个List或者
map对象。

2007-11-19 10:10 shiren1118
看一个来自Groovy官方网站的例子:
def list = [5, 6, 7, 8]
assert list.get(2) == 7
assert list[2] == 7
assert list instanceof java.util.List

def emptyList = []
assert emptyList.size() == 0
emptyList.add(5)
assert emptyList.size() == 1

2007-11-19 10:10 shiren1118
与Java的区别如下:
1.通过[value...]的方式来声明
2.通过list[index]的方式来访问和赋值
3.通过[]来声明一个空的map

2007-11-19 10:12 shiren1118
developerWorks 中国  >  Java technology  >
实战 Groovy: Groovy 的腾飞

熟悉 Groovy 新的、遵循 JSR 的语法
        developerWorks
       
       
文档选项
        将此页作为电子邮件发送       

将此页作为电子邮件发送


级别: 中级

Andrew Glover, CTO, Vanward Technologies

2005 年 8 月 22 日

    随着 Groovy JSR-1(及其后续发行版本)的发布,Groovy 语法的变化已经规范化 —— 这意味着如果以前没有对此加以注意,那么现在是开始注意它的时候了。这个月,Groovy 的常驻实践者 Andrew Glover 将介绍 Groovy 语法最重要的变化,以及在经典 Groovy 中找不到的一个方便特性。

从我在 alt.lang.jre 的系列文章“Feeling Groovy” 中介绍 Groovy 开始,差不多有一年时间了。从那时起,通过发行许多版本,逐步解决了语言实现中的问题,并满足开发人员社区的一些特性请求,Groovy 已经成熟了许多。最后,在今年四月,Groovy 有了一个重大飞跃,它正式发布了新的解析器,该解析器的目标就是将这门语言标准化为 JSR 进程的一部分。

在本月“实战 Groovy”这一期的文章中,我将祝贺 Groovy 的成长,介绍通过 Groovy 非常好用的新解析器规范化的一些最重要的变化:即变量声明和闭包。因为我要将一些新 Groovy 语法与我在关于 Groovy 的第一篇文章中介绍的经典语法进行比较,所以您可以在另一个浏览器窗口中打开“ alt.lang.jre: 感受 Groovy”这篇文章。

2007-11-19 10:13 shiren1118
为什么会发生这些变化?

如果您一直在跟踪 Groovy,不管是阅读文章和 blog,还是自己编写代码,您都可能已经遭遇过这门语言的一、两个微妙的问题。在进行一些灵敏的操作,例如对象导航,特别是使用闭包的时候, Groovy 偶尔会遇到歧义性问题和语法受限的问题。几个月之前,作为 JSR 进程的一部分,Groovy 团队开始着手解决这些问题。四月份,随 groovy-1.0-jsr-01 发行版本提供的解决方案是一个更新过的语法以及一个用来对语法进行标准化的新语法内容解析器。
       
关于本系列

将任何一个工具集成到开发实践中的关键是:知道什么时候使用它,什么时候把它留在箱子中。脚本语言可以是工具箱中极为强大的附件,但是只有在将它恰当应用到适当的地方时才这样。为了实现这个目标, 实战 Groovy 是一个文章系列,专门介绍 Groovy 的实际应用,并教导您什么时候使用它们,以及如何成功地应用它们。

好消息是:新语法是对语言的完全增强。另一个好消息是:它和以前的语法没有很大不同。像所有 Groovy 一样,语法的设计目标是较短的学习曲线和较大的回报。

当然,符合 JSR 的解析器也给新 Groovy 带来一些与目前“经典”语法不兼容的地方。如果用新的解析器运行本系列以前文章中的代码示例,那么您自己就可以看,代码示例可能无法工作!现在,这一点看起来可能有点苛刻 —— 特别是对 Groovy 这样自由的语言来说 —— 但是解析器的目标是确保作为 Java 平台的标准化 语言的 Groovy 的持续成长。可以把它当作新 Groovy 的一个有帮助的指南。

2007-11-19 10:13 shiren1118
Groovy 依然是 Groovy!

在深入研究变化的内容之前,我要花几秒钟谈谈什么没有改变。首先,动态类型化的基本性质没有改变。变量的显式类型化(即将变量声明为 String 或 Collection) 依然是可选的。稍后,我会讨论对这一规则的一点新增内容。

知道分号依然是可选的时候,许多人都会感到轻松。对于放松对这个语法的使用,存在许多争论,但是最终少数派赢得了胜利。底线是:如果愿意,也可以使用分号。

集合(Collection)的使用大部分还保持不变。仍然可以用 array 语法和 map,像以前那样(即最初从文章“alt.lang.jre: 感受 Groovy”中学到的方式)声明类似 list 的集合。但范围上略有变化,我将在后面部分展示这一点。

最后,Groovy 对标准 JDK 类的增加没有发生多少变化。语法糖衣和漂亮的 API 也没变, 就像普通的 Java File 类型的情况一样,我稍后将展示这一点。

2007-11-19 10:14 shiren1118
容易变的变量

Groovy 的变量规则对新的符合 JSR 的语法的打击可能最大。经典的 Groovy 在变量声明上相当灵活(而且实际上很简洁)。而使用新的 JSR Groovy 时,所有的变量前都必须加上 def 关键字或者 private、protected 或 public 这样的修饰符。当然,也可以声明变量类型。另外,如果正在定义类,希望声明属性(使用 JavaBeans 样式的 getter 和 setter 公开),那么也可以用 @Property 关键字声明成员变量。请注意 —— Property 中的 P 是大写的!

例如,在“alt.lang.jre: 感受 Groovy”中介绍 GroovyBeans 时,我在文章的清单 22 中定义了一个叫做 LavaLamp 的类型。这个类不再符合 JSR 规范,如果要运行它,则会造成解析器错误。幸运的是,迁移这个类不是很困难:我要做的全部工作就是给所有需要的成员变量添加 @Property 属性,如清单 1 所示:

清单 1. LavaLamp 的返回结果

package com.vanward.groovy
class LavaLamp{
  @Property model
  @Property baseColor
  @Property liquidColor
  @Property lavaColor
}
llamp = new LavaLamp(model:1341, baseColor:"Black",
  liquidColor:"Clear", lavaColor:"Green")
println llamp.baseColor
println "Lava Lamp model ${llamp.model}"
myLamp = new LavaLamp()
myLamp.baseColor = "Silver"
myLamp.setLavaColor("Red")
println "My Lamp has a ${myLamp.baseColor} base"
println "My Lava is " + myLamp.getLavaColor()


不是太坏,不是吗?

正如上面描述的,对于任何 变量,如果没有修饰符、@Property 关键字或者类型,则需要具有 def 关键字。例如,清单 2 的代码在 toString 方法中包含一个中间变量 numstr ,如果用 JSR 解析器运行此代码,则会造成一个错误:

2007-11-19 10:14 shiren1118
清单 2. 不要忘记 def 关键字!

class Person {
  @Property fname
  @Property lname
  @Property age
  @Property address
  @Property contactNumbers
  String toString(){
   
   numstr = new StringBuffer()
       
   if (contactNumbers != null){
           contactNumbers.each{
                numstr.append(it)
                numstr.append(" ")
           }
   }
   
   "first name: " + fname + " last name: " + lname +
        " age: " + age + " address: " + address +
        " contact numbers: " + numstr.toString()
}
}


认识这个代码吗?它借用来自“在 Java 应用程序中加一些 Groovy 进来 ”一文的清单 1 中的代码。在清单 3 中,可以看到运行代码时弹出的错误消息:

清单 3. 错误消息

c:devprojects>groovy BusinessObjects.groovy

BusinessObjects.groovy: 13: The variable numstr is undefined in the current scope
@ line 13, column 4.
      numstr = new StringBuffer()
      ^
1 Error


当然,解决方案也是在 toString 方法中将 def 关键字添加到 numstr。清单 4 显示了这个更合适的 def 解决方案。

清单 4. 用 def 重新处理

  String toString(){
   
   def numstr = new StringBuffer()
       
   if (contactNumbers != null){
           contactNumbers.each{
                numstr.append(it)
                numstr.append(" ")
           }
   }
   
   "first name: " + fname + " last name: " + lname +
        " age: " + age + " address: " + address +
        " contact numbers: " + numstr.toString()
}


另外,我还可以为 numstr 提供一个像 private 这样的修饰符,或者将它声明为 StringBuffer。不论哪种方法,重要的一点是:在 JSR Groovy 中,必须在变量前加上某些东西。

2007-11-19 10:14 shiren1118
封闭闭包(closure)

闭包的语法发生了变化,但是大多数变化只与参数有关。在经典的 Groovy 中,如果为闭包声明参数,就必须用 | 字符作为分隔符。您可能知道,| 也是普通 Java 语言中的位操作符;结果,在 Groovy 中,只有在某个闭包的参数声明的上下文中,才能使用 | 字符。

在“alt.lang.jre: 感受 Groovy”的清单 21 中,我演示了迭代,查看了用于闭包的经典 Groovy 参数语法。可以回想一下,我在集合上运用了 find 方法,该方法试图找到值 3。然后我传入了参数 x,它代表 iterator 的下一个值 (有经验的 Groovy 开发人员会注意到,x 完全是可选的,我可以引用隐式变量 it)。使用 JSR Groovy 时,必须删除 | ,并用 Nice 样式的 -> 分隔符代替它,如清单 5 所示:

清单 5. 新的 Groovy 闭包语法

[2, 4, 6, 8, 3].find { x ->
  if (x == 3){
    println "found ${x}"
  }
}


新的闭包语法有没有让您想起 Nice 语言的块语法呢?如果不熟悉 Nice 语言,请参阅 alt.lang.jre: Nice 的双倍功能,这是我在 alt.lang.jre 系列上贡献的另一篇文章。

正如我在前面提到过的,Groovy 的 JDK 没有变。但是就像刚才所学到的,闭包却发生了变化;所以,使用 Groovy 的 JDK 中那些漂亮的 API 的方式也发生了变化,但仅仅是轻微的变化。在清单 6 中,可以看到这些变化对 Groovy IO 的影响根本是微不足道的:

清单 6. Groovy 的 JDK 依旧功能强大!

import java.io.File
new File("maven.xml").eachLine{ line ->
  println "read the following line -> " + line
}


改编过滤器

现在,不得不让您跳过很大一部分,但您还记得在“用 Groovy 进行 Ant 脚本编程”一文中,我是如何介绍闭包的威力和工具的吗?谢天谢地,我在这个专栏的示例中所做的多数工作都很容易针对新语法重新进行改编。在清单 7 中,我只是将 @Property 属性添加到 Filter 的成员 strategy(最初在那篇文章的清单 2 和清单 3 中显示)。然后在闭包中添加 -> 分隔符,万岁 —— 它可以工作了!

清单 7. 过滤改编!

package com.vanward.groovy
class Filter{
@Property strategy
boolean apply(str){
  return strategy.call(str)
}
}
simplefilter = { str ->
  if(str.indexOf("java.") >= 0){
    return true
  }else{
    return false
  }
}
               
fltr = new Filter(strategy:simplefilter)
assert !fltr.apply("test")
assert fltr.apply("java.lang.String")
               
rfilter = { istr ->
  if(istr =~ "com.vanward.*"){
    return true
  }else{
    return false
  }
}
               
rfltr = new Filter(strategy:rfilter)
assert !rfltr.apply("java.lang.String")
assert rfltr.apply("com.vanward.sedona.package")


目前为止还不坏,您觉得呢?新的 Groovy 语法很容易掌握!

2007-11-19 10:15 shiren1118
对范围(range)的更改

Groovy 的范围语法的变化非常小。在经典的 Groovy 中,您可以通过使用 ... 语法指明排他性(即上界)来避开这些变化。在 JSR Groovy 中,只要去掉最后一个点(.),并用直观的 < 标识替代它即可。

请注意观察我在下面的清单 8 中对来自“Feeling Groovy”一文中的范围示例进行的改编:

清单 8. 新的范围语法

myRange = 29..<32
myInclusiveRange = 2..5
println myRange.size() // still prints 3
println myRange[0]   // still prints 29
println myRange.contains(32) //  still prints false
println myInclusiveRange.contains(5) // still prints true

2007-11-19 10:15 shiren1118
您是说存在歧义?

您可能注意到,在使用 Groovy 时,有一项微妙的功能可以让您获得方法引用,并随意调用这个引用。可以将方法指针当作调用对象方法的方便机制。关于方法指针,有意思的事情是:它们的使用可能就表明代码违反了迪米特法则。

您可能会问“什么是迪米特法则”呢?迪米特法则使用只与直接朋友对话 这句格言指出:我们应当避免调用由另一个对象方法返回的对象上的方法。例如,如果 Foo 对象公开了一个 Bar 对象类型,那么客户应当通过 Foo 访问 Bar 的行为。结果可能是一些脆弱的代码,因为对某个对象的更改会传播到整个范围。

一位受尊敬的学者写了一篇优秀的文章,叫做“The Paperboy, the Wallet, and the Law of Demeter”(请参阅 参考资料)。这篇文章中的示例是用 Java 语言编写的;但是,我在下面用 Groovy 重新定义了这些示例。在清单 9 中,可以看到这些代码演示了迪米特法则 —— 如何用它洗劫人们的钱包!

2007-11-19 10:19 shiren1118
一些新东西!

如果在 Groovy 的 JSR 发行版中没有什么新东西,那就没有意思了,不是吗?谢天谢地,JSR Groovy 引入了 as 关键字,它是一个方便的类型转换机制。这个特性与新的对象创建语法关系密切,新的语法可以用类似数组的语法很容易地在 Groovy 中创建非定制 类。所谓非定制,指的是在 JDK 中可以找到的类,例如 Color、Point、File,等等。

在清单 11 中,我用这个新语法创建了一些简单类型:

清单 11. Groovy 中的新语法

def nfile = ["c:/dev", "newfile.txt"] as File
def val = ["http", "www.vanwardtechnologies.com", "/"] as URL
def ival = ["89.90"] as BigDecimal
println ival as Float


注意,我用便捷语法创建了一个新 File 和 URL,还有 BigDecimal ,还要注意的是,我可以用 as 把 BigDecimal 类型转换成 Float 类型。




        回页首


接下来是什么呢?

JSR 对 Groovy 的规范化过程并没有结束,特别是在有些东西在 Groovy 的当前版本中(在本文发布时是 JSR-2)仍然不起作用的情况下。例如,在新的 Groovy 中,不能用 do/while 循环。此外,新的 Groovy 还无法完全支持 Java 5.0 的 for 循环概念。结果是,可以使用 in 语法,但是不能使用新推出的 : 语法。

这些都是重要的特性,不能没有,但是不用担心 —— Groovy 小组正在努力工作,争取在未来几个月内实现它们。请参阅 参考资料,下载最新的发行版本,并学习更多关于 JSR Groovy 进程的内容;还请继续关注下个月的“实战 Groovy”,下个月我(和两个客座专栏作家)将深入讨论 Groovy 闭包的更精彩的细节。

2007-11-19 10:21 shiren1118
1、 hello world(看看开发环境) 2、 99乘法表(看看循环、格式化输出)3 做个比较复杂点的程序,看看过程调用、循环、判断这些基本的语言特征。



好些年没有学新语言了,还是先试试这三板过时的(面向对象、数据库、网络服务都没有涉及到)斧头还能不能砍得了东西吧。

1 hello world

脚本语言就是方便,一点上下文都没有,一个println就搞定了



2 99乘法表

1def i=0
2def j
3while(i<9){
4    i++
5    j=1
6    while(j<=i){
7        print(j+"*"+i+"="+(i*j)+"        ")
8        j++
9    }
10    println()
11}

脚本语言就是松散,分号加不加都可以。语法和数据类型好像都跟java差不多。



3 写个复杂一点的例子。前两天看《程序员法则》刚好看到提起了著名的八皇后问题,就写个八皇后吧:

1int q=8
2int[] i=new int[q]
3int count=0
4long t = System.currentTimeMillis();
5scan(0)
6println("totle results:"+count)
7println("totle time:"+(System.currentTimeMillis()-t));
8def scan(n){
9    if (n==q){
10        println(i.toList())
11        count++
12        return
13    }
14    i[n]=0
15    while(i[n]<q){
16        i[n] = i[n]+1
17        if (check(n))
18            scan(n+1)
19    }
20}
21def check(n){
22    if (n>0)
23        for (j in 0..<n)
24            if (i[j]==i[n] || i[j]-i[n]==j-n || i[j]-i[n]==n-j )
25                return false
26    return true
27}



呵呵,典型的面向过程,全局变量都弄出来了。运行一下还满快的

2007-11-19 10:22 shiren1118
groovy 学习笔记2 IDE

groovy虽然没有自己的IDE,但是它可以依附在很多现有的开发环境如eclipse,intelli idea等。不过不巧我都不大用这些开发环境的。还好,找到了groovy的ultraedit语法文件 这样在ultraedit下面也可以高亮显示、编译和运行groovy了。



ultraedit甚至还提供了命令自动补全功能,不过默认使用的组合键是ctrl+space,恰好和输入法切换键冲突了。不过我们可以修改组合键:


Advanced - Configuration - Key Mapping


在commands里面找到AutoComplete(命令不是按字母排序的,按一下“A”键就自动找到啦),然后输入焦点转到 Press New Key框中,选择自己喜欢的组合键,比如 Alt+space,确认组合键出现在框里面后点一下Assign键,大功告成。


详细介绍见 [url]http://groovy.codehaus.org/UltraEdit+Plugin[/url]


editplus也是我心爱的编辑器之一,还好不只我喜欢editplus和groovy,有个韩国网站也有同好:[url]http://www.javaclue.org/index.jsp[/url]


看不懂:-P。不过也不用看懂,直接把他们写的groovy语法文件








[url]http://www.javaclue.org/groovy/editor/editplus/groovy.acp[/url]



[url]http://www.javaclue.org/groovy/editor/editplus/groovy.stx[/url]





下载下来,在editplus的参数选项--设置和语法里面添加groovy的语法和自动补全文件,现在editplus也支持groovy的高亮显示和自动补全了。





不过editplus的自动补全和ultraedit有写不同,是敲一个关键字,然后按空格的时候把相关的语法元素自动补进来。

2007-11-19 10:25 shiren1118
一个面向对象的语言往往都是通过package把对象组织起来的,但是很奇怪居然没有找到groovy的package方面的资料,难道groovy不支持?那么我们怎么用groovy来设计负责一点的程序呢?还是做试验试试吧:

Dog.groovy:

1package com
2class Dog {
3    public def name;
4    def bark ()  {
5        println("barking")
6    }
7    def say ()  {
8        println("My name is "+name);
9    }
10}
11


嗯,一只会说一句话的狗,还回吠哦。

编译一下看看有没有错: groovyc Dog.groovy
嗯,没有错,而且在当前目录下生成了一个com目录,其中有Dog.class文件

再建一个类来引用这个类  trainDog.groovy:
1dog = new com.Dog(name:"Doggie");
2dog.bark();
3dog.say();
4



运行……失败了:

Caught: General error during class generation: No such class: com.Dog in constructor call for class: trainDog. At [1:7] D:groovymygroovycom        rainDog.groovy

一番努力之后,始终无法让 trainDog.groovy运行起来,但是反编译这两个groovy生成的class文件看起来又很正确。算了,用java来运行它吧(还好一开始就配置了editplus下面的调试环境,下面的命令由editplus自动生成,不用自己敲了)

D:jdk1.5.0injava.exe -classpath .;d:groovygroovy-1.0-jsr-01.jar;d:groovylibasm-1.5.2.jar trainDog

果然不错:

---------- java ----------
barking
My name is Doggie
Normal Termination
输出完成(耗时 0 秒)。


看来groovy虽然可以直接运行,却不能直接相互引用。进行复杂应用的时候还是要先编译好以便他们可以相互引用类文件。此外groovy编译器会自动为包创建对应的目录,所以所有的groovy不管分散到多少包里面都要在同一个目录(所有包的上一层)下面编译。

2008-1-3 14:24 ziyouniao1213
我觉得关键是思想,语言并不重要

2008-1-4 15:51 cauc_dg
关注一下

页: [1] 2


Powered by ITPUB论坛