- 浏览: 308238 次
- 性别:
- 来自: 天津
文章分类
最新评论
-
suxiaojack:
15题,就是拿杨辉三角填充空格,答案应该是C(38,19)吧? ...
Project Euler解题汇总 013 ~ 022 -
songhaikang:
这篇文章挺好的,跟着你的步骤很快就可以入门了。非常感谢。
[转贴]Derby入门 —— (1) -
Eastsun:
呵呵,我没有Android的机器,所以兴趣不大
使用Java写的GVmaker虚拟机(开源) -
crapricorn:
那个版本的用不了虚拟键盘啊 呵呵 我们的手机没有实体键盘呀 所 ...
使用Java写的GVmaker虚拟机(开源) -
Eastsun:
crapricorn 写道希望sun侠能做出个android平 ...
使用Java写的GVmaker虚拟机(开源)
原文地址:Java.next: Common Ground
翻 译:Eastsun
本文是Java.next系列的第一部分。在这一部分,我将探讨作为Java.next的语言所具有的共同特征。
我选择了四种语言作为“Java.next”的代表:Clojure,Groovy,JRuby,以及Scala。乍看起来,这几种语言有着很大的不同。Clojure是Lisp方言;Groovy是作为“类Java”的选择;JRuby即具有Ruby语言的优雅,同时也有着Rails所带来的优势;与其他都不一样的是Scala,它有着静态语言所具有的特点。
正如你所料想的一样,有很多关于这些语言中谁才是最好的辩论。之所以有着这么多的辩论,很大程度上是因为这些语言有着很多共同点。它们有着一个共同的演变背景:Java语言。Java语言所具有的优点以及缺陷影响着这些语言的设计方向。
在这篇文章中,我着重从下面两个方面来阐述这些语言的共同点:
☆ 过去的10年中,我们在基于虚拟机、面向对象的语言编程中得到了很多关于如何开发易读的、可维护的应用。Java.next吸取了这些成果,使得这些语言更注重于问题的本质而不是形式。
☆ “本质 VS 形式”的设计理念使得编程方式发生了很大的改变,这种观念的变化比以前从C/C++到Java的转变更大。
我将Java.next所具有的共同优点概括为以下八点:
● 一切皆对象
● 简洁的属性定义方式
● 易用的集合类
● 函数式编程
● 运算符重载
● 可维护的异常处理
● 给已有类增加新方法
● 创建新的语言结构
一切皆对象
在Java中,我们每时每刻都要面对对象类型与基本类型的不同之处。这种不同导致三个实际问题:
1.API必须写两份:一个针对对象类型;一个针对基本类型。更糟糕的情形是需要重写多份:一个针对对象类型,然后对每一个基本类型各写一份。
2.默认的数值类型有着范围限制,一旦越界,程序会以诡异的形式中断。
3.对于那些高精度类型(译者注:指BigInteger等类型),你不能使用直观的数学操作符(+,-,etc.)来操作它们。
在Java.next中,一切皆是对象。你可以在所有的类型上使用相同的语法调用方法。
简洁的属性定义方式
在Java中建立一个属性,你必须定义一个域,一个Getter,一个Setter,以及(通常)一个相应的构造函数,每一个定义都需要适当的访问修饰词。在Java.next中,你可以毕其功于一役。
如果你需要复写(或删除)一个Getter,Setter或是构造函数,你也可以做到,而无需重写其它部分。
这还不是全部。所有这些语言信奉TMTOWTDI (There's More Than One Way To Do It),因此这儿不止一种方式可以实现上面同样的要求。
易用的集合类
Java.next针对大部分重要的集合类提供了便利的语法:array与map。此外,你可以通把将函数作为参数将一系列操作连贯起来,而避免使用Java中那种显式的迭代或循环方式。譬如:找出100以内的奇完全平方数:
对哈希表(字典)有着同样便利的操作。
函数式编程
上面集合类的便利使用只是函数式编程的一个特殊情形。Java.next中函数作为一等公民,支持将函数作为参数,将函数作为返回值,以及支持闭包。举一个简单的例子:创建一个函数adder,使得能计算与一个运行时指定的值之和:
运算符重载
在Java中,你不能重载运算符。因此你只能像这样操作BigDecimal:
Java.next允许你重载运算符。这样你能够创建新的类型并使得它像内建类型一样工作。譬如你能够新建一个ComplexNumber或RationalNumber,使其支持+,-,*,/运算符:
可维护的异常处理
检查型异常(Checked Exception)是一个失败的试验。检查型异常的处理代码使得Java代码变得臃肿并掩盖了问题的关键。更糟糕的是,检查型异常使得代码的维护变得困难。
Java.next不要求你声明检查型异常,也不要求你显式的处理检查型异常。这表明Java平台的其他语言完全可以避免Java语言中丑陋的检查型异常。
给已有类增加新方法
在Java中,你不能给已有类添加方法。这使得面向对象模型变得很荒谬,开发者需要创建一些工具类,而这是与OO相违背的。
在Java.next中,你能够给已有类增加方法:
创建新的语言结构
Java包括Java语言以及API库,这两部分是截然不同的:你能够创建新的API库,但你不能够添加新的语言特性。
而在Java.next中,API库与语言特性没有明显的界线。你能够创建新的语言结构使得它像核心语言特性一样工作。例如,Clojure提供了一个and函数:
你需要解决的不一定都是这样二元化的问题。你可能需要一个most函数,当它参数中大部分真时返回true。Clojure中没有这个,但你可以自己动手写一个:
这里的关键之处不是“我的语言是否需要一个most条件?”,而是不同的领域有不同的需求。在Java.next中,语言与库的界限被最小化,你可以添加适当的语言特性以适应你的领域需求,而不是相反。
再举一个例子,考虑Ruby的attribute语法:
attr_accessor是Ruby固有的语法. dsl_attribute是我写的一个库方法,它允许你在做赋值操作的时候省略"=",像下面这样:
结论
这些Java.next语言有着相当多的共同点。尽管我使用一些孤立的例子来说明这些特点,但只有将它们一起使用时才能体现这些语言的真正威力。综合Java.next的所有特征,会导致一个完全不同的编码方式:
★ 在编码时你不再需要为了代码的可测试与适应性而采取保守方式:使用类工厂,设计模式以及依赖注入。作为代替,你可以构建一个最小解决方案,并随时改进它。
★ 在Java.next中,你可以开发更适合你问题的内部领域特定语言(DSLs)。
以我的经验,这种编码方式能将代码量减少一个数量级,同时提高代码的可读性。
很多人在寻找“next big language”。下一个“big language”已经在这里,但它不是一个单独的语言,而是一组概念的综合体,就如Java.next中表现出来的那样。
过渡到Java.next配的上"big"这个称号吗?绝对可以。根据我的经验,一旦你作出转变,每一步都有着巨大的进步,包括学习曲线以及生产力。
在这个系列的后续部分,我将讨论这些语言的不同之处。
翻 译:Eastsun
本文是Java.next系列的第一部分。在这一部分,我将探讨作为Java.next的语言所具有的共同特征。
我选择了四种语言作为“Java.next”的代表:Clojure,Groovy,JRuby,以及Scala。乍看起来,这几种语言有着很大的不同。Clojure是Lisp方言;Groovy是作为“类Java”的选择;JRuby即具有Ruby语言的优雅,同时也有着Rails所带来的优势;与其他都不一样的是Scala,它有着静态语言所具有的特点。
正如你所料想的一样,有很多关于这些语言中谁才是最好的辩论。之所以有着这么多的辩论,很大程度上是因为这些语言有着很多共同点。它们有着一个共同的演变背景:Java语言。Java语言所具有的优点以及缺陷影响着这些语言的设计方向。
在这篇文章中,我着重从下面两个方面来阐述这些语言的共同点:
☆ 过去的10年中,我们在基于虚拟机、面向对象的语言编程中得到了很多关于如何开发易读的、可维护的应用。Java.next吸取了这些成果,使得这些语言更注重于问题的本质而不是形式。
☆ “本质 VS 形式”的设计理念使得编程方式发生了很大的改变,这种观念的变化比以前从C/C++到Java的转变更大。
我将Java.next所具有的共同优点概括为以下八点:
● 一切皆对象
● 简洁的属性定义方式
● 易用的集合类
● 函数式编程
● 运算符重载
● 可维护的异常处理
● 给已有类增加新方法
● 创建新的语言结构
一切皆对象
在Java中,我们每时每刻都要面对对象类型与基本类型的不同之处。这种不同导致三个实际问题:
1.API必须写两份:一个针对对象类型;一个针对基本类型。更糟糕的情形是需要重写多份:一个针对对象类型,然后对每一个基本类型各写一份。
2.默认的数值类型有着范围限制,一旦越界,程序会以诡异的形式中断。
3.对于那些高精度类型(译者注:指BigInteger等类型),你不能使用直观的数学操作符(+,-,etc.)来操作它们。
在Java.next中,一切皆是对象。你可以在所有的类型上使用相同的语法调用方法。
; clojure (. 1 floatValue) 1.0 // groovy 1.floatValue() ===> 1.0 # ruby 1.to_f => 1.0 // scala 1.floatValue res1: Float = 1.0
简洁的属性定义方式
在Java中建立一个属性,你必须定义一个域,一个Getter,一个Setter,以及(通常)一个相应的构造函数,每一个定义都需要适当的访问修饰词。在Java.next中,你可以毕其功于一役。
; clojure (defstruct person :first-name :last-name) // groovy class Person { def firstName def lastName } # ruby Person = Struct.new(:first_name, :last_name) // scala case class Person(firstName: String, lastName: String)
如果你需要复写(或删除)一个Getter,Setter或是构造函数,你也可以做到,而无需重写其它部分。
这还不是全部。所有这些语言信奉TMTOWTDI (There's More Than One Way To Do It),因此这儿不止一种方式可以实现上面同样的要求。
易用的集合类
Java.next针对大部分重要的集合类提供了便利的语法:array与map。此外,你可以通把将函数作为参数将一系列操作连贯起来,而避免使用Java中那种显式的迭代或循环方式。譬如:找出100以内的奇完全平方数:
; clojure (filter (fn [x] (= 1 (rem x 2))) (map (fn [x] (* x x)) (range 10))) (1 9 25 49 81) // groovy (1..10).collect{ it*it }.findAll { it%2 == 1} ===> [1, 9, 25, 49, 81] # ruby (1..10).collect{ |x| x*x }.select{ |x| x%2 == 1} => [1, 9, 25, 49, 81] // scala (1 to 10).map(x => x*x).filter(x => x%2 == 1) res20: Seq.Projection[Int] = RangeMF(1, 9, 25, 49, 81)
对哈希表(字典)有着同样便利的操作。
函数式编程
上面集合类的便利使用只是函数式编程的一个特殊情形。Java.next中函数作为一等公民,支持将函数作为参数,将函数作为返回值,以及支持闭包。举一个简单的例子:创建一个函数adder,使得能计算与一个运行时指定的值之和:
; clojure (defn adder [x] (fn [y] (+ x y))) // groovy adder = { add -> { val -> val + add } } # ruby def adder(add) lambda { |x| x + add } end // scala def sum(a: Int)(b: Int) = a + b
运算符重载
在Java中,你不能重载运算符。因此你只能像这样操作BigDecimal:
// Java math balance.add(balance.multiply(interest));
Java.next允许你重载运算符。这样你能够创建新的类型并使得它像内建类型一样工作。譬如你能够新建一个ComplexNumber或RationalNumber,使其支持+,-,*,/运算符:
; Clojure (+ balance (* balance interest)) // Groovy balance + (balance * interest) # JRuby balance + (balance * interest) // Scala balance + (balance * interest)
可维护的异常处理
检查型异常(Checked Exception)是一个失败的试验。检查型异常的处理代码使得Java代码变得臃肿并掩盖了问题的关键。更糟糕的是,检查型异常使得代码的维护变得困难。
Java.next不要求你声明检查型异常,也不要求你显式的处理检查型异常。这表明Java平台的其他语言完全可以避免Java语言中丑陋的检查型异常。
给已有类增加新方法
在Java中,你不能给已有类添加方法。这使得面向对象模型变得很荒谬,开发者需要创建一些工具类,而这是与OO相违背的。
// Java (from the Jakarta Commons) public class StringUtils { public static boolean isBlank(String str) { int strLen; if (str == null || (strLen = str.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if ((Character.isWhitespace(str.charAt(i)) == false)) { return false; } } }
在Java.next中,你能够给已有类增加方法:
; Clojure (defmulti blank? class) (defmethod blank? String [s] (every? #{\space} s)) (defmethod blank? nil [_] true) // Groovy String.metaClass.isBlank = { length() == 0 || every { Character.isWhitespace(it.charAt(0)) } } # Ruby (from Rails) class String def blank? empty? || strip.empty? end end // Scala implicit def strWrapper(s :String) = new { def isBlank = s.forall{ _.isWhitespace } }
创建新的语言结构
Java包括Java语言以及API库,这两部分是截然不同的:你能够创建新的API库,但你不能够添加新的语言特性。
而在Java.next中,API库与语言特性没有明显的界线。你能够创建新的语言结构使得它像核心语言特性一样工作。例如,Clojure提供了一个and函数:
; clojure (and 1 2) => 2
你需要解决的不一定都是这样二元化的问题。你可能需要一个most函数,当它参数中大部分真时返回true。Clojure中没有这个,但你可以自己动手写一个:
; clojure (most 1 2) => true (most 1 2 nil) => true (most 1 nil nil) => false
这里的关键之处不是“我的语言是否需要一个most条件?”,而是不同的领域有不同的需求。在Java.next中,语言与库的界限被最小化,你可以添加适当的语言特性以适应你的领域需求,而不是相反。
再举一个例子,考虑Ruby的attribute语法:
# Ruby class Account attr_accessor :name dsl_attribute :type end
attr_accessor是Ruby固有的语法. dsl_attribute是我写的一个库方法,它允许你在做赋值操作的时候省略"=",像下面这样:
# normal attributes account.name = "foo" # equals-free attributes account.type checking
结论
这些Java.next语言有着相当多的共同点。尽管我使用一些孤立的例子来说明这些特点,但只有将它们一起使用时才能体现这些语言的真正威力。综合Java.next的所有特征,会导致一个完全不同的编码方式:
★ 在编码时你不再需要为了代码的可测试与适应性而采取保守方式:使用类工厂,设计模式以及依赖注入。作为代替,你可以构建一个最小解决方案,并随时改进它。
★ 在Java.next中,你可以开发更适合你问题的内部领域特定语言(DSLs)。
以我的经验,这种编码方式能将代码量减少一个数量级,同时提高代码的可读性。
很多人在寻找“next big language”。下一个“big language”已经在这里,但它不是一个单独的语言,而是一组概念的综合体,就如Java.next中表现出来的那样。
过渡到Java.next配的上"big"这个称号吗?绝对可以。根据我的经验,一旦你作出转变,每一步都有着巨大的进步,包括学习曲线以及生产力。
在这个系列的后续部分,我将讨论这些语言的不同之处。
发表评论
-
JavaFX1.2的性能貌似有了很大的提升
2009-06-03 09:36 1981Osvaldo Pinali Doederlein's B ... -
Java.next:第二部分——与Java互操作
2008-09-19 23:05 1875原文地址:Java.next #2: Java Inter ... -
隐式转换:比动态类型更强大?
2008-09-16 18:37 1672本文内容主要来自Implicit Conversions: ... -
澄清:Java中只有按值传递,没有按引用传递!
2008-07-13 22:23 3982前言:在JAVA面试题解惑系列(五)——传了值还是传了引用 ... -
Ruby,Python不能威胁到Java的13个理由
2008-05-28 22:50 1481最近,danielstoner发表了一篇题为13 reas ... -
Java:进化的尽头
2008-05-28 17:45 1304原文地址:http://blog. ... -
《Effective Java》: Joshua Bloch访谈
2008-05-23 00:52 2613原文地址:Effective ... -
JSR 308:Java语言复杂度在恣意增长?
2008-05-20 13:54 1759原帖地址:http://www ... -
Sun能否让Java重振雄风?
2008-05-13 14:42 0原文地址:Can Sun rejuvenate Java? ... -
Groovy, JRuby, Jython, Scala:谁是胜利者?
2008-05-13 00:04 6557原文地址:Groovy, JRuby, Jython, Sca ... -
JAVA比C++更快?
2008-04-08 15:03 2043首先:我必须承认,我取JA ... -
在J2ME中模拟C语言中的文件操作
2008-02-27 00:09 1616最近在写一个模拟器(OR虚拟机),用于运行文曲星(一种 ... -
使用StAX解析XML:使用定制事件和编写 XML
2007-10-12 23:01 2103除了提供一个低层的基 ... -
使用StAX解析XML: 拉式解析和事件
2007-10-08 20:53 33052007 年 7 月 05 日 Streaming API ... -
[转载]Streaming API for XML (StAX) 简介
2007-10-07 13:35 2307Streaming API for XML (StAX) 是用 ... -
使用CookieHandler管理Cookie数据
2007-05-31 23:22 10886前言 : 因为只学过J2SE部分,对JAVA网络编程也不甚了 ... -
浅谈HTTP的无状态性
2007-05-30 01:26 2033HTTP是Hyper Text Transf ... -
用动态代理进行修饰
2007-04-11 16:26 1847动态代理为实 ... -
一种得到代码所在行号的方法
2007-04-02 20:03 3919RT,今天在论坛上看到有人提出这个问题,马上联想 ... -
网络词汇表
2007-04-01 13:33 1996【协议 】--- protocol,指通信双方通信时遵守的一 ...
相关推荐
1. **JDBC(Java Database Connectivity)**: JDBC是Java语言用来与各种数据库进行交互的一组接口和类。它允许开发者编写与数据库无关的代码,通过驱动程序实现与特定数据库的连接。 2. **Statement 和 ...
这个库是我在日常开发过程中积累下来的一些可复用组件,大部分都在我的工作项目和个人项目中有使用。 最新版本: Gradle集成 // core 核心库, 格式:jar和aar compile 'com.mcxiaoke.next:core:1.5.0' // task ...
java.util.LinkedList$ListItr.next(LinkedList.java:886) JMeter.plugins.functional.samplers.websocket.ServiceSocket.getResponseMessage(ServiceSocket.java:125) JMeter.plugins.functional.samplers....
1. 每次需要读取输入时才创建`Scanner`对象,但不要立即关闭。在所有读取操作完成后,一次性关闭`Scanner`。这样可以确保在所有需要读取的地方都有可用的`Scanner`。 2. 创建一个单独的`Scanner`对象,并将其作为...
java.util.ConcurrentModificationException 解决方法 ... at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793) at java.util.HashMap$KeyIterator.next(HashMap.java:828) 例如以下程序(转
它提供了 hasNext()、next() 和 remove() 三个方法,分别用于判断是否还有下一个元素、获取下一个元素和删除当前元素。 下面是一个抛出 ConcurrentModificationException 异常的示例代码: ```java public class ...
### Java学习笔记:Eclipse与Tomcat配置详解 #### 一、配置Eclipse工作空间 在开始JavaWeb项目的开发之前,首先需要配置好Eclipse的工作空间。本例中,我们设定工作空间为`D:\Program\eclipse\workspace`。工作...
1. **规范化问题**:当使用`java.sql.Date`时需要注意,它的日期部分是规范化的,即只包含日期而没有时间。这意味着任何传递给它的非规范化的时间信息(如小时、分钟等)将会被清除。 2. **日期格式的匹配**:在...
它的值也是从1970年1月1日开始的毫秒数,不过在创建`java.sql.Date`对象时,会忽略掉时间部分,确保始终表示一天的开始——0点0分0秒。因此,当你通过`new java.sql.Date(new java.util.Date().getTime())`创建`java...
如果我们把一个java.sql.Date值通过PrepareStatement的setDate方法存入数据库时,java程序会对传入的java.sql.Date规范化,非规范化的部分将会被劫取。 因此,在保存java.util.Date的精确值时,我们需要利用java....
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class Greenplum { public static void main(String args[]) throws Exception{ ...
在Java编程中,`java.util.ConcurrentModificationException` 是一个常见的运行时异常,通常发生在尝试并发修改集合时。这个异常的产生是由于集合类(如HashMap)的非线程安全特性,当你在一个线程中使用迭代器遍历...
总的来说,KingbaseV8 JDBC驱动为Java开发者提供了方便、高效的方式来连接和操作KingbaseV8数据库,确保了在不同Java版本下的兼容性,是开发过程中不可或缺的一部分。在实际项目中,根据具体运行环境选择合适的JDBC...
1. **Thin Driver**(也称为纯Java驱动):这是一款轻量级的驱动,完全由Java编写,无需Oracle客户端软件。它直接通过网络协议与数据库通信,适用于跨平台的Java应用程序。要使用Thin Driver,需要在项目中包含`...
myeclipse 9.1 破解 激活,java编写,适用于装有java环境的各种操作系统,win,linux,maxos 第一步:Usrcode中输入任意用户名 第二步:点击systemid一次,这时候会出现一行错误 Cannot find JNIWrapper native ...
为了解析`AndroidManifest.xml`,Java本身并不直接支持XML的解析,但我们可以引入第三方库,比如`AXmlResourceParser.jar`。这是一个轻量级的XML解析器,专门用于处理Android的XML资源文件,它能够解析APK中复杂的...
这个偏移量可以是一个固定的值,也可以是一个随机的值,以增强加密的安全性。 结论 Java 实现凯撒密码是一种简单而且实用的加密方法。通过使用 Java 语言,可以轻松地实现凯撒密码的加密和解密过程。这两种方法...