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

1
2
3
4
5
class HelloWorld {
  static void main(String[] args) {
    println "Hello, world!"
  }
}

综上所述,选择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官方网站上的例子,在官方网站上还有许多教程和应用实例,大家不妨去看看。
利用已存在的Java类库:

1
2
3
4
5
6
7
8
9
10
11
12
13
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的源码:

1
2
3
4
5
class HelloWorld {
  static void main(String[] args) {
    println "Hello, world!"
  }
}

HelloWorld.class反编译得到的Java文件HelloWorld.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// 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;
    }
}
Share

Related Posts

0 Responses to “Java帝国的王储—Groovy !”


  • No Comments

Leave a Reply