`
如若_晴
  • 浏览: 111690 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

为什么用Java:一个Python程序员告诉你

 
阅读更多

原文转自:http://news.cnblogs.com/n/541402/

 

英文原文:Why Java? Tales from a Python Convert

  这篇文章专门给程序员写的,普通读者慎入。原作者:Kevin Sookocheff 译者:Celia Zhen

  每当我告诉别人我一直在用 Java 工作时,大家的反应都是:

  “纳尼!Java?为啥是 Java?”

  说实话,本人刚开始的时候也是同样的反应。但是由于 Java 的类型安全,执行性能和坚如磐石的工具,我渐渐地开始欣赏 Java。同时我注意到,现在的 Java 已今非昔比——它在过去的 10 年间稳健地改善着。

  缘何是 Java?

  假设每天都用 Java 的想法还没有让君恶心到食不下咽,我在此重申 Java 已非你所了解的“吴下阿蒙”了。当 Python, Ruby, 和 Javascript 在“动态类型语言革命”™(我自己造的名词)中大放异彩时,Java 已经悄悄地借鉴了动态语言和函数式语言的很多吸引人的特性,同时保留了让 Java 和 JVM 晋级一流开发环境的先贤的努力成果。凭借大约 9 百万 Java 攻城狮的基层群体,Java 仍然是世界上最受欢迎的编程语言。我们不能仅仅因为 Java 的语法有一点点繁琐,就抹杀掉它所有的历史和开发工作。但是流行不等同于正确。下面我们就来看看是什么让 Java 如此大放异彩。

  Java 虚拟机(JVM)

  Java 虚拟机(JVM) 已经诞生 20 年了。在此期间,它被部署在成千上万的系统上,历经了无数的漏洞修复和性能提升。JVM 的优点有以下几个方面。首先,JVM 完美支持日志和监控, 这使你可以很方便地监控小到单个线程的性能指标。JVM 有世界上最优化的垃圾回收器之一,你可以根据优化吞吐量等因素灵活选择垃圾回收算法。最后,Java 承诺的“write once, run anywhere”终于得已实现——你可以轻松地在任何架构上部署一个 Java 应用(大家还是承认 applet 从来没有过吧)。为什么用 Scala 和 Clojure 这样新式语言的聪明人会选择 JVM 作为他们的执行环境呢?——因为 JVM 为你的代码提供了一个无出其右的分发环境。抛弃像 JVM 这样坚如磐石的工具是非常不合理的。

  库的支持

  如果你需要做点什么,很可能已经有非常好用且经过测试的 Java 库在等着你。Java 库大部分都是成熟并用于实际生产开发的。Google, Amazon, LinkedIn, Twitter 和很多 Apache 项目都很倚重于 Java。如果你用了 Java,你可以参考这些库和公司,从而借鉴伟大的程序员先驱们的工作。

  类型安全

  Java 的类型系统,虽然有时很繁琐,但是这使得你可以写出“好用”的代码。不再有运行调试,它使你可以依靠编译器而不是单元测试——单元测试只在你知道 bug 在哪里的时候才有用。类型安全也使你轻松的代码重构。Java 同时支持范型——Go 语言的最大诟病之一。再者,Guava 这样的库I以最小的样板和开销,标准化了创建类型安全的 API 的方法。 Java 编译器的改进也意味着你可以在享受类型安全的同时最小化范型所需的样板代码。

  并发性

  下面这条 tweet 总结了大多数动态语言的并行状态:

  Most JS/Python/Ruby apps… pic.twitter.com/hkDkjdxpFH

  — Reuben Bond (@reubenbond)

  Java 却有着对多线程和并行的一流支持。对于 Java 1.7, 许并行的 immutable 数据结构令你轻松地在线程间共享数据。Akka 库更进一步的提供了 Erlang 型的 Actors 来写并发和分布式的程序。我并不是在说 Java 比 Go 具有更好的并行支持,但是可以管理单个线程这一特性为 Java 应用提供了异步性能;而 Python 是做不到这点的。

  用最新的 Java 来编程

  现在你的心情可能已经从恶心变成好奇了,那么我们在 2015 年该如何写 Java 呢?从哪儿开始呢?首先,让我们回顾一些在 Java 7 和 Java 8 涌现的核心语言概念。

  迭代

  首先我们一起来看看迭代。下面是 Java 8 中的 for 循环:

List<String> names = new LinkedList<>();  // compiler determines type of LinkedList
// ... add some names to the collection
names.forEach (name -> System.out.println (name));

  或者是被大大简化的 for 关键词?

for (String name : names)
        System.out.println (name);

  这 2 种循环结构都比你平时看到的 for 循环简洁的多。

  Lambda 函数

  上面提到的第一个 for 循环引入了 Lambda 函数这个新概念。Lamda 函数,语法记作->, 是 Java 语言的一项重大改革,并从函数式编程中引入了一些概念。

  下面来看几个 Java 中 Lambda 函数的例子。

// Lambda Runnable
Runnable r2 = () -> System.out.println ("Hello world two!");

// Lambda Sorting
Collections.sort (personList, (Person p1, Person p2) -> p1.getSurName () .compareTo (p2.getSurName ()))

// Lambda Listener
testButton.addActionListener (e -> System.out.println ("Click Detected by Lambda Listener"));

  这里无法详细展开 Lambda 函数这个话题——http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764 文章提供了一个很好的切入点来更多地了解 Lambda 函数。

  

  Java 8 引入了流(stream)的概念,这为 Java 提供了很多现代函数式语言的特性。流是一种对集合上的一系列转换延迟执行的机制。比如我们来数一下以’A’开头的名字。首先想到的方法肯定是像下面这样:

List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = 0;
for (String name : names)  {
   if (name.startsWith ("A"))
       ++count;
}

  如果用流,上述就可以简化为首先将集合转换成流,然后使用函数:

List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = names.stream ()
                 .filter (name -> name.startsWith ("A"))
                 .count ();

  Java 同时支持用 parallelStream ()来进行流的并行处理。并行流允许流水线业务在独立的线程同时执行,这不仅改进了语法,同时提高了性能。在大多数情况下,你可以简单得用 parallelStream ()替换 stream ()实现并行。

   Try-With-Resources 结构

  在 Java 6 之前,打开一个文件然后读取内容需要通过 try/finally 来完成:

static String readFirstLineFromFileWithFinallyBlock (String path)
                                                    throws IOException {
   BufferedReader br = new BufferedReader (new FileReader (path));
   try {
       return br.readLine ();
   } finally {
       if (br != null) br.close ();
   }
}

  但是 readLine 和 close 都有可能抛出异常。在这种情况下,readLine 抛出的异常被忽略,我们事实上并不知道 readLine 执行失败。

  Java 7 引入了 Try-With-Resources 结构来克服这种缺陷:

static String readFirstLineFromFile (String path) throws IOException {
   try (BufferedReader br =
                  new BufferedReader (new FileReader (path))) {
       return br.readLine ();
   }
}

  上例中,无论在何种失败情况下,BufferedReader 都会自动关闭文件流。你可以通过用逗号分隔的方式,用一个 try 语句来打开多个资源。

  多重 catch

  以往 Java 只允许一个 catch 代码块对应一个异常,这造成如下的代码冗余:

catch (IOException ex) {
    logger.log (ex);
    throw ex;
catch (SQLException ex) {
    logger.log (ex);
    throw ex;
}

  从 Java 7 开始,你可以在一个代码块内捕捉多个异常,从而减少了代码冗余:

catch (IOException|SQLException ex) {
   logger.log (ex);
   throw ex;
}

  数值字面常量(Numeric Literals)

  数值字面常量可以添加下划线是 Java 语言的新特性。这允许你使用_作为大数字的视觉分隔符。下面的例子不言自明:

nt thousand = 1_000;
int million  = 1_000_000;

  使用 Java

  看到现代 Java 的语法如何简化并扩展了老 Java 之后,你可能已经摩拳擦掌跃跃欲试 Java 了。我整理了一下第三方的工具和库,这些可以用来帮助你们上手。

  Maven

  Maven 是一个 Java 构建系统,相比于配置,它更重视规范。Maven 定义了应用程序的结构,并提供了许多内置函数,比如运行测试,打包应用,部署你的库。使用 Maven 会显著降低管理 Java 项目的认知开销。 Maven Central 是 Java 世界中的 PyPI,为已发布的 Java 库提供一站式服务。

  核心函数

  谷歌的 Guava library 提供了谷歌 Java 开发中所使用的核心函数。这包括应用于集合,缓存,基础数据类型,并发,字符串处理工作,I/O等的常见函数。Guava 为如何设计好的的 Java API 提供了绝佳的案例分析,提供最有效的从 Java 中推荐的最佳实践的具体例子一个很好的案例, Effective Java 中推荐的最佳实践大部分都在 Guava 中得以体现。Guava 被用于谷歌产品开发,进行了超过 286,000 个单元测试,可谓经受过实战测试的考验。

  日期/时间函数

  Joda-Time 已经成为 Java 实际上的标准日期/时间函数库。事实上,Java 8 几乎一字不差地采用了 Joda-Time 规范。自此,我们建议使用 java.time 中的日期/时间函数代替 Joda-Time。但是,如果你需要使用 Java 8 之前的版本,Joda-Time 提供了无与伦比的 API。

  分布式系统

  Akka 提供类似 Erlang 型的 Actor 模型的抽象层来编写分布式系统。Akka 可以从容应对许多种不同的故障,为编写可靠的分布式系统提供了更高层次的抽象。

  Web 应用程序

  需要用 Java 写一个功能完善的 Web 应用程序?莫怕,有Play Framework 罩着你。Play 基于 Akka 的非阻塞I/O,提供了编写 Web 应用程序的可扩展的异步框架。如果想使用不那么前沿但是被广泛应用于产品的框架,请尝试Jetty

  单元测试

  JUnit 仍为编写单元测试的标准。最近几年,JUnit 的匹配器有所扩展,允许你对集合作 assertions。例如,您可以轻松地断言一个链表是否包含某个特殊值。

  模拟框架(Mocking Framework)

  Mockito 是 Java 的标准模拟库。它提供了所有你能想到的且对编写测试非常重要的模拟库的功能。

  然而不足的是。。。

  目前为止,我一直在为 Java 说好话,但是有些方面它还是很烂。

  它还是 Java!

  Java 的历史遗留不可避免,Java 仍然向下兼容其最早的版本,这意味着语言和标准库的最烂的部分还存在着。Guava 是为了令 Java 语言更讨人喜欢而产生这个事实就证明了,Java 和 API 存在不一致,令人困惑的问题,有时甚至是完全错误的。

  JSON

  Java 缺少映射到 JSON 的 object literal syntax(如 Python 的字典 literal syntax)。正因如此,从 Java 对象映射到 JSON 有时需要繁复的对象实例化和映射,反之亦然。目前有各种 JSON 库在这个领域竞争,Jackson 是当前的最受欢迎的,但是 Jackson 的文档需要进一步完善。

  模拟(Mocking)

  Mockito 解决了测试 Java 代码中的很多痛点,但是从像 Python 语言的灵活转换到 Java 语言的严格,你需要更谨慎地来设计你的类用于模拟。

  REPL

  我之所以喜欢 Python,其中一点就是它可以迅速地实现读取﹣求值﹣输出循环( read-eval-print loop),从而快速评估新的想法或检验假设。虽然一直有声音说要把读取﹣求值﹣输出循环添加到标准 Java 库,这一点目前还是不支持的。

  语法累赘

  虽然 Java 编译器的进步意味着明确的类型签名不再那么需要——尤其对于泛型——但是 Java 仍然比 Python 冗余的多。启动和运行一个项目需要更多的样板和开销——通常这意味更多的工作。

  结论

  Java 拥有一个漫长而传奇的历史,其中有好有坏。如果你已经很多年没有使用 Java 工作了,也许现在是一个好机会再次尝试它。只要不是像下面这样做:

分享到:
评论

相关推荐

    java For python 程序员

    1. Java教程是为Python程序员准备的,目的是帮助已经熟练使用Python的开发者快速学习Java语言,并迁移到Java编程环境上。 2. Java教程同样适合那些想掌握大数据基础技能的算法工程师,因为Java是处理大数据领域中...

    java2python--java代码转python工具

    Java到Python的转换工具,如"java2python",是一个重要的软件开发辅助工具,它能够帮助程序员将已有的Java代码转换成Python代码,以便在Python环境中执行或进行进一步的开发工作。这种转换过程涉及到多种语言特性和...

    基于Java和Python的黑马程序员苍穹外卖项目设计源码

    该项目为黑马程序员开发的苍穹外卖系统源码,采用Java和Python双语言编写,总文件数达到165个,其中包括141个Java源文件、15个XML配置文件、3个JSON文件、2个YAML文件、1个Git忽略文件、1个文本文件、1个Python脚本...

    如何像python程序员一样思考

    《如何像Python程序员一样思考》是一本优秀的计算机科学入门教材,它不仅提供了一种学习Python的有效途径,更重要的是,它教会了读者如何像一个真正的程序员那样思考问题,这是成为一名优秀程序员不可或缺的能力。...

    作业1:Java、C++和Python的OO特性调研报告1

    在 Python 中,如果一个属性或方法以单下划线开头(_name),则暗示它是内部使用的,不应直接在外部访问。双下划线开头(__name)的属性或方法会触发名称修饰(name mangling),进一步确保它们在子类中不会与同名...

    写给Python程序员的Scala入门教程1

    例如,`val a = 1`声明了一个名为`a`的整型常量,`val b = true`声明了一个布尔型常量`b`。 6. **Scala的脚本执行**: 和Python一样,Scala的源代码文件(`.scala`)可以直接运行,无需编译成字节码。通过指定`#!/...

    Python-Leetcode的Python和JAVA解决方案

    LeetCode是一个在线平台,专注于提供编程问题以提升程序员的算法技能。在这个平台上,你可以找到大量的算法题目,涵盖数据结构和算法的各个领域,包括排序、搜索、图论、动态规划等。本资料主要包含Python和Java两种...

    1. C++程序员python速成.ppt

    Python 作为一种广泛使用的编程语言,具有简洁易用的语法和庞大的标准库。作为 C++ 程序员,学习 Python 的基础语法和数据类型是非常必要的。本文将对 Python 的基础语法和数据类型进行详细的介绍。 一、程序结构 ...

    Jython示例

    在Python代码中,你可以像操作Python对象一样操作Java对象,这样就为Python程序员提供了访问Java世界的能力。例如,你可以创建Java集合、使用Java的网络API或者调用复杂的Java库。 ```python from java.util import...

    几份程序员简历参考模板,涵盖Java开发、Python、Web全栈、前端开发、软件工程.rar

    几份程序员简历参考模板,涵盖Java开发、Python、Web全栈、前端开发、软件工程.rar 几份程序员简历参考模板,涵盖Java开发、Python、Web全栈、前端开发、软件工程.rar 几份程序员简历参考模板,涵盖Java开发、Python...

    java程序员等级图

    Java程序员等级图是指导开发者职业发展的重要参考,它通常涵盖了从初学者到高级专家的不同阶段,每个阶段都对应着特定的技能集和技术要求。在Java编程领域,程序员的成长路径可以分为多个等级,如初级程序员、中级...

    10套HR喜欢的时尚个性、设计感十足的简历模板,Java、Python、数据库程序员可以拿来用,含自荐信

    3.专业经历和项目经验:向HR解释你在过去的职位或项目中如何更像是一个专家,具体地描述你所做的工作以及在项目中发挥的角色。强调你解决问题和实现目标的具体技能和策略。 4.重点突出和量化成果:尽可能量化你的...

    7套Java、Python程序员可以直接用的水墨古风风格简历模板.zip

    2.职业目标或摘要:简短而精确地概述你的职业目标或提供一个摘要,展示你的技能和经验。 3.技术技能:详细列出你掌握的编程语言、框架、工具和技术。这部分应该直接且易于扫描。 4.工作经历:按时间顺序列出你的工作...

    java与python的区别.pdf

    - Java执行速度通常比Python快,这在处理大量数据和需要高性能的应用场景中是一个优势。 - Python可能因为其解释执行的特性,在执行速度上略逊于Java,但在很多应用中,Python的开发速度和易用性可能更受开发者青睐...

    有java基础快速学Python摘要

    - **删除对象**:使用`del`关键字可以删除一个或多个对象,如`del var1, var2`。 3. **脚本执行**: Python脚本的第一行可以指定解释器路径,如`#!/usr/bin/python`,或者使用`#!/usr/bin/env python`,后者会在...

    Python-Java-Stream:适用于Python的Java流

    Python-Java-Stream 是一个库,它为Python程序员提供了一种使用类似Java 8的流API处理数据的方式。这个库的目的是为了让Python开发者能够利用流式处理的优势,提高代码的可读性和效率,同时减少复杂的数据操作代码量...

    python类似java的反射操作

    在Python中,你可以将一个变量用于存储任何类型的对象,如整数、字符串、列表或自定义类的实例。 2. **内置函数`type()`**:`type()`函数可以用来查询一个对象的类型。例如,`type(1)`会返回`&lt;class 'int'&gt;`,表明1...

    程序员简历模板包含JAVA,C,C++, Python等

    对于标题提及的"程序员简历模板包含JAVA,C,C++, Python等",我们可以深入探讨一下如何构建一个针对这些编程语言的优质简历。 首先,简历的结构应该清晰明了,通常包括以下几个部分: 1. **基本信息**:包括姓名...

    Java程序员简历模板40套

    "Java程序员简历模板40套"提供了一个丰富的资源库,帮助开发者快速构建专业且吸引人的简历,从而在竞争激烈的就业市场中脱颖而出。以下是一些关于如何利用这些模板以及创建有效Java程序员简历的关键知识点: 1. **...

    python调用java,开发jbpm6.0.0工作流Application

    在这个项目中,可能使用了Jython,因为它更符合Python程序员的习惯,无需额外的JNI编程。 接下来,我们关注Java部分。Java Business Process Management (JBPM) 是一个开源的工作流和业务流程管理系统,版本6.0.0 ...

Global site tag (gtag.js) - Google Analytics