您的位置:首页 > 编程语言 > Java开发

《疯狂Java讲义》第1章——Java语言概述与开发环境

2015-11-22 11:49 831 查看
本章是本书开篇第一章,作者从Java语言和Java开发环境两个大方面展开,其中Java语言从以下几个方面进行阐述:

Java语言

发展简史

竞争对手

Java程序概述

程序运行机制

程序基本规则

垃圾回收机制

第一个Java程序

而Java开发环境则具体作了如下的讲解:

Java开发环境

下载并安装Java8 JDK

设置PATH环境变量

关于CLASSPATH环境变量

此外,作者还总结了初学者容易犯的错误,并作出了相应的解答。

最后,作者在“何时使用IDE”这个问题上,给出了自己作为过来人的建议。

首先来看第一部分——Java语言。

1、发展简史:

关于Java的历史,我认为只需简单了解即可——Java本是Sun公司“Green计划”的一个部分,后来由于商业原因导致项目近乎夭折,但却因祸得福——在Sun完全把Java开放到网上的短短几个月时间内,就被开发者们奉为瑰宝,产生了无数的Java程序。后来,随着各版本JDK的相继发布,以及JSP/Servlet、EJB规范的出现,包括Struts、Spring等开源框架的诞生,乃至Google公司使用Java作为开发Android应用的语言,Java越来越表现出强大的生命力,在各个领域扮演着越来越重要的角色。

2、竞争对手:

在《疯狂Java讲义》中,作者把C#、Ruby、Python三者列为Java的比较对象。

C#是Microsoft公司在自身平台上拓展Java未遂,而推出的模仿Java,但又与Java形成竞争之势的语言,在Windows平台上,C#更能发挥自身优势,但如果考虑跨平台,则Java是更佳的选择。

Ruby的最大特点是简洁易用,而且相比较于Java,Ruby完全面向对象,不存在基本数据类型。与Java相似,Ruby也是完全跨平台的。Ruby在中小型企业应用开发可以发挥巨大优势,而Java则能在大型企业应用开发中扮演重要角色。

Python是一种面向对象的解释型脚本语言,最大的特点是可扩展性强以及语法清晰。虽然是脚本语言,但它的功能强大而完善,许多大规模的软件都使用到了Python。

3、Java程序概述:

1)程序运行机制:

高级语言可以分为编译型语言和解释型语言。其中编译型语言是指可以被某平台的编译器一次性把源代码编译成该平台的可执行机器码的语言,而解释性语言是指在运行的时候被某平台的解释器把源代码逐行解释成该平台的机器码并立即执行的语言。

Java程序的运行机制比较特殊。Java源程序需要进行编译,但编译的结果并不是所在平台的机器码,而是一种被称为“字节码”的中间代码,然后再将生成的字节码交由所在平台的Java虚拟机解释成平台机器码,再执行。因此,Java语言是一种半编译半解释型的语言。

2)程序基本规则:

a)Java程序的组织形式:

Java程序中最小的单位是,方法、属性,以及其他的可执行部分,全部都应定义在Java类中。程序执行的入口(也就是程序从哪里开始执行)是main方法,main方法的格式如下:

public static void main(String[] args){
//在这里书写可执行代码
}


如果试图用java命令执行不包含上述格式的main方法的类,会返回一个“在某某类中找不到main方法”的异常,如下所示:

这是一个不包含main方法的类:

public class HelloWorld{

}


按下win键+r键,输入cmd,回车进入windows控制台,使用”cd+空格+路径“进入到HelloWorld.java文件(在本例中,HelloWorld类是HelloWorld.java文件中唯一的一个类)的上一级目录C:\Users\Administrator\Desktop下,对HelloWorld源文件执行编译命令——javac HelloWorld.java,以及对HelloWorld.class文件执行执行命令——java HelloWorld。(前提是已经配置了PATH环境变量,关于环境变量,本篇文章后续部分有详细介绍)执行结果如下:





可以发现,javac命令成功将HelloWorld.java源文件编译成了HelloWorld.class文件,但执行java命令时,系统报出了“在类HelloWorld中找不到main方法……”的错误。由此可见,要作为一个可以执行的Java类,必须具有符合格式要求的main方法!

b)Java源文件的命名规则:

命名规则有三条:

1、源文件的扩展名必须是”.java”,也就是源文件名必须以”.java”结尾。

2、1个源文件可以包含多个类,但其中最多只能有一个用public修饰的类

3、如果源文件中没有public类,则文件名随意,否则源文件名=public类名

3)垃圾回收机制:

”垃圾回收“这个短语,乍一看似乎跟Java,甚至跟编程没有什么关系,因此在这里必须先搞清楚这个短语的各个成分的含义。

首先是”垃圾“,顾名思义,就是没有用的东西,在程序中,把不再被程序引用的对象称为垃圾(关于对象,后续内容将会介绍,此处知道即可)。接着是”回收“,那么回收什么?由谁来回收呢?回收什么,准确地说,是回收”不再被程序引用的对象占用的内存“,而由谁来回收,这就引出了Java不同于C/C++的地方了——在C/C++中,这个”回收“的动作,是由程序员来执行的,而在Java中,这项回收的工作,被下放到了JRE,程序员在编程的时候,无需像在C/C++中一样,手动地去做这个”回收“的工作。

于是,Java中的”垃圾回收机制“,就是JRE可以在程序员编程的时候,悄悄地完成”回收不再被程序引用的对象占用的内存“这项工作,而程序员却毫不知情。

那么问题来了,既然程序员也可以自己来做垃圾回收这项工作,那Java发明”垃圾回收机制“的用意何在?这就要看C/C++程序员在做垃圾回收这项工作的时候,效果是怎样的了。事实证明,C/C++程序员经常忘记及时回收无用的内存,甚至有的时候,错误地回收了程序核心类库占用的内存,导致程序崩溃。于是Java提供了垃圾回收机制,来改善这个问题。

Java中的内存,大致可以分为栈内存和堆内存(关于内存的分类,后续内容将会介绍,此处知道即可),其中堆内存,是用来保存程序运行过程中产生的对象,而垃圾回收机制管理的,正是堆内存。那么怎么个管理法呢?作者在文中讲了两个方面:一是如前所述,释放没用的对象;二是清理内存碎片。那么问题又来了——什么叫做”内存碎片“?我们可以想象,JRE每次回收的内存空间,可能并不是连续的,就像老鼠偷吃苹果一样,可能一口咬一边,另一口又跑到了另外一边,简称”乱啃“,结果整个苹果看起来就是坑坑洼洼的样子。垃圾回收也是如此,我们把这些已经回收的,但并不是连在一起的内存,成为”内存碎片“。Java垃圾回收机制,还做了这样一项工作,就是将这些坑坑洼洼的内存碎片进行整理,使得它们之间彼此连接起来,移到同一端,成为一整片。

总结一下,Java垃圾回收机制有以下的好处:

1、对于程序员来说,从烦人的内存回收中释放出来,提高了编程效率;

2、对于程序本身来说,避免了程序员”乱回收“,保护了程序的完整性

那么,说了这么多,垃圾回收机制只有优点吗?答案是否定的。任何事物都具有两面性,垃圾回收机制也是如此——既然垃圾回收机制可以自动回收无用内存,那么自然而然,JVM就必须持续跟踪程序中所有对象的状态,时刻监视它们是否仍是”有用的对象“,进而释放那些无用对象占用的内存。由于多做了这项工作,增加了开销,程序跑起来,性能自然受到了影响。另外,垃圾回收机制是怎么跟踪对象的状态的?这就涉及到垃圾回收机制使用的是什么样子的算法。如果这个算法不够好,那么很有可能导致垃圾回收机制跟我们程序员一样”发懵“,不能很好地完成使命。

总结一下,Java垃圾回收机制有以下的缺陷:

1、JVM必须持续跟踪程序中对象状态,增加了开销,影响了程序的性能

2、垃圾回收机制使用的算法好坏,会影响垃圾回收的效果

说了这么多Java帮我们做好的工作,不是等于白说吗?反正我们又不用管。其实,为了让垃圾回收机制更好地工作,需要我们程序员在编程的时候养成良好的编程习惯——当我们确信某一个对象在程序中不会再使用的时候,我们要习惯性地将它的引用设置为null。如下所示:

public class GarbageCollectionTest{
public static void main(String[] args){
Garbage g = new Garbage();//创建Garbage类的一个对象
//使用g指向的对象做一些事情...
g = null;//引用g指向的对象不会再被使用,将它设置为null
}
}

//Garbage类
class Garbage{

}


4、第一个Java程序:

1)编辑Java源程序:

在桌面新建一个记事本文件,文件名命名为HelloWorld,同时修改文件的扩展名,将”.txt”修改为”.java”。右键 –>”用记事本打开该文件“,输入以下代码:

public class HelloWorld{
//Java程序的入口方法,程序将从这里开始执行
public static void main(String[] args){
//向控制台打印一条语句
System.out.println("Hello World!");
}
}


2)编译Java程序:

编译Java程序需要用到javac命令,如果已经配置好PATH环境变量(关于环境变量,在本篇文章后续部分有详细介绍),则操作如下:

a.按下win键+r键,输入cmd,进入控制台

b.输入cd C:\Users\Administrator\Desktop,进入HelloWorld所在路径

c.输入javac -d C:\Users\Administrator\Desktop HelloWorld.java,回车

执行效果如下所示:





如图所示,javac命令已将HelloWorld.java文件成功编译成HelloWorld.class文件,并存放于路径”C:\Users\Administrator\Desktop“下。在上述javac命令中,-d 选项的作用是指定生成的.class文件的存放位置,实际上,由于目标路径就是当前路径,上述的命令完全可以简化为”javac -d. HelloWorld.java“,其中一点”.”表示当前路径。又因为javac命令不指定-d 选项时,.class文件的生成路径默认就是当前路径,因此上述的javac命令又可以简化为”javac HelloWorld.java“(也就是本文前面部分在说明类中丢失main方法时的执行效果时,使用的javac命令格式)。

3)运行Java程序:

在前面步骤的基础上,执行命令“java HelloWorld”(前提是已配置好PATH环境变量,关于环境变量,本篇文章后续部分有详细介绍),效果如下所示:



如图所示,java命令已成功解释执行HelloWorld.class文件,打印出“Hello World!”字样

接下来,来看第二部分——Java开发环境:

1、下载和安装Java 8的JDK:

1)什么是JDK:

JDK是Java Development Kit的缩写,即Java开发工具包。它包括3个部分:

1.Java编译器:将Java源程序编译为.class文件的程序

2.Java运行时环境(JRE):全称是Java Runtime Environment,用于运行Java程序

3.Java常用类库

2)下载Java 8 JDK:

a)登录Java 8 SDK Oracle官网下载地址 ,下载JDK最新版本

b)单击下图右侧JDK Download的链接,进入JDK 8 下载页面



c)根据自身平台,选择合适的JDK版本,其中,使用 32位 Windows 系统的用户选择Windows x86版本,使用 64位 Windows 系统的用户选择Windows x64版本。

3)安装Java 8 JDK:

Windows 64位JDK下载完成后,得到一个exe文件,双击该文件即可。

2、设置PATH环境变量(Windows上):

1)什么是PATH环境变量:

环境变量的作用是为操作系统指定一些运行环境的参数。而其中“PATH环境变量”的作用,是当要求操作系统运行一个程序的时候,告诉操作系统去哪里找这个程序。

在本文的前面,已经多次使用javac和java,我们前面使用这两个命令的方式,是进入控制台,进入到.java文件(.class文件)所在目录,然后直接执行javac(java)命令。那么操作系统怎么知道java.exe和javac.exe这两个程序在什么地方呢?其实操作系统会在两个地方寻找这两个程序。第一个地方,当然就是当前路径了,而第二个地方,就是PATH环境变量所指定的路径。

2)在Windows上设置PATH环境变量:

在桌面或资源管理器左侧,右键单击“计算机”,选择“属性”,单击左侧“高级系统设置”,单击下方“环境变量”,此时会弹出环境变量对话框,上方为当前用户的环境变量区,下方为系统环境变量区。若选择将PATH环境变量建为用户变量,则该变量只对系统当前用户有效,若选择将PATH环境变量建为系统变量,则该变量对系统所有用户有效。在此,使用系统变量编辑PATH环境变量:在系统变量区找到已经存在的PATH环境变量,双击它,弹出编辑框,将前面安装好的JDK 8的bin目录路径(此处为F:\jdk8\bin)粘贴到“变量值”的最前面,以“;”与后面的内容分隔开,如下图所示:



点击确定保存。关闭旧的Windows命令行窗口,cmd打开新的窗口,输入java、javac命令,出现如下所示大段的参数说明,即表示环境变量设置成功。



3、关于CLASSPATH环境变量:

1)CLASSPATH环境变量的作用:

以前面运行Java程序的命令“java HelloWorld”为例,我们知道,PATH环境变量解决了这条命令的前半部分,即“java”,使得系统知道到什么地方去找到java.exe这个可执行文件,那么这个命令的后半部分——“HelloWorld”呢?一种习惯性的说法是,系统会在“当前路径”下寻找HelloWorld类的字节码文件。这样子的说法的正确性是有前提的,这个前提就是我们所用的JDK版本必须是在JDK1.5以后(包含JDK1.5)。因为在JDK1.4以前,系统不会自动在所谓的“当前路径”下寻找HelloWorld.class文件,那么,就必须要有一个类似PATH的环境变量来告诉系统去哪里找,而这就是CLASSPATH环境变量。

为了能在“当前路径”下寻HelloWorld.class,我们需要新建一个名为CLASSPATH的环境变量,并添加一点“.”,表示要在当前路径下搜索HelloWorld.class。除此之外,使用java等命令还需要依赖于JDK的lib目录下的dt.jar和tools.jar中的Java类,于是还需要在CLASSPATH环境变量的后面追加上这两个jar包的路径,如下图所示:



其中JAVA_HOME也是一个环境变量,它的值其实就是JDK的安装路径,设置这个环境变量的作用,书中并没有提到,我猜想是为了方便以后更换JDK时不用同时改动多处,只需修改 JAVA_HOME即可:



然而这一切工作,在JDK1.5之后都无需再做,java、javac等命令在执行时,会自动在当前目录下搜索被执行的类文件,并且同时系统会自动加载tools.jar和dt.jar文件中的Java类。但一旦设置了CLASSPATH环境变量,系统就不会按照默认的方式搜索类文件以及加载必须的jar包,而会按照CLASSPATH指定的路径去寻找和加载相关类,因此我们就必须把上述3项内容都设置进去:当前路径、dt.jar路径、tools.jar路径。

另外,在Windows命令行窗口中输入java或javac命令时,在下方打印出来的大段参数选项中,有一个名字叫做“-classpath”的选项:



这个选项是用来手动指定系统到哪里搜索和加载相关类,当指定了-classpath选项之后,CLASSPATH环境变量指定的值就失效了,系统只认当前-classpath指定的路径,因此在-classpath选项中,也必须指定上述的3项内容:当前路径、dt.jar路径、tools.jar路径。

总结一下,在JDK1.5以后,java、javac等命令寻找相关类的依据的优先级顺序如下:

-classpath选项指定的值 > CLASSPATH环境变量指定的值 > 系统默认值

另外,作者在本章中还总结了一些初学者常犯的错误

1、环境变量的设置问题:

1)错误类型1:CLASSPATH环境变量值只设置了dt.jar和tools.jar所在的路径

解答:应在此基础上,再增加一点“.”,表示在当前路径下搜索类

1)错误类型2:喜欢手动输入路径,导致莫名其妙的错误

解答:在资源管理器地址栏上复制路径,粘贴到环境变量输入框中

2、大小写问题:

现象:执行命令时,不注意类名的大小写,例如“java HelloWorld”写成“java helloworld”,导致错误

解答:Java严格区分大小写,在书写类名的时候一定要注意是否与类定义完全一致,并且java所有关键字都是小写

3、路径包含空格问题:

现象:CLASSPATH环境变量包含的路径中如果存在空格,很可能引发错误

解答:把JDK以及其他Java相关程序安装在不带空格的目录下

4、main方法问题:

现象:执行包含main方法的类时,抛出“在类Xxx中找不到main方法,请将main方法定义为…”的错误

解答:main方法的定义一定要严格按照以下形式:

public static void main(String[] args){
//在这里书写可执行代码
}


最后,作者就“何时使用IDE”这个问题,给出了自己的建议:

当我们离不开IDE工具时,就不能使用IDE,当我们十分清楚在IDE工具中所做的操作对应发生的动作时,才可以使用IDE。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java