First they ignore you
then they ridicule you
then they fight you
then you win
    -- Mahatma Gandhi
Chinese => English     英文 => 中文             
随笔-143  评论-742  文章-0  trackbacks-0
让我们来回顾一下主流语言的发展历程:机器语言(由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( http://groovy.codehaus.org  背后有ThoughtWorks, Big Sky, G2One等公司的支持)横空出世,她几乎兼容Java的所有语法,并能无需转换直接利用Java所写的类及接口,在Spring2中可以透明地注入Groovy对象(与注入Java对象没有任何区别),且拥有自己的一些‘敏捷’特性,如动态类型,Closure,Mixins等,以及对应J2EE中如JSP, Servlet的Groovy敏捷版--GSP以及Groovlet等,不但如此她还拥有Ruby最引以为傲的Ruby on Rails的对应实现版本但非克隆--Grails( http://grails.org  背后有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平台。

附关于Groovy的JCP投票结果:




再来看一个Groovy官方网站( http://groovy.codehaus.org )上的例子,在官方网站上还有许多教程和应用实例,大家不妨去看看。
利用已存在的Java类库:
import org.apache.commons.lang.WordUtils

class Greet {
  def name
  Greet(who) { name 
= who[0].toUpperCase() + who[1..-1] }
  def salute() { println 
"Hello $name!" }
}

class Greeter extends Greet {
  Greeter(who) { name 
= WordUtils.capitalize(who) }
}

new Greeter('world').salute()


最后,看看Groovy与其他Java世界的动态语言的受关注程度的比较吧,从图中可以看出,Groovy有压倒性趋势:



--------------------------------------------------------------------------------------
文中提到的通过反编译获得源码:
HelloWorld.groovy编译为HelloWorld.class,然后将HelloWorld.class反编译为HelloWorld.java

HelloWorld.groovy的源码:
class HelloWorld {
    
static void main(String[] args) {
          println 
"Hello, world!"
    }
}


HelloWorld.class反编译得到的Java文件HelloWorld.java:
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   HelloWorld.groovy

import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;

public class HelloWorld
    
implements GroovyObject
{

    
public HelloWorld()
    {
        MetaClass metaclass;
        Class class1 
= HelloWorld.class;
        Class class2 
= groovy.lang.MetaClass.class;
        metaclass 
= (MetaClass)ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.invokeStaticMethodN(class1, org.codehaus.groovy.runtime.ScriptBytecodeAdapter.class"initMetaClass"new Object[] {
            
this
        }), class2);
        metaclass;
        (MetaClass)ScriptBytecodeAdapter.castToType(metaclass, class2);
        
this;
        JVM INSTR swap ;
        metaClass;
        JVM INSTR pop ;
    }

    
public static void main(String args[])
    {
        Class class1 
= HelloWorld.class;
        Class class2 
= groovy.lang.MetaClass.class;
        ScriptBytecodeAdapter.invokeStaticMethodN(class1, class1, 
"println"new Object[] {
            
"Hello, world!"
        });
    }

    
public MetaClass getMetaClass()
    {
        Class class2;
        MetaClass metaclass;
        Class class1 
= HelloWorld.class;
        class2 
= groovy.lang.MetaClass.class;
        
if(!ScriptBytecodeAdapter.compareEqual(metaClass, null))
            
break MISSING_BLOCK_LABEL_118;
        metaclass 
= (MetaClass)ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.invokeStaticMethodN(class1, org.codehaus.groovy.runtime.ScriptBytecodeAdapter.class"initMetaClass"new Object[] {
            
this
        }), class2);
        metaclass;
        (MetaClass)ScriptBytecodeAdapter.castToType(metaclass, class2);
        
this;
        JVM INSTR swap ;
        metaClass;
        JVM INSTR pop ;
        
return (MetaClass)ScriptBytecodeAdapter.castToType(metaClass, class2);
    }

    
public Object invokeMethod(String method, Object arguments)
    {
        Class class1;
        MetaClass metaclass;
        class1 
= HelloWorld.class;
        Class class2 
= groovy.lang.MetaClass.class;
        
if(!ScriptBytecodeAdapter.compareEqual(metaClass, null))
            
break MISSING_BLOCK_LABEL_121;
        metaclass 
= (MetaClass)ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.invokeStaticMethodN(class1, org.codehaus.groovy.runtime.ScriptBytecodeAdapter.class"initMetaClass"new Object[] {
            
this
        }), class2);
        metaclass;
        (MetaClass)ScriptBytecodeAdapter.castToType(metaclass, class2);
        
this;
        JVM INSTR swap ;
        metaClass;
        JVM INSTR pop ;
        
return ScriptBytecodeAdapter.invokeMethodN(class1, metaClass, "invokeMethod"new Object[] {
            
this, method, arguments
        });
    }

    
public Object getProperty(String property)
    {
        Class class1;
        MetaClass metaclass;
        class1 
= HelloWorld.class;
        Class class2 
= groovy.lang.MetaClass.class;
        
if(!ScriptBytecodeAdapter.compareEqual(metaClass, null))
            
break MISSING_BLOCK_LABEL_118;
        metaclass 
= (MetaClass)ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.invokeStaticMethodN(class1, org.codehaus.groovy.runtime.ScriptBytecodeAdapter.class"initMetaClass"new Object[] {
            
this
        }), class2);
        metaclass;
        (MetaClass)ScriptBytecodeAdapter.castToType(metaclass, class2);
        
this;
        JVM INSTR swap ;
        metaClass;
        JVM INSTR pop ;
        
return ScriptBytecodeAdapter.invokeMethodN(class1, metaClass, "getProperty"new Object[] {
            
this, property
        });
    }

    
public void setProperty(String property, Object value)
    {
        Class class1;
        MetaClass metaclass;
        class1 
= HelloWorld.class;
        Class class2 
= groovy.lang.MetaClass.class;
        
if(!ScriptBytecodeAdapter.compareEqual(metaClass, null))
            
break MISSING_BLOCK_LABEL_121;
        metaclass 
= (MetaClass)ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.invokeStaticMethodN(class1, org.codehaus.groovy.runtime.ScriptBytecodeAdapter.class"initMetaClass"new Object[] {
            
this
        }), class2);
        metaclass;
        (MetaClass)ScriptBytecodeAdapter.castToType(metaclass, class2);
        
this;
        JVM INSTR swap ;
        metaClass;
        JVM INSTR pop ;
        ScriptBytecodeAdapter.invokeMethodN(class1, metaClass, 
"setProperty"new Object[] {
            
this, property, value
        });
        
return;
    }

    
public void setMetaClass(MetaClass value)
    {
        Class class2;
        Class class1 
= HelloWorld.class;
        class2 
= groovy.lang.MetaClass.class;
        value;
        (MetaClass)ScriptBytecodeAdapter.castToType(value, class2);
        
this;
        JVM INSTR swap ;
        metaClass;
        JVM INSTR pop ;
    }

    
void super$1$wait()
    {
        
super.wait();
    }

    String 
super$1$toString()
    {
        
return super.toString();
    }

    
void super$1$wait(long l)
    {
        
super.wait(l);
    }

    
void super$1$notify()
    {
        
super.notify();
    }

    
void super$1$notifyAll()
    {
        
super.notifyAll();
    }

    Class 
super$1$getClass()
    {
        
return super.getClass();
    }

    
boolean super$1$equals(Object obj)
    {
        
return super.equals(obj);
    }

    Object 
super$1$clone()
    {
        
return super.clone();
    }

    
int super$1$hashCode()
    {
        
return super.hashCode();
    }

    
void super$1$wait(long l, int i)
    {
        
super.wait(l, i);
    }

    
void super$1$finalize()
    {
        
super.finalize();
    }

    
transient MetaClass metaClass;
    
public static Long __timeStamp;

    
static 
    {
        Long long1;
        Class class1 
= HelloWorld.class;
        Class class2 
= groovy.lang.MetaClass.class;
        long1 
= new Long(0x1121e0ead4dL);
        Long _tmp 
= long1;
        __timeStamp 
= (Long)long1;
    }
}



附:通过与Java的比较,迅速掌握Groovy
posted on 2007-03-03 01:16 山风小子 阅读(4388) 评论(11)  编辑  收藏 所属分类: Groovy & Grails

评论:
# re: Java世界中动态语言的选择--Groovy ! 2007-03-03 01:55 | 灵魂机器
真的太奇怪了,为什么eclipse 和 netbeans 都对ruby 支持而对groovy 不支持呢?至少目前netbeans 6.0M6就只支持jruby,而且我感觉ruby 比groovy 火多了,sun对jruby 的支持力度似乎大得多。因此我认为这张图是因为groovy 是一个英文单词,而其他的不是,所以搜出来的结果当然groovy多  回复  更多评论
  
# re: Java世界中动态语言的选择--Groovy ! 2007-03-03 02:03 | 山风小子
@灵魂机器
netbeans5就已经支持Groovy了 :)
NetBeans IDE新增对Groovy脚本语言的支持 2005.06.23 来自:CSDN ( http://news.csdn.net/n/20050623/22622.html )
eclipse上也有Groovy插件可用 :)
Groovy IDE: http://groovy.codehaus.org/Eclipse+Plugin
Sun的决策向来存在问题,所以对于它支持JRuby力度较大我一点都不意外 :)
最后我不知道google有没有语义相关功能,所以就不多说了 :)  回复  更多评论
  
# re: Java帝国的王储--Groovy ! 2007-03-11 15:42 | Jcat
很有兴趣,最近也十分关注Groovy

BTW,IntelliJ IDEA的插件GroovyJ还是蛮好用的(有的功能,如code completing,还在开发中,值得期待)  回复  更多评论
  
# re: Java帝国的王储--Groovy ! 2007-03-11 21:43 | 山风小子
@Jcat
可惜我钟爱Eclipse,不过Groovy IDE还不错,用着挺顺手的 :)
以后请多指教 :)  回复  更多评论
  
# re: Java帝国的王储--Groovy ! 2007-03-12 03:04 | sinoly
语言的战争。。。。
不过还是我的那个观点,没有人可以选择到绝对对的方向,但是我们能做到的是选择一个不是错误的方向  回复  更多评论
  
# re: Java帝国的王储--Groovy ! 2007-03-12 09:23 | 山风小子
@sinoly
其实语言主流与否无关紧要,最重要的是我们能利用她高效地解决问题 :)
以前在下研究过Jython--一种不耀眼的语言,Python的Java实现版本,但当我想让她与Java混编时,发现其无法无缝结合Java,需要转换,所以听说Groovy与Java能无缝与Java结合,并具有我想要的动态特性,当机立断,转学Groovy,在学习的过程中,感受到她的魅力,所以想把这种卓越的语言介绍给还不了解她的朋友,仅此而已 :)  回复  更多评论
  
# re: Java帝国的王储——Groovy ! 2007-06-17 06:25 | piggy
现在硅谷新创的网络公司80%是基于Rails在开发,所以Sun和MS都积极插一脚搞Ruby不难理解。语言本身好坏不是关键,关键是有没有杀手级应用。  回复  更多评论
  
# re: Java帝国的王储——Groovy ! 2007-06-17 12:05 | 山风小子
@piggy
您说的很有道理,希望Grails早日成熟起来 :)  回复  更多评论
  
# re: Java帝国的王储——Groovy ! 2007-11-23 12:48 | milo
@灵魂机器
netbeans对Grooby有支持  回复  更多评论
  
# re: Java帝国的王储——Groovy ! 2008-02-04 11:13 | 范连洲
groovy之所以难反编译,是因为它依赖于java,实现走了很多弯路,希望groovy有自己专有有编译器,不依赖于java,这样应该可以大大提高效率,兼容java也应该不难。  回复  更多评论
  
# re: Java帝国的王储——Groovy ![未登录] 2008-02-27 22:56 | h
这样不会更慢么?  回复  更多评论
  



标题  
姓名  
主页
验证码 *  
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-10-13 15:24 编辑过