`
61party
  • 浏览: 1123249 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

转贴:Java语言的十大问题及引申思考

阅读更多

转自:http://blog.163.com/gordonkkk/blog/static/63425684200962795039630/

从CSDN上看到一篇批评Java语言诸多问题的翻译文章,原文作者是Mario Fusco。他指出了Java语言落后于时代,积重难返的10个问题。看过之后引起了我的一些联想。下面列出他所说的10大问题。桔黄色字体是我一点点不成熟的思考。

1、缺少闭包(closure):我想这个不需要解释了。函数式编程已经存在几十年了,但最近几年,它们获得了越来越多的关注,最主要的原因,是它可以自然地编写并行程序。我部分的同意Joshua Bloch强调在Java中引入闭包的问题需要再想一想(BGGA提议的方式真的很糟),至少闭包的缺失,使得在Java中做任何真正的函数式编程都是不可能的。

闭包的定义和特性,Java里很难体会,因为Java里没有真正意义的闭包,我也是从JavaScript里对闭包有了大致的了解。Java是个逻辑严格自洽的语言,严密到了一定程度,以至于目前的Java里根本没有闭包的容身之处——闭包中引用的外围局部变量,到底放在堆栈中,还是托管堆中?他们的作用域和生存期如何处理?又该如何被GC回收?但闭包确实是好东西。即使我自认为是一个Java程序员,在写多了JavaScript代码又回到Java后,对于不能随时随地的写一段{}括起来的代码块,感觉很不自由。针对闭包问题,Java还是有自己能将就的办法,那就是内部类。至少还有内部类,至少内部类还有一部分的闭包特性,使得一些优雅的设计(如集合框架迭代器)能够存在。

2、缺少一等函数:这个问题与前一个有些关联,但我认为它更糟糕。在Java里,要达到类似效果的唯一方式,是使用著名的、丑陋悲惨的单方法匿名内部类,但这看上去的确是一个拙劣的方法。甚至在C#中,也通过代理机制,提供了一个更好的实现。

所谓一等函数,面向对象的Java没有似乎不能强求。但它带来的问题,就是Java里有时候策略模式的拙劣实现。C#作为一个高级语言,又是强类型的,也一样可以有delegate,匿名方法,甚至Lambda表达式。Java里就只能生造出一个单方法接口,new一个无意义的对象,来承载其中的函数。

3、原生类型(Primitive types):如果在Java中一切皆对象,那是多么完美啊,但他们偏偏不这样设计。因而,这一点导致了一些问题,比如,不能把一个int放到集合(Collection)里,这个在Java5中通过自动装箱特性得到了解决(下面会提到)。它也造成了传值与传引用上的困扰,原生类型数据是通过值传给方法的(复制一份拷贝,然后传给函数),而真正的对象是通过传递(译注:其实是复制对象地址再传递,因此应该也是传值方式,只是由于函数内部可通过这个对象地址访问对象,因此效果上类似传引用)。
这似乎不是个太大的问题,我觉得这里有些吹毛求疵了。Effective Java里建议在新的代码中不要使用原生类型,这正是一个建设性的做法。Java并不是没有原生类型的包装类,不去使用的责任应该由程序员来负,而不是Java。

4、自动装箱(Autoboxing)和自动拆箱(autounboxing):这个特性是为了解决因原生类型的存在所导致的问题,在Java5引入的。它允许静默地转换原生类型到相应的对象,但这常常导致其它的问题。比如Integer可以为null,但int不能,因此这时JVM只能抛出一个难以调试的空指针异常(NullPointerException)。此外,它还可能导致其它奇怪的行为,就像下面的例子,我们就很难理解,变量test为什么是false:
Intger a = new Integer(1024);
Intger b = new Integer(1024);
boolean test = a < b || a == b || a > b;
这个例子老实说我认为很不恰当。诚然,a和b都是对象,a<b和a>b的判断中的自动拆箱和a==b的未拆箱造成了混淆,但要知道自动拆箱和装箱本身只是便利措施,不能对它要求更多。这里更有问题的其实是==判断。String类遇到==也是一样的问题,Java未在语言级别提供==的算符重载,个人认为是一种失策。

5、缺少范型具类化:范型是Java5引入的一个很酷的特征,但是为了保持与旧版本Java的兼容性,导致缺失某些重要的特性,尤其是不能在运行时反省范型的类型。例如,你有一个方法,接受List< ?>参数,如果传进来一个List< String>,你却不能知道运行里该范型的确切类型。同理,你也不能创建范型数组。这意味着,尽管这样的代码看起来很自然,但却不编译不了。

擦除,意味着在JVM中所谓泛型,已经彻底还原成了基本的未参数化形式。Java的泛型,自我学习的第一天起,就不停的被告知,被提醒“擦除”的概念。擦除带来的好处只有一个,就是和旧代码兼容。擦除带来的不足却有很多,而补偿起来却非常困难。同样的,自从我学习Java泛型的第一天起,就不停的提醒我自己,你知道Java泛型能做什么,现在更要知道它做不到什么。有时候我们可以简单的多引入一个参数记录类型的Class对象,但更多的时候,享用泛型解决问题,此路不通。

6、不可避免的范型警告:你有发现过自己陷入不可能去掉的关于范型的警告么?如果你像我一样大量使用范型,我打赌你碰到过。事实上,是这个问题的规模化症状,让他们认为需要引入一个特定的注解 (@SuppressWarnings("unchecked")) 来处理这种情况,我觉得,范型应该可能被设计的更好。

泛型的转换警告我感觉是很无厘头的。从一个参数类型转换到另一个,编辑器告诉我它可能是不安全的。为什么是不安全的?因为它记不住类型参数,因为类型参数运行时要被擦除......既然自己无法做泛型层面的类型检查,把维护类型安全的责任推给了程序员,又何必假模假式的做出警告?强制类型转换的时候怎么不来提醒转换有可能失败呢?两者的区别又有多大呢?


7、不能传void给方法调用:我得承认,这种给方法传递void的需求,乍一看有些怪异。我喜欢DSL,当我实现自己的DSL库(lambdaj)的一个特定特性时,我不得不需要一个方法声明成这样的签名:void doSomething(Object parameter),这里为这个方法传进来的参数parameter,是另一个方法调用的结果,它唯一的目的,是注册调用(的对象)自身,以可以在以后执行它。让我吃惊的是,即使println方法返回void,看上去也并没有一个好理由,不允许我把代码写成这样,:
doSomething(System.out.println("test"));

这条我基本没看懂。我很同意他那句话“这种给方法传递void的需求,乍一看有些怪异”。如果是我的话,完全可以不设计这样别扭的API。void就是void,不应该再有更多的责任。想想JavaScript中Null和Undefined之间造成的混淆吧,Java里就别来这套了。

8、没有原生的代理机制:代理是一种非常有效和应用广泛的模式,但Java提供的代理机制,只针对接口,而不是具体类。这是为什么象cblib这样提供这种机制的库,被如此多的主流框架,如Spring和Hibernate,采用的原因。此外,由于cglib通过运行时创建被代理类的子类来实现的,因此这些种方式有一个众所周知的限制——不能代理final类,比如String.

final类是用来做什么的,不就是防止被改变的吗?以它作为引用的类型,可以放心的认为对象的行为一定和类的定义中写的一模一样,这才是final的用意。从这个角度考虑,想要代理final类,与final的语义起了冲突。asm-cglib是很好的第三方工具,我认为足以满足一般性的需求了。但如果Java能有一种能语言级的代理的支持,显然会更好。无论以何种方式处理,总比运行时动态创建被代理的子类效率高,api的使用难度也会更低。

9、差劲的Switch……case语句:Java规定,switch……case只能选择int和enum(Java5开始)。这一点如果跟更现代的语言如Scala相比,看起来简直太弱了。

这个问题似乎在目前的Java中消失了.....很大的一个原因是,由于Java中Switch太烂,以至于很少使用了......

10、受检查异常(Checked exception):类似原生类型,受检查异常也已经成为Java的一个罪孽之源。它迫使程序员必须做下面两件极其糟糕讨厌的事情中的一个:让你的代码里充斥大量的、糟糕难读的、容易出错的try……catch语句,而这样做的最大意义,只是将捕获的异常,包装成运行时异常,然后再重新抛出;或者是让大量的抛出声明子句污染你的API,让接口缺少灵活性和可扩展性。

这是Java一个广泛被批评的地方。我觉得Java的受检查异常还是有意义的。在很多所谓一定会出异常,一定要考虑异常处理的地方,受检查异常是合理的——你要么应当立即处理它,要么必须抛出它,真正必须处理的异常出现在接口中,并不算污染API吧。现在的问题是,受检查的异常被大量滥用。我个人认为,可以将这些异常化为运行时异常,并做一个小小的标记,在未被Catch或Throw时引起编译器警告,再引入一个特定的,忽略该警告的注解。这样可能会是一个圆满的解决方法。


11、痛苦的线程同步编程:这是我自己认为Java的问题。Java的线程机制实在有点扯。你必须在脑中模拟一切运行时的可能性,而任何微小的代码变化都可能破坏你原先的设想。在这种情况下小心翼翼的在线程间通讯和同步。编写线程安全的复杂代码,简直是一场头脑风暴,并不是任何人都能胜任这样的工作。这个问题和Java没有闭包,不能进行函数式编程是紧密相关的,目前的Java很难做的更好,现有的API已经在尽量降低使用难度了。但涉及到实际业务的复杂需求时,Java不能提供任何语言级别的协助,还是让人相当沮丧。当然事情发生在我这里时,我只能说自己的水平差,不是一个足够优秀的Java程序员。

分享到:
评论

相关推荐

    java编程事项(转载收集整理版)

    1. **基本语法**:Java是一种静态类型的面向对象编程语言,其语法严谨。学习Java首先要了解变量声明、数据类型(如int、String等)、运算符、控制结构(如if语句、for循环、while循环)以及方法定义。 2. **类与...

    转贴:利用钩子技术控制进程创建.txt

    - **稳定性问题**:不当的Hook实现可能导致系统崩溃或其他不稳定现象。 - **安全风险**:恶意软件可能滥用此技术进行攻击活动,因此在设计和实现时必须考虑安全性。 总之,利用钩子技术控制进程创建是一项复杂而...

    flex和java进行CRUD操作(转贴)

    开发过程中,利用Flex的调试器和Java的日志框架如Log4j,可以帮助排查问题,跟踪代码执行流程。 10. **部署与维护** 最后,完成CRUD功能的Flex应用需要与Java服务打包并部署到相应的服务器环境,如Tomcat或JBoss...

    android和java面试大全集

    史上最全的android和java面试文档集。包括有: java程序员面试宝典.txt Java面试宝典2011版-1C,Java基础部分.doc... Java面试题及答案(基础题122道) - 在梦想与现实之间徘徊 - JavaEye技术网站.mht 等等,还有好多。

    java面试大全(中软国际的大公司)

    通过阅读"java面试题及答案(基础题122道,代码题19道).doc"和"java练_习_题.doc",可以针对性地复习和练习这些知识点,而"JAVA基础笔试.doc"和"中软的面试题(转贴).doc"则可能包含实际的面试题目,可以帮助模拟...

    Java SafeEngine API接口说明

    Java SafeEngine API接口说明是上海市数字证书认证中心有限公司开发的数字证书系统的接口说明,旨在提供给开发者使用Java语言开发安全的数字证书应用程序。该API接口提供了丰富的功能,包括基本项获取、密钥库、证书...

    使用Struts2开发Java Web应用程序(转贴)

    Struts2是一个强大的Java Web应用框架,源自WebWork2,结合了Struts1.x的优点,致力于简化企业级应用的开发、部署和维护。它强调在开发过程中提高效率,同时注重部署的简便性和后期维护的便利性。Struts2的易用性...

    Axis学习笔记(网页转贴)

    **Axis学习笔记(网页转贴)** Axis是一个开源的Java库,主要用于创建和使用Web服务。它是Apache软件基金会的一部分,广泛应用于开发基于SOAP(简单对象访问协议)的Web服务。本学习笔记将深入探讨Axis在Web服务开发...

    易语言源码动网转贴.rar

    易语言是一种基于中文编程的计算机程序设计语言,它旨在降低编程技术门槛,让不懂英文的用户也能进行软件开发。易语言的源码是其程序设计的核心部分,包含了程序的逻辑结构、功能实现以及数据处理等关键信息。"动网...

    转贴:四十岁的男人要像孩子一样养.doc

    同时,保持积极乐观的态度,帮助他们以正确的心态面对健康问题,促进身体的快速恢复。 饮食习惯上,四十岁的男性更倾向于简单、天然的食材,他们对复杂的烹饪不再感兴趣,而是注重食品的品质和健康。作为伴侣,了解...

    易语言动网转贴.rar

    易语言是中国本土开发的一种编程语言,它以汉字作为程序代码的基本元素,降低了编程的门槛,使得不懂英文的用户也能进行程序开发。"动网转贴"可能是基于易语言编写的一个功能模块或者工具,用于在论坛或者网站之间...

    动易系统的论坛转贴工具

    动易论坛转贴工具采用了一种通用的标记语言转换技术,如UBB(Unified Bulletin Board Code),这是一种类似于HTML的文本标记语言,用于在论坛中表示富文本。当用户选择论坛帖子时,工具会自动将帖子的HTML代码转换为...

    电子政务-导电泡棉转贴装置.zip

    6. **维护与保养**:提供关于导电泡棉及转贴装置的日常维护、清洁、替换等方面的指导,以延长设备使用寿命。 7. **未来趋势**:探讨电子政务领域中导电材料和技术的未来发展,可能涉及新材料的研发、更高效的转贴...

    ZZ: 时间管理方法(转贴)

    【时间管理方法(转贴)】 时间管理是个人和团队高效工作的关键,它涉及到如何规划、组织和优化日常活动,以便在有限的时间内完成更多的任务并实现目标。在这个快速发展的IT行业中,良好的时间管理能力可以帮助程序员...

Global site tag (gtag.js) - Google Analytics