“JAVA语法古板,没有什么特性“
“JAVA配置太繁琐了”
“JAVA实现一个功能代码比其他语言多“
这是我在网络或者工作中经常听到的大家对JAVA语言的评价,作为十年以上JAVA的忠实粉丝,每次我听到这种对编程语言的讨论就不自觉的思考一个问题:是语言问题还是程序员问题?
的确,JAVA作为一门静态语言,其语法结构非常严谨,没有胶水语言那样特别多花里胡哨的东西。如果有十个程序员用JAVA实现一个功能,那么十个人写的JAVA代码语法整体上不会有太大差别,但是用如python,javascript这样的脚本语言可能就会有不同的写法。想当初我学js的时候,明明可以这样学写,但是网络上资料又是另外一种写法,再过几天又看到还有另外的写法,搞得有时候真不知道哪一种才是最合理的。JAVA在语法上没有所谓“灵活”,这是因为JAVA在语法结构上比较单一,它是强类型语言,没有别的语言那么“随意”,特别不像javascript那样定义一个 变量可以是var也可以是let还可以是const,定义一个对象可以是用josn,也可以new Object,还可以用Class语法。这是因为JAVA语言是纯粹的面向面向对象编程的语言,JAVA世界里一切皆对象,没有单独存在的方法或者函数。所有方法必须是一个类或者一个对象才能调用。要创建JAVA对象只有两种方式,一个是new,一个是反射(动态代理类似)。甚至有人说,实现同样的功能,JAVA的代码量要多出一半左右,所以JAVA太繁琐了,对新手一点也不友好。
对此,我觉得一门语言的强大不强大并不是通过代码量体现的,代码多不代表这个语言就不好用,同样的代码量少不代表这个语言就很强。存在既合理,所有的编程语言都是在不同的领域发挥自己的优势,不然计算机都发展这么多年了,至今为止都还没有任何一门编程语言能一统江湖,独占鳌头的。
举一个比较有意思的例子,比如从操作系统读取一个文本文件的内容,如果用Python可能一两行代码就完成了。但是用JAVA去读取的话首先需要创建输入流,流又有字节流,字符流,文件流、缓冲流等各种各样的流,流之间还可以相互包装,然后还需要各种cry catch异常处理。以下是python和JAVA读取文件的区别:
//python读取文件f = open('file.txt', 'r')line = f.readline()//Java读取文件public class ReadFileExample { public static void main(String[] args) { String filePath = "file.txt"; try { BufferedReader reader = new BufferedReader(new FileReader(filePath)); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } reader.close(); } catch (IOException e) { e.printStackTrace(); } }}
没错,单从这个例子看,java代码比python显得更臃肿,需要做更多的编码工作。但是我们可以从另外一个角度看待这个问题。面向对象有一个特性就是基于接口编程,JAVA中一切都是对象,自然也奉承这个理念。所以JAVA SDK对文件的读写只做简单的底层接口,不做更多细节的处理,这样做虽然用户觉得实现起来略显繁琐但是却有很大灵活性。你完全可以自定义一个流替换默认的流,也可以用基础的流装饰一个更强大的文件输入流,比如在JAVA中new BufferedReader(new FileReader(filePath)) 用BufferedReader 装饰了FileReader这样就把自主权交给了使用者,因为你完全可以用字节流InputStream去实现文件的读取。因此使用JAVA,有时候看似代码量多了,但恰恰可以让你能更加发挥你的聪明才智,体现你成熟的编程思想,用面向对象的思维构建软件。在简单的软件工程中确实没有什么用处,但是在大型复杂项目用JAVA构建就特别考验你的架构思维。
上面的例子,其实JDK也完全可以像Python一样基于底层文件流再加一层封装,只暴露一个方法就可以简单读取文件,但是JDK并不想这么做,它觉得定义接口是JDK做的事,用什么方式读取那是应用层的事,把自主权交给应用层更合理。可以看到,不管哪一种语言,要实现一个功能抛开一些特别有技巧的算法以外,需要的代码量其实都差不多的,有的语言是本身就提供了,有的是直接依赖外部库函数,有的就需要程序员在应用层自己去做二次封装。
所以并不是代码少了,而是别人帮你在其他地方写了这一部分代码而已。虽然JAVA JDK本身读取文件比较麻烦,但是有一些优秀的第三方库就做了封装,也可以达到如其他语言一样一两行代码就可以读取文件内容的效果。例如 开源的第三方commons-io就是一个强大的IO处理工具包,它的一个工具类 FileUtils就有很多的静态方法可以直接调用。要读取文件仅仅一行代码 FileUtils.readLines(File file, String encoding) 。通过上面所述,笔者的观点是JAVA并不是不能做到代码简洁,而是省掉的代码由谁去实现而已,要么是JDK自带,要么是第三方封装,要么就是用户自己封装。
其次,JAVA之所以流行乃至现在还热度不减,那一定是得益于大名鼎鼎的Spring框架。可以这么说,JAVA在web领域能占据一席之地而且经久不衰一定程度上是因为Spring以及Spring强大的生态圈。在移动和桌面开发领域JAVA已经渐渐失去市场,但是在企业web领域还能继续保持大哥地位是Spring容器技术的助力让JAVA又重新回到开发者的视野。Sping的IOC,AOP两大核心让JAVA对象管理更加简单,因此基于Spring又衍生出一批又一批优秀的框架。比如MVC框架提供了通用的web开发模版,不管是已经过时的Struts还是风头正盛的Spring MVC都是这方面的杰出代表。在数据访问层又有各种各样开源的ORM框架如mybatis,hibernate,jpa,Spring jdbc等,他们都统一提供了web开发中的数据访问模型,屏蔽了对数据库访问的差异性。之所以可以用不同的框架替换恰恰就是因为JAVA语言的思想,面向接口编程而不是面向实现。所以JAVA只定义了标准的JDBC接口,由数据库厂家去实现这种接口即可。
更为有趣的是,这些框架本身并不一定依赖Spring,但是Spring流行起来后各开源框架几乎都用Spring代替了原始的配置,大大的简化了框架的接入,因为使用了Spring 又吸引了一波又一波的新老用户。如果说上面这些优秀框架解决了web控制,数据访问层,那么后起之秀 SpringBoot框架的出现一定是J2EE领域革命性的。SpringBoot强大之处在于它基于Spring但不是要代替Spring ,对应用层的业务框架没有任何侵入性,因为它并没有提供应用层面的任何功能,它的核心功能就是借助Spring容器让应用配置更简单甚至零配置,高端一点说话就是实现自动化配置。
下面我举个例子简单说一下SpringBoot的神奇作用。我们知道没有SpringBoot框架之前,如果需要接人SpringMvc框架,那需要自己导入各种依赖包,然后配置过滤器、拦截器,静态资源映射等一大堆繁琐的配置。虽然是基于Spring,但是也需一大堆的配置步骤,对于经验丰富的JAVA程序员这些配置工作已经滚瓜烂熟但是又不得不在各个项目中重复配置。对于新人来说就那就是配置的深渊,可能一个jar包冲突就需要半天时间去解决,所以某种程度上新手就觉得java 太难搞了,一度想放弃。
SpringBoot的出现,彻底改变了这种局面,也让JAVA web开发再次吸引了一波粉丝。它奉承约定大于配置的理念,把一些约定成俗的配置封装起来,使用者只需要依赖一个模块进来就可以开箱即用。比如我们现在只需要依赖spring-boot-starter-web这一个jar包到项目中,那么就拥有了SpringMvc的默认功能,再也不需要一个一个去配置那些繁琐的bean和xml文件。SpringBoot强大之处不仅只是提供默认配置,如果你对默认配置不满意,你完全可以自定义配置覆盖默认行为,这样看起来是不是非常的牛?软件领域的六大设计原则之一开闭原则在SpringBoot中运用得淋漓尽致啊。笔者现在看JAVA从来不关注他在语言层面又有了什么新变化,更多的是关注有没有类似Spring和SpringBoot这样优秀的框架出现一睹他们的设计思想,毕竟编程的最高境界是思想而不是语法。
最后,我想说的是j2ee从原始的纯编程的Servlet 到页面和代码混淆的jsp,再到各种提高开发效率的mvc三层开发框架,再发展到到SpringBoot这种自动化配置,根据时代的变迁和生产力的提高最后又衍生出SpringCloud微服务解决方案,这一切都是为JAVA开源社区为了进一步提高软件开发效率而去做的贡献。所以,JAVA之所以流行得益于他它的开放性以及它强大的开源生态。
随着JAVA Web 的开发生态不断完善,J2EE也从之前的配置深渊演变到了现在的自动化构建,让web应用构建越来越简单。试想一下,当你只需要在pom文件依赖一个jar包就可以拥有一个web服务,你还能说Java复杂,代码量多吗?我一度认为,编程界也有能量守恒定律,同一个功能的实现需要的代码少了,并不是不需要,一定是其他地方有人帮你写了那一部分代码,所以我们不能简单的通过代码量少来评价一门语言的好坏。
为什么有经验的程序员都比较青睐JAVA,新手基本觉得JAVA难学呢?笔者认为根本原因在于JAVA语法相对比较难入门,语法层面上它没有多样性,它并不像其他语言一样一行代码就可以输出helloword,更不能直接通过shell 就可以直接输出结果。学习JAVA需要一定的知识量,是一个积累的过程。等你对JAVA机制以及他的生态越来越了解了,你就会发现它其实一点不难,拥有了一定知识量后你才明白为什么JAVA可以构建大型应用。严谨、安全、面向对象、Spring加持、开源框架众多让JAVA在web开发领域立于不败之地。
想学编程的新手朋友们,如果给你选择,你会选择什么语言入门呢?