Java是一种计算机编程语言,拥有跨平台、面向对象、泛型编程的特性,普遍应用于企业级Web应用开发和移动应用开发。java
任职于太阳微系统的詹姆斯•高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言,应用在电视机、电话、闹钟、烤面包机等家用电器的控制和通讯。因为这些智能化家电的市场需求没有预期的高,Sun公司放弃了该项计划。随着1990年代互联网的发展,Sun公司看见Oak在互联网上应用的前景,因而改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。程序员
Java编程语言的风格十分接近C++语言。继承了C++语言面向对象技术的核心,Java舍弃了C++语言中容易引发错误的指针,改以引用替换,同时移除原C++与原来运算符重载,也移除多重继承特性,改用接口替换,增长垃圾回收器功能。在Java SE 1.5版本中引入了泛型编程、类型安全的枚举、不定长参数和自动装/拆箱特性。太阳微系统对Java语言的解释是:“Java编程语言是个简单、面向对象、分布式、解释性、健壮、安全与系统无关、可移植、高性能、多线程和动态的语言。”正则表达式
Java不一样于通常的编译语言或直译语言。它首先将源代码编译成字节码,而后依赖各类不一样平台上的虚拟机来解释执行字节码,从而实现了“一次编写,处处运行”的跨平台特性。在早期JVM中,这在必定程度上下降了Java程序的运行效率。但在J2SE1.4.2发布后,Java的运行速度有了大幅提高。数据库
与传统型态不一样,Sun公司在推出Java时就将其做为开放的技术。全球数以万计的Java开发公司被要求所设计的Java软件必须相互兼容。“Java语言靠群体的力量而非公司的力量”是 Sun公司的口号之一,并得到了广大软件开发商的认同。这与微软公司所倡导的注重精英和封闭式的模式彻底不一样,此外,微软公司后来推出了与之竞争的.NET平台以及模仿Java的C#语言。后来Sun公司被甲骨文公司并购,Java也随之成为甲骨文公司的产品。编程
Java语言之父-詹姆斯•高斯林数组
Java之因此被开发,是要达到如下五个目的:浏览器
Java技术主要分红几个部分:Java语言、Java运行环境、类库。通常状况下说Java时并不区分指的是哪一个部分。安全
Java在1.5版本时,作了重大改变,太阳公司并1.5版本重命名为Java 5.0。服务器
Java的特色之一就是面向对象, 是程序设计方法的一种。“面向对象程序设计语言”的核心之一就是开发者在设计软件的时候可使用自定义的类型和关联操做。代码和数据的实际集合体叫作“对 象”。一个对象能够想象成绑定了不少“行为(代码)”和“状态(数据)”的物体。对于数据结构的改变须要和代码进行通讯而后操做,反之亦然。面向对象设计 让大型软件工程的计划和设计变得更容易管理,能加强工程的健康度,减小失败工程的数量。网络
Java语言的第二个特性就是跨平台性,也就是说使用Java语言编写的程序能够在编译后不用通过任何更改,就能在任何硬件设备条件下运行。这个特性常常被称为“一次编译,处处运行”。
执行Java应用程序必须安装Java Runtime Environment(JRE),JRE内部有一个Java虚拟机(Java Virtual Machine,JVM)以及一些标准的类库(Class Library)。经过JVM才能在电脑系统执行Java应用程序(Java Application),这与.Net Framework的状况同样,因此电脑上没有安装JVM,那么这些程序将不可以执行。
实现跨平台性的方法是大多数编译器在进行Java语言程序的编码时候会生成一个用字节码写成的“半成品”,这个“半成品”会在Java虚拟机(解释层)的帮助下运行,虚拟机会把它转换成当前所处硬件平台的原始代码。以后,Java虚拟机会打开标准库,进行数据(图片、线程和网络)的访问工做。主要注意的是,尽管已经存在一个进行代码翻译的解释层,有些时候Java的字节码代码仍是会被JIT编译器进行二次编译。
有些编译器,好比GCJ,能够自动生成原始代码而不须要解释层。可是这些编译器所生成的代码只能应用于特定平台。而且GCJ目前只支持部分的Java API。
甲骨文公司对于Java的许但是“全兼容的”,这也致使了微软和升阳关于微软的程序不支持RMI和JNI接口、而且增长特性为己所用的法律争端。升阳最终赢得了官司,得到了大约两千万美圆的赔偿,法院强制要求微软执行升阳公司关于Java的许可要求。做为回应,微软再也不在Windows系统中捆绑Java,最新的Windows版本,Windows Vista和Internet Explorer 7.0版本也再也不提供对于Java应用程序和控件的支持。可是升阳公司和其余使用Java运行时系统的公司在Windows操做系统下对用户提供无偿的第三方插件和程序支持。
Java语言使用解释层最初是为了轻巧性。因此这些程序的运行效率比C语言和C++要低不少,用户也对此很有微词。不少最近的调查显示Java的程序运行速度比几年前要高出许多,有些一样功能的程序的效率甚至超过了C++和C语言编写的程序[来源请求]。
Java语言在最开始应用的时候是没有解释层的,全部须要编译的代码都直接转换成机器的原始代码。这样作的后果就是得到了最佳的性能,可是程序臃肿异常。从JIT技术开始,Java的程序都通过一次转换以后才变成机器码。不少老牌的第三方虚拟机都使用一种叫作“动态编译”的技术,也就是说虚拟机实时监测和分析程序的运行行为,同时选择性地对程序所须要的部分进行编译和优化。全部这些技术都改善了代码的运行速度,可是又不会让程序的体积变得失常。
程序的轻便性事实上是软件编写很难达到的一个目标,Java虽然成功地实现了“一次编译,处处运行”,可是因为平台和平台之间的差别,所编写的程序 在转换代码的时候不免会出现微小的、不可察觉的错误和意外。有些程序员对此很是头疼,他们嘲笑Java的程序不是“一次编译,处处运行”,而是“一次编 译,处处调试”。以Java AWT为例,早期Java AWT内提供的按钮、文字区等均是以电脑系统所默认的样式而显示。这令Java程序在有些没有提供图案的电脑系统产生错误(在Microsoft Windows设有窗口管理器,在一些Linux distribution则没有)。后来SUN公司针对Java AWT一些问题而推出Java Swing。
平台无关性让Java在服务器端软件领域很是成功。不少服务器端软件都使用Java或相关技术创建。
C++语言被用户诟病的缘由之一是大多数C++编译器不支持垃圾收集机制。一般使用C++编程的时候,程序员于程序中初始化对象时,会在主机内存堆栈上分配一块内存与地址,当不须要此对象时,进行析构或者删除的时候再释放分配的内存地址。若是对象是在堆栈上分配的,而程序员又忘记进行删除,那么就会形成内存泄漏(Memory Leak)。久而久之,程序运行的时候可能会生成不少不清除的垃圾,浪费了没必要要的内存空间。并且若是同一内存地址被删除两次的话,程序会变得不稳定,甚 至崩溃。所以有经验的C++程序员都会在删除以后将指针重置为NULL,而后在删除以前先判断指针是否为NULL。
C++中也可使用“智能指针”(Smart Pointer)或者使用C++托管扩展编译器的方法来实现自动化内存释放,智能指针能够在标准类库中 找到,而C++托管扩展被微软的Visual C++ 7.0及以上版本所支持。智能指针的优势是不需引入缓慢的垃圾收集机制,并且能够不考虑线程安全的问题,可是缺点是若是不善使用智能指针的话,性能有可能 不如垃圾收集机制,并且不断地分配和释放内存可能形成内存碎片,须要手动对堆进行压缩。除此以外,因为智能指针是一个基于模板的功能,因此没有经验的程序 员在须要使用多态特性进行自动清理时也可能一筹莫展。
Java语言则不一样,上述的状况被自动垃圾收集功能自动处理。对象的建立和放置都是在内存堆栈上面进行的。当一个对象没有任何引用的时候,Java的自动垃圾收集机制就发挥做用,自动删除这个对象所占用的空间,释放内存以免内存泄漏。
注意程序员不须要修改finalize方法,自动垃圾收集也会发生做用。可是内存泄漏并非就此避免了,当程序员疏忽大意地忘记解除一个对象不该该有的引用时,内存泄漏仍然不可避免。
不一样厂商、不一样版本的JVM中的内存垃圾回收机制并不彻底同样,一般越新版本的内存回收机制越快,IBM、BEA、SUN等等开发JVM的公司都曾宣称过本身制造出了世界上最快的JVM[来源请求],JVM性能的世界纪录也在不断的被打破并提升。
IBM有一篇有关Java内存回收机制比不激活垃圾收集机制的C++内存处理快数倍的技术文章[14],而著名的Java技术书籍《Java编程思想》(Thinking in Java)也有一段论述Java内存及性能达到甚至超过C++的章节[15] 。
编写Java程序前应注意如下几点:
关键字 下面列出了Java关键字。这些关键字不能用于常量、变量、和任何标识符的名称。
关键字 | 描述 |
---|---|
abstract | 抽象方法,抽象类的修饰符 |
assert | 断言条件是否知足 |
continue | 不执行循环体剩余部分 |
default | switch语句中的默认分支 |
do-while | 循环语句,循环体至少会执行一次 |
double | 64-bit双精度浮点数 |
else | if条件不成立时执行的分支 |
enum | 枚举类型 |
extends | 表示一个类是另外一个类的子类 |
final | 表示定义常量 |
finally | 不管有没有异常发生都执行代码 |
float | 32-bit单精度浮点数 |
for | for循环语句 |
goto | 用于流程控制 |
if | 条件语句 |
implements | 表示一个类实现了接口 |
import | 导入类 |
instanceof | 测试一个对象是不是某个类的实例 |
int | 32位整型数 |
interface | 接口,一种抽象的类型,仅有方法和常量的定义 |
long | 64位整型数 |
native | 表示方法用非java代码实现 |
new | 分配新的类实例 |
package | 一系列相关类组成一个包 |
private | 表示私有字段,或者方法等,只能从类内部访问 |
protected | 表示保护类型字段 |
public | 表示共有属性或者方法 |
return | 方法返回值 |
short | 16位数字 |
static | 表示在类级别定义,全部实例共享的 |
strictfp | 浮点数比较使用严格的规则 |
super | 表示基类 |
switch | 选择语句 |
synchronized | 表示同一时间只能由一个线程访问的代码块 |
this | 调用当前实例或者调用另外一个构造函数 |
throw | 抛出异常 |
throws | 定义方法可能抛出的异常 |
transient | 修饰不要序列化的字段 |
try | 表示代码块要作异常处理 |
void | 标记方法不返回任何值 |
volatile | 标记字段可能会被多个线程同时访问,而不作同步 |
while | while循环 |
Java自带了建立接口的类别,能够这样使用:
public interface Deleteable { void delete(); }
这段代码的意思是任何实现(implement)Deleteable接口的类别都必须实现delete()方法。每一个类别对这个方法的实现能够自行定制。由此概念能够引出不少种使用方法,下面是一个类别的例子:
public class Fred implements Deleteable { // 必須實做Deleteable介面中的delete方法 @Override public void delete() { // 實做的程式碼 } // 這個類別也能够包含其余方法 public void doOtherStuff() { } }
在另一个类别中,可使用这样的代码:
public void deleteAll(Deleteable [] list) { for(int i = 0; i < list.length; i++){ list[i].delete(); } }
由于队列中全部的对象均可以使用delete()方法。Deleteable队列中包含Fred对象的引用,而这个类别和其余Deleteable类别在使用deleteAll()方法时候不须要进行任何改变。
之因此这样作就是为了在接口的执行和其代码之间进行区别。举例来讲,一个名叫Collection的接口能够包含任何对象所须要的引入、转换和存储数据的方法,其余的类均可以使用这个接口。可是这个接口能够是一个可重定义大小的队列、一个链表或者是其余功能的集合。
这种特性实际上是一种折中的办法。Java的设计者们不想让Java有多重继承的特性,由于C++的多重继承显示了这种特性的困难。Java的接口功能能够提供一样的功能,可是又不会很复杂。
在Java语言中,应用程序接口(API)化身成类,而且分组成为包。每一个包中包含有相关的接口和类。对于不一样的平台,Java提供了不一样版本的包。API的设定由sun公司和其余公司经过JCP(Java社区程序)决定。任何公司和我的均可以参与这个工程,对API进行设计。2004年,IBM和BEA公司准备联合对官方的Java开源软件工程进行支持,可是2005年初,sun公司拒绝了这个支持。
并非全部的工程和环境须要企业档次的复杂性,好比一个简单的我的网站或者独自编程的程序师所写的程序。这些程序师会发现Java的复杂管理对于本身要作的程序来讲过于强大了。一些人以为Java在面向对象上面作的没有Ruby和Smalltalk纯粹。可是最新出现的用Java实现的语言Groovy解决了这些问题。
做为一种已经建立的新技术,Java显然综合了不少语言的特性,好比C++、C语言、Python等等。一些对于Java的评论认为Java的不变性在动摇。
有些程序师不喜欢原始类型(primitive type)和类别(class)的分离,尤为是那些曾经使用过Smalltalk和Ruby的程序师。Java的代码相对于其余的代码来讲过于冗长,这与它的轻便化声明相违背。
Java是一种单层继承的语言。这也致使了程序师在试图使用多重继承时候的不便,而不少语言均可以使用这个特性。可是Java可使用接口类,把多重继承可能致使的风险减小到最小。Java不支持运算符重载,这是为了防止运算符重载使得代码的功能变得不清晰。可是用Java实现的语言Groovy能够进行运算符重载。过去Java对于文本的操做和其余语言,好比Perl和PHP相比差的较多,但Java在1.4版本时候引入了正则表达式。
- 至Java 1.7为止,Java语言不支持闭包(closure)和混入(mixin)特性。
- Java 1.8加入闭包(Lambda Expressions) 。
使用Swing平台编写的带有GUI(图形用户界面)的程序和其余原始程序很是不一样。选用AWT工 具包编写程序的程序师看到的都是原始接口,并且也没法得到先进的GUI编程支持,若是使用的话,就要提供每一个平台上面所需的API,这将是一项庞大的工 程。Swing则是彻底用Java语言所写的程序,避免了接口元素重复的问题,只使用全部平台都支持的最基本的绘图机制。可是不少用户不知道如何在 Java风格和Windows风格之间进行转换,结果形成了Java程序的接口在不少程序中很是特殊。苹果电脑已经提供了优化过的Java运行时程序,包含了Mac OS X的经典Aqua接口风格。
在IBM捐赠给Eclipse基金会的SWT界面框架中,用户会看到熟悉的本地风格界面。但这又引发了不一样喜爱的开发人员之间的争论。
因为Java编译器和虚拟机的不一样对Java代码的性能影响比语言自己的影响大的多,因此统一讨论Java的程序的性能常常是有误导性的。据IBM的数据,在一样的硬件上2001年时的IBM JDK版本的性能是1996年的JDK版本的十倍左右。见IBM东京研究院的数据:http://www.is.titech.ac.jp/ppl2004/proceedings/ishizaki_slides.pdf而即便是在同一时期,不一样公司的JDK和JRE的性能也不同,好比SUN、IBM、BEA等公司都有本身开发的JDK和JRE。
Java语言的一些特性不可避免的有额外的性能代价,例如数组范围检查、运行时类型检查等等。Java程序的性能还会由于不一样的动态复杂性和垃圾处 理机制使用的多少而各有不一样。若是JVM的实现比较优化的话,那么这些功能甚至能够增长内存分配的性能。这和老是使用STL或者托管C++的程序的状况类 似。
尽管如此,仍然有许多人认为Java的性能低。这部分归因于Sun公司最初的JVM实现使用未优化的解释机制来运行字节码。一些新版本的JVM使用Just-In-Time(JIT) 编译器,在加载字节码的时候将其编译成针对运行环境的本地代码来实现一些本地编译器的优化特性。Just-In-Time机制和本地编译的性能比较仍旧是 一个有争议的话题。JIT编译须要不少时间,对于运行时间不长或者代码不少的大型程序并不适宜。可是不算JIT编译阶段的话,程序的运行性能在不少JVM下能够和本地编译的程序一争短长,甚至在一些计算比较密集的数值计算领域也是这样。目前,Java已经使用更先进的HotSpot技 术来代替JIT技术,Java的性能有了更进一步的提高。另外,在使用-server选项运行Java程序时,也能够对Java进行更深刻的优化,好比在 运行时将调用较多的方法内联(inline)到程序中来提升运行速度,这就是所谓的“动态优化”,而本地编译器是没法作到这一点的;这也是一些Java代 码比对应用C/C++等语言编写的本地代码运行的更快的缘由之一。微软的.NET平台也使用JIT编译器,因此也有相似问题。
Java的设计目的主要是安全性和可携性,因此对于一些特性,好比对硬件架构和内存地址访问的直接访问都被去除了。若是须要间接调用这些底层功能的话,就须要使用JNI(Java 本地接口)来调用本地代码,而间接访问意味着频繁调用这些特性时性能损失会很大,微软的.NET平台也有这样的问题。因此到目前为止,性能敏感的代码,例 如驱动程序和3D视频游戏,仍是大多使用本地编译,甚至直接以不直接支持面向对象的C语言或机器码编写。但最近已经有了许多用纯Java编写的3D游戏, 其效果与用C语言编写的不相上下,例如“合金战士”(英文名:Chrome)。这主要是由于新版的Java 3D技术已经能像C++同样调用硬件加速,也就是使用显卡来加速,不管是C++仍是Java语言写的3D游戏都是使用显卡及GPU来处理,从而使得CPU能够专一于其余方面的工做。
Java平台即由Java编程语言所撰写的软件赖以运行的平台,是Java软件和电脑系统的中介,最初被设计用在 Applet 等桌面端程序,不事后来逐渐转移到服务端的运用。
Java 运行环境,即Java Runtime Environment
,简称为JRE,是在任何平台上运行Java编写的程序都须要用到的软件。终端用户能够以软件或者插件方式获得和使用 JRE。Sun 公司还发布了一个JRE的更复杂的版本,叫作JDK,即Java 2开发包,里面包含了Java须要的编译器、参考文档和调试器等。
根据Sun公司的统计,安装Java运行环境的我的计算机已经超过7亿。[1]自从Sun指控微软添加Windows特效类文件到Java运行环境(JRE),并经过Visual J++运行这些类文件,微软再也不绑定Java运行环境到Windows操做系统。Apple的Mac OS X通常默认绑定Java运行环境, 并且许多Linux发行版也绑定一些兼容的自由软件包GNU Classpath。[2]
一些Java软件被桌面计算机普遍应用,好比NetBeans和Eclipse integrated development environments,文件共享程序如LimeWire和Vuze. Java还被应用于线性代数计算编程环境,包括用户界面和部分系统核心功能。
Java ME在移动设备上愈来愈流行,并开始与Symbian, BREW,和.NET Compact Framework展开竞争。
由于手机制造商的多样性,须要一种新的统一标准,使程序能够运行于不一样手机供应商制造的手机上。第一代这样的标准是MIDP 1,它假设手机显示屏很小,没有音频操做权限,并且只容许小于32kb的程序运行。MIDP2有声音访问权限,程序大小限制提升到了64kb。随着手机设 计的能力和速度的快速提高,其发展速度远比标准的制定快的多,一些厂商开始放松了对标准的遵照,好比容许更大的程序在手机上运行。
网络服务器和企业级应用
Java EE,Java平台企业版(Java Platform Enterprise Edition),是Sun公司为企业级应用推出的标准平台。Java平台共分为三个主要版本Java EE、Java SE和Java ME。
Sun公司在1998年发表JDK1.2版本的时候,使用了新名称Java 2 Platform,即“Java2平台”,修改后的JDK称为Java 2 Platform Software Developing Kit,即J2SDK。并分为标准版(Standard Edition,J2SE),企业版(Enterprise Edition,J2EE),微型版(MicroEdition,J2ME)。J2EE便由此诞生。
2005年6月,JavaOne大会召开,SUN公司公开Java SE 6。此时,Java的各类版本已经改名以取消其中的数字“2”:J2EE改名为Java EE, J2SE改名为Java SE,J2ME改名为Java ME。
随着Java技术的发展,J2EE平台获得了迅速的发展,成为Java语言中最活跃的体系之一。现现在,J2EE不只仅是指一种标准平台,它更多的表达着一种软件架构和设计思想。