Java作为一门编程语言,自诞生以来已经流行了20多年,在学习它之前,我们有必要先了解一下它的历史,了解它是如何一步步发展到今天这个样子。

孕育

上世纪90年代,硬件领域出现了单片式计算机系统,比如电视机机顶盒这些消费设备。这些设备的特点是处理能力和内存都有限。如果使用C++编写程序,则对于这类设备来说过于庞大。

所以需求便来了,为了适应这类设备,需要一种小型的计算机语言,Java便应运而生了。

1991年,Sun公司的James Gosling, Mike Sheridan和Patrick Naughton发起了一个名为“Green”的项目小组,主要用于电视机顶盒这类消费设备。

由于设备的处理能力和内存有限,所以要求语言短小、代码紧凑。而对于电视机顶盒这类消费设备来说,厂商会选择各种不同的CPU,所以要求语言可移植、不与特定的平台捆绑在一起

出生

Green项目组以C++为基础,对C++进行了一些改造,并删除了一些不太实用、复杂繁琐的东西,开发出了名为“Oak”的语言,(Oka来自James Gosling办公室外的橡树)。

成长

挫折

1992年夏天,Green项目组已经能够演示Green操作系统、Oak的程序设计语言、类库和其硬件。

1992年9月,Green项目组发布了它的第一个名为“Start 7”的产品,该产品是一个个人数字助理设备,具有图形界面和非常智能的远程控制。

1992年11月,Green项目被剥离,成为Sun Microsystems的全资子公司Firstperson。

但是当时的硬件生产厂商对其项目并不感兴趣,Firstperson花了一年多也没找到希望购买其技术的买家。

1994年,First Person公司解散,被重新纳入Sun公司。Oak语言无法进入市场,也被暂时搁置下来。

机遇

在上面的过程中,Internet的万维网也在不断发展。对于客户机/服务器模型来说,万维网需要做的是将超文本页面转换到屏幕的浏览器中。

1994年6月到7月,Sun公司的团队看到了互联网的发展,一些图形Web浏览器的出现让他们认为互联网可以演变成他们为有线电视所设想的相同的高度交互性媒体。经过三天的头脑风暴后,该团队将目标平台重新定位为万维网平台。

1994年中期,Oak语言的开发者意识到他们可以开发一个浏览器,WebRunner浏览器诞生。

1995年,互联网的发展带给了Oak语言一个机遇。当时的网络页面是单调、死板的静态页面,业界希望页面能够“灵活”起来,并且希望代码能够通过网络传播进行跨平台运行。Oak的语言短小、可移植的特点和这些需求不谋而合。

Sun公司首先推出了可以嵌入网页并且可以随同网页在网络上传输的Applet(Applet是一种将小程序嵌入到网页中进行执行的技术)。

设计者在设计WebRunner浏览器具有在网页中执行内嵌代码的能力,这种能力能让网页变得“灵活”。

同年,Sun公司将Oak更名为Java(因为Oak已经被使用了,Java一词来自咖啡),WebRunner浏览器也演变成了HotJava浏览器,HotJava浏览器完全使用Java开发。

同年5月23日,Sun公司在Sun World会议上展示并正式发布了Java语言和HotJava浏览器,各大公司都纷纷停止了自己公司相关项目的开发,竞相购买Java的使用许可证,并为自己的产品开发了相应的Java平台。

发展

1996年初,Sun公司发布了Java的第1个开发工具包(JDK1.0),这是Java发展的里程碑,标志着Java成为了一种独立的开发工具。

同年9月,约8.3万个网页应用了Java来制作。

同年10月,Sun公司发布了Java平台的第1个即时编译器。

但是人们很快意识到Java1.0并不能用来进行真正的应用开发。

1997年2月,JDK1.1面世,它弥补了JDK1.0的大多明显缺陷,改进了反射能力,但是仍有局限性。

1998年12月,Sun公司发布了第二代Java平台——JDK1.2。此次发布有几个不同的版本,分别是标准版J2SE、用于手机等嵌入式设备的微型版J2ME、用于服务器端处理的企业版J2EE。

此次发布是Java发展过程中最重要的里程碑,标志着Java的应用开始普及。

2000年5月,JDK1.3、JDK1.4、J2SE1.3相继发布。

2001年9月,J2EE1.3发布。

2002年2月,J2SE1.4发布。该版本提高了Java的计算能力,扩展了标准类库,提高了系统性能。

在此期间,Java Applet采用低调姿态,淡化了客户端的应用,成为服务器端应用的首选平台

2004年9月,J2SE 1.5版本发布,该版本为重大更新,是自1.1版本以来第一个对Java语言做出重大改进的版本。JavaOne会议后,版本数字从1.5改为5.0。

2005年6月,Java SE 6发布。版本名称发生了改变,如J2SE改为Java SE、J2ME改为Java ME、J2EE改为Java EE。该版本没有对语言方面再进行改进,但是改进了其他性能,增强了类库。

2006年11月,Sun公司将Java技术作为免费软件对外发布。

2007年3月起,全世界所有开发人员均可对Java源代码进行修改。

随着数据中心越来越依赖于商业硬件而不是专用服务器,Sun公司在2009年被Oracle收购。

2011年,Oracle发布Java SE 7。

2014年,Java SE 8发布,近20年以来,该版本有了最大改变,Java 8提供了一种“函数式”编程方式,可以很容易地表述并发执行的计算。

2017年,Java SE 9发布。

Java 9之后,Oracle宣布每6月更新一次版本。

2020年3月,Java SE 14发布。

Java Web的发展

Java一路走来,为了适应时代发展,做出了许多改变。

在早期,Java是为了解决传统的单机程序设计问题,但由于种种原因,Java后来转向Web。

Web的最初模样

Web为了提供交互性内容采取了客户端/服务器系统,但是交互性完全由服务器提供。服务器产生静态页面,这些静态页面是事先写好的,将其提供给能够解释并显示的客户端浏览器。

但是我们的需求是千变万化的,事先写好的静态页面肯定不能满足我们日益增长的需求。

CGI

CGI(Common Gateway Interfa,通用网关接口),它是一段程序,运行在服务器上,提供同客户端HTML页面的接口,通俗的讲CGI就像是一座桥,把网页和WEB服务器中的执行程序连接起来,它把HTML接收的指令传递给服务器,再把服务器执行的结果返还给HTML页。

CGI使网页变得不是静态的,而是交互式的。

但是CGI程序的响应时间依赖于发送的数据量的大小、服务器和网络的负载,一旦网站变得复杂起来,响应就会变得非常慢且难以维护。

Applet

Applet是一种将小程序嵌入到网页中进行执行的技术,含有Applet的网页的HTML文件代码中部带有<applet></applet>这样一对标记,当支持Java的网络浏览器遇到这对标记时,就将下载相应的小应用程序代码并在本地计算机上执行该Applet。

在当时,Java Applet 可以大大提高Web页面的交互能力和动态执行能力。

Java刚出现时,Applet是最受大家欢欣鼓舞的。但是由于当时的网络环境的问题,安装Java运行时环境(JRE)所需要的10MB带宽对当时的用户来说太过于恐怖。并且微软的IE浏览器并并没有包含JRE,所以Applet并没有得到大规模应用。

Servlet

Servlet(Server+Applet),即服务器端小程序。Servlet能够按照用户提交的内容处理并返回相应的资源。可以输出HTML页面,动态展示数据。Servlet实现正确的接口就能够处理Http请求。

但是出现了一个很大的问题:HTML代码需要在Servlet类中用Java代码一行一行输出,表现、逻辑、控制、业务等全部在Servlet类中,造成Servlet类代码混乱(HTML代码、Java代码都写在一起),重复性高、阅读性差、开发困难。

下面是使用Servlet在浏览器中输出有一个h1标题的Hello World!字符串的HTML页面。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
response.setContentType("text/html;charset=utf-8");
out.println("<html>");
out.println("<head>");
out.println("<title>$Title$</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
}

可想而知,更复杂的页面得写多少代码!

JSP

为了解决上面的问题,Sun公司开发出了JSP。

JSP(JavaServer Page)是一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTML、XML或其他格式文档的Web网页,然后返回给请求者。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求。

可以将JSP页面看成是一个能内嵌Java代码的HTML页面。

静态部分(HTML页面)是模板,可以提前写好,动态部分(数据)可以由Java代码动态生成。这样一来就避免了在单纯使用Servlet时HTML代码和Java代码都出现在Servlet类中的混乱情况。

JSP在运行时被转换成Servlet,因此JSP本质是Servlet。

下面是使用JSP做和上面同样的事情:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>

仍使用HTML模板,但不是用Java语句一行一行“堆”出来,这多方便!

使用了JSP后,虽然不用一行行地“堆”HTML页面了,但是代码混乱的问题仍没有解决。表现、逻辑、控制、业务等代码仍然写在一块了,只不过是从Servlet类中挪到JSP中了。

这样混乱的代码极不利于团队开发,如果项目很小,那还能理顺,但如果项目非常大的话,那就“剪不断,理还乱了”。

所以这时候,我们急需将代码分门别类的码放整齐。

JSP + JavaBean(Model1模式)

JavaBean 是用Java语言写成的可重用组件,JavaBean类要求:

  1. 类是公开的
  2. 具有私有成员变量
  3. 具有无参构造器
  4. 具有setter和getter方法

上面已经说了,单纯使用JSP会有大量的HTML代码和Java代码耦合在一起,不利于开发、维护、分工协作。

我们举一个登录的例子:

登录大致需要以下几步:

  1. 在浏览器中输入用户名、密码
  2. 获取数据,交给服务器
  3. 把数据处理成合适的形式
  4. 查询数据库的用户表,看是否有一条用户名和密码都符合输入的记录。如果有,则登录成功。

单纯使用JSP时,以上步骤全部在JSP登录页面中完成,该页面既需要显示登录表单、又需要获取、处理数据、还需要查询数据库。太乱了!!

有了JavaBean,我们可以将JSP中大量重复的代码抽取成可重用的组件,封装成JavaBean,在一定程度上减轻了代码的耦合度,也在一定意义上实现了分层

比如,用户本身就是一个对象,我们可以将其抽取成JavaBean,数据的传递、查找都可使用JavaBean来完成。

JSP+Servlet+JavaBean(Model2模式——MVC模式)

上面介绍了Servlet、JSP、JSP+JavaBean,虽然在进步,但是都不尽如人意。那为什么不让它们结合起来取长补短?

我们之所以使用JavaBean,就是为了让Java代码和HTML代码分离开了,而Servlet也是一个Java类,为什么不使用它呢?

JSP+JavaBean已经实现了部分分层,使用MVC(Model-View-Controller)模式能进一步分层。

Model(模型):MVC模式的中心组件,处理数据和逻辑。(比如JavaBean,但不止只有JavaBean)

View(视图):展示数据,渲染页面。(前端页面,比如HTML页面、JSP页面)

Controller(控制器):从View接收数据,向Model发送数据,即用于控制数据分发。(比如Servlet)

还用上面的登录例子:

  1. 将JSP登录页面作为View

  2. Servlet类(Controller)用于接收用户输入的用户名、密码,将其封装为用户类(JavaBean),然后去数据库中查询。如果能查询到则登录成功。

  3. 将查询结果返回给Controller,Controller根据查询结果选择一个合适的View,并将数据渲染到页面,展示给用户。(在本例中,如果查询成功,则进入系统主页;如果查询不到,则用户会看到一个登录失败页面)

使用了MVC设计模式后,代码有了明显的分层,结构清晰,各司其职。

框架

为了减轻工作量,各种框架逐渐出现在人们的视野中。

所谓框架,可以把它看做一个半成品的项目/软件,框架中有许多东西别人都已经帮我们写好了,比如各种类、方法。

我们要做的就是去了解、学习框架,在写好的框架的基础上、遵循框架的制定好的规则、按照自己的思路、结合框架的思想、去开发我们自己的项目。

目前Java的Web开发中最出名的框架就是Spring家族了,比如SpringMVC、Spring、SpringBoot。

熟悉、利用这些框架能够帮助我们快速、优雅地开发出符合需求的项目。

另,框架是别人写好的轮子,有了它,我们能够跑得更快,但是别忘了怎么走。

总结

说了这么多,相当于陪着Java从出生到现在走了一遍。我们可以看出Java的发展也不是一帆风顺的,我认为Java之所以现在还这么流行,原因之一就是它能够一直保持更新,一直在根据时代的需求结合自身的特点不断地做出改变。正如那句话「穷则变,变则通,通则达」。一门语言能做到这样,身为人更应该要做到。

如有错误,还请指正。



参考资料:

  1. 百度百科
  2. 维基百科
  3. Java官方文档
  4. Java核心卷一(第10版)
  5. Java编程思想(第4版)

文章首发于公众号『行人观学』

Java的前生今世的更多相关文章

  1. Java NIO 的前生今世 之四 NIO Selector 详解

    Selector Selector 允许一个单一的线程来操作多个 Channel. 如果我们的应用程序中使用了多个 Channel, 那么使用 Selector 很方便的实现这样的目的, 但是因为在一 ...

  2. 月光宝盒之时间魔法--java时间的前生今世

    月光宝盒花絮 “曾经有一份真诚的爱情摆在我的面前,但是我没有珍惜,等到了失去的时候才后悔莫及,尘世间最痛苦的事莫过于此.如果可以给我一个机会再来一次的话,我会跟那个女孩子说我爱她,如果非要把这份爱加上 ...

  3. 揭秘 BPF map 前生今世

    揭秘 BPF map 前生今世 本文地址:https://www.ebpf.top/post/map_internal 1. 前言 众所周知,map 可用于内核 BPF 程序和用户应用程序之间实现双向 ...

  4. Netty 源码分析之 番外篇 Java NIO 的前生今世

    简介 Java NIO 是由 Java 1.4 引进的异步 IO. Java NIO 由以下几个核心部分组成: Channel Buffer Selector NIO 和 IO 的对比 IO 和 NI ...

  5. RPC 原理的前生今世

    (如果感觉有帮助,请帮忙点推荐,添加关注,谢谢!你的支持是我不断更新文章的动力.本博客会逐步推出一系列的关于大型网站架构.分布式应用.设计模式.架构模式等方面的系列文章) 在校期间大家都写过不少程序, ...

  6. RCNN,Fast RCNN,Faster RCNN 的前生今世:(2)R-CNN

    Region CNN(RCNN)可以说是利用深度学习进行目标检测的开山之作.作者Ross Girshick多次在PASCAL VOC的目标检测竞赛中折桂,2010年更带领团队获得终身成就奖,如今供职于 ...

  7. 线程中sleep()方法和wait()方法的前生今世

    先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索[程序职场]关注这个执着的职场程序员.我有什么:职场规划指导,技能提升方法,讲不完的职场故事,个人成长经验. 不知道大家有没有这种感觉,在公 ...

  8. web框架的前生今世--从servlet到spring mvc到spring boot

    背景 上世纪90年代,随着Internet和浏览器的飞速发展,基于浏览器的B/S模式随之火爆发展起来.最初,用户使用浏览器向WEB服务器发送的请求都是请求静态的资源,比如html.css等.  但是可 ...

  9. 主动降噪技术(ANC)的前生今世--原理仿真

    一 原理: 主动降噪就是通过反相检测麦克风的声音或噪声来减弱周围环境的噪声让扬声器出来的声音听起来更清晰.主动降噪技术的目标就是通过一个自适应滤波器把不想要的噪声反相从而把噪声约束到固定的范围内.该系 ...

随机推荐

  1. ElementUi 全选功能实现

    每次使用官方的示例都会被坑一下(可能是我的理解不够透彻吧,不记录一下保不准下次依旧会忘), 故此今天做个Demo 记录一下.本次仍然使用官网给出的示例,只做理解性的说明. 1.此处先给出官方示例代码: ...

  2. ActiveMQ 反序列化漏洞(CVE-2015-5254)复现

    1.运行漏洞环境 sudo docker-compose up -d 环境运行后,将监听61616和8161两个端口.其中61616是工作端口,消息在这个端口进行传递:8161是Web管理页面端口.访 ...

  3. CSS选择器-类-ID-伪类

    类选择器(Class selectors) 通过设置元素的 class 属性,可以为元素指定类名.类名由开发者自己指定. 文档中的多个元素可以拥有同一个类名. 在写样式表时,类选择器是以英文句号(.) ...

  4. Rocket - devices - TLBusBypass

    https://mp.weixin.qq.com/s/WviVHxlZvsNm8mea2VpfTw 简单介绍TLBusBypass的实现. 1. TLBypassNode TLBypassNode定义 ...

  5. Java实现 LeetCode 713 乘积小于K的子数组(子集数量+双指针)

    713. 乘积小于K的子数组 给定一个正整数数组 nums. 找出该数组内乘积小于 k 的连续的子数组的个数. 示例 1: 输入: nums = [10,5,2,6], k = 100 输出: 8 解 ...

  6. java实现第六届蓝桥杯奇妙的数字

    奇妙的数字 奇妙的数字 小明发现了一个奇妙的数字.它的平方和立方正好把0~9的10个数字每个用且只用了一次. 你能猜出这个数字是多少吗? 请填写该数字,不要填写任何多余的内容. 结果:69 impor ...

  7. Java实现第八届蓝桥杯9算数式

    9算数式 题目描述 观察如下的算式: 9213 x 85674 = 789314562 左边的乘数和被乘数正好用到了1~9的所有数字,每个1次. 而乘积恰好也是用到了1~9的所有数字,并且每个1次. ...

  8. 介绍几种给你的Python代码加上酷炫的进度条的方式

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 大家好,在下载某些文件的时候你一定会不时盯着进度条,在写代码的时候使用进度 ...

  9. mysql 错误:Table is marked as crashed and should be repaired 解决办法

    遇到这个问题几个敲命令轻松搞定 1.首先进入mysql命令台: mysql -u root -p 回车 输入密码 2.查询所有的库 mysql> show databases; 3.进入数据库“ ...

  10. 【LGR-072】回首过去

    题目   点这里看题目. 分析   可以发现,符合条件的分数约分后,其分母必须为\(2^m5^k\).因此,原分数一定可以表示为: \[\frac{XY}{2^m5^kX} \]   其中\((10, ...