第2章 Java语言基础
在用人单位的面试中,Java语言基础知识是考察的重点之一,也是一个合格Java程序员必须掌握的知识。一个对于Java语言基础知识一知半解的程序员,会在实际的项目开发工作中犯一些低级错误,对项目开发的质量和团队的开发进度都有很大的影响。代码的质量,直接影响了软件工程的质量。
Java语言基础主要涉及以下几个方面。
• Java的基本语言元素。
• 原始数据类型。
• 变量声明。
• 变量的初始化。
• Java源文件的结构。
• main()方法。
面试题1 掌握Java标识符
请标记出下面代码中的错误。
public class JavaSign { public int 48abc=20; private int Num=100; private int m-48abc; private int m_abc=30; private int number=60; private String $hk; private double ¥money; public String我的变量="我是一个兵!"; private String my@email="helloworld"; public static void main(String[] args) { System.out.println(num); System.out.println(my@email); System.out.println(48abc+m_abc); System.out.println(number); } }
考点:这是一个比较有代表性的面试题,考察求职者Java语言基础的基本功,重点考察求职者对Java标识符的掌握。
出现频率:★★★★★
【面试题解析】标识符是一个语言的基本元素,在Java开发语言中,标识符可以用来表示类、方法、变量和标签。标识符是由一系列的字符组成,每个字符可以是字母、数字、连接符号(例如_)或者任意的货币符(如$、¥等)。
求职者必须要注意的是,Java标识符的第1个字母不能为数字,Java语言是区分字母大小写的,Num和num是两个毫不相干的标识。
注意:Java使用的是Unicode编码。Unicode中每个字符都对应了一个唯一的数字,而不论是什么平台、使用什么语言、编写什么程序。Unicode标准已经被当今工业界的领导们所采用,例如Apple、HP、IBM、JustSystem、Microsoft、Oracle、SAP、Sun、Sybase、Unisys和其他许多公司。最新的标准例如XML、Java、ECMAScript(JavaScript)、LDAP、CORBA 2.0、WML等,以及许多操作系统、所有最新的浏览器和许多其他产品都支持。Unicode标准的出现和支持它的工具存在,是近来全球软件技术最重要的发展趋势。
基本上,计算机只是处理数字,输入或输出的字母或其他字符都被编码为一个数字。在创造Unicode之前,有数百种指定这些数字的编码系统,没有一个编码可以包含足够的字符。例如,欧州共同体就需要好几种不同的编码系统来包括所有的语言。即使是单一种语言,例如英语,也没有哪一个编码可以适用于所有的字母、标点符号和常用的技术符号。不同编码系统也会互相冲突。也就是说,两种编码可能使用相同的数字代表两个不同的字符,或使用不同的数字代表相同的字符。因此任何一台特定的计算机(特别是服务器)都需要支持许多不同的编码,而且不论什么时候数据通过不同的编码或平台之间,数据总会存在损坏的风险。
例如,在简体中文(GB)、繁体中文(BIG5)、日文中,“赵”都是同一个字,但是编码方式不同。BIG5的赵对应0xBBAF,而0xBBAF在GB里面就被显示为“化”,这就是我们常见的乱码的原因之一。Unicode采用统一的编码,“赵”只对应一个数字,不必管它来自哪种语系。
下面举例来说明如何区分正确和错误的标识符。
正确的Java标识符示例:
Abc123、abc、¥m、$kill、my_code、gач
非法的Java标识符:
46m、my@email、 int-1
面试题中,求职者容易忽略一点,中文变量和中文字符是合法的。
参考答案:
public class JavaSign { // 错误:Java的标识符不能以数字开头 public int 48abc=20; private int Num=100; // 错误:Java的标识符不能包含-,只能在表达式中使用 private int m-48abc; private int m_abc=30; private String $hk; private double ¥money; public String我的变量="我是一个兵!"; private int number=60; // 错误:不能在变量中使用@,为不合法标识符 private String my@email="helloworld"; public static void main(String[] args) { // 错误:没有定义num变量,因为Java是区分大小写的 System.out.println(num); // my@email定义错误 System.out.println(my@email); // 48abc定义错误 System.out.println(48abc+m_abc); // 错误:不能在静态方法中引用一个非静态变量 System.out.println(number); } }
面试题2 掌握Java关键字
编译、运行如下代码,请选择正确的一项描述。
public class JavaKey { private int java=100;//(1) public String True="my Java";//(2) public static void main(String[] args) { int ingeter=20;(3) JavaKey key=new JavaKey(); //(4) System.out.println(key.java);//(5) } }
(a)编译成功,打印100。
(b)编译不通过,提示(1)处有错误。
(c)编译不通过,提示(2)处有错误。
(d)编译不通过,提示(3)处有错误。
(e)编译不通过,提示(4)、(5)处有错误。
考点:主要考察求职者对于Java关键字的掌握,一般都会在面试题中出现开发中容易出现的混淆关键字。
出现频率:★★★★
【面试题解析】Java语言中的关键字是开发语言中预定义的保留标识符,不能在程序代码中表示类、变量、方法等成员。Java的关键字有如下特征。
• Java的关键字都是小写的。
• then和sizeof都不是Java的关键字。熟悉C或者C++,写惯了ASP的程序员一定要注意。
• 大写的NULL不是java语言的关键字。String是Java语言的一个封装类的类名,也不是关键字。
下面给出Java语言的关键字,如表2.1所示。
表2.1 Java语言的关键字
Java语言中的保留字:null、true和false。
Java语言中保留但是未使用的关键字:const和goto。
参考答案:(a)。
面试题3 找出Java关键字
Which of the following are keyWords or reserved words in Java?(下面哪些是Java语言的关键字或者是保留字?)
(a)if
(b)then
(c)goto
(d)while
(e)case
(f)sizeof
考点:主要考察求职者对于Java关键字的掌握。
出现频率:★★★★
【面试题解析】请参考Java关键字表。
参考答案:(a)(c)(d)(e)。
面试题4 挑选Java关键字
Which of these are key words in java?(下面哪些是Java关键字?)
(a)default
(b)NULL
(c)String
(d)throws
(e)long
(f)true
考点:主要考察求职者对于Java关键字的掌握。
出现频率:★★★★
【面试题解析】请参考Java关键字表。
参考答案:(a)、(d)、(e)、(f)。
面试题5 选择完整合法的Java注释
下面是否为一条完整而且合法的Java注释?
/*//*/
(a)不是,块状注释(/*…*/)尚未闭合,因为这里单行注释(//…)注释掉了块状注释的闭合部分。
(b)这是一个完全有效的注释。编译器会忽略//部分。
(c)是一个非法注释,编译器会报错。
考点:考察求职者对Java注释的熟悉程度。在软件项目开发中,规范而且完整的注释可以提高代码的可读性和可维护性。
出现频率:★★★★
【面试题解析】Java语言提供了3种用于程序的注释。
• 单行注释://…到行尾。
• 多行注释:/*…*/。
• 归档(Javadoc)注释:/**…*/。
多行注释可以跨越多行,以/*开头,*/结尾,例如:
/* a mothed Test Hello */
注意:如果多行注释内容出现注释起始符号,例如//、/*、//*等,编译器视为普通字符,并不做任何处理。但是多行注释不能嵌套,如下注释会引发错误:
/* hello Test /* a sub */ */
注释在软件开发中的使用。
1.文件头注释
文件头注释以 /*开始,以*/结束,需要注明该文件的创建时间、文件名、命名空间信息。
例如:
/* * Created on 2005-7-2 * File Test.java * Package com.cn * Create Date:2008-08-01 * /
2.类、接口注释
类、接口的注释采用 /** … */,描述部分用来书写该类的作用或者相关信息,块标记部分必须注明作者和版本。注释代码示例如下:
/**Title: XXXX DRIVER 2.0 *Description: XXXX DRIVER 2.0 *Copyright: Copyright (c) 2003 *Company:XXXX有限公司 * * @author Java Development Group * @version 2.0 */
如下示例也很常见:
/** * A class representing a window on the screen. * For example: * * Window win = new Window(parent); * win.show(); * * * @author Sami Shaio * @version %I%, %G% * @see java.awt.BaseWindow * @see java.awt.Button */ class Window extends BaseWindow { ... }
3.构造函数注释
构造函数注释采用 /** … */,描述部分注明构造函数的作用,不一定有块标记部分。
无块标记的示例如下:
/** * 默认构造函数 */
带块标记的示例如下:
/** * 带参数构造函数,初始化模式名、变量名称和数据源类型 * @param schema * Ref模式名 * @param name * Ref变量名称 * @param type * byVal数据源类型 */
4.域注释
域注释可以出现在注释文档里面,也可以不出现在注释文档里面。用/** … */的域注释将会被认为是注释文档而出现在最终生成的HTML报告里面(Javadoc),而使用/* … */的注释则会被忽略。例如:
/** * @作者 闫术卓 * @创建时间Sep 1, 2008 2:10:30 PM */
上面的域注释会生成下面的HTML报告:
@作者 闫术卓 @创建时间 Sep 1, 2008 2:10:30 PM
5.方法注释
方法注释采用 /** … */,描述部分注明方法的功能,块标记部分注明方法的参数,返回值、异常等信息。例如:
/** * 设置是否有外码约束 * * @param conn * Connection与数据库的连接 */
注意:初级程序员容易忽略Java代码的注释,而往往只关注代码的实现逻辑,高级程序员更加注重代码的规范性和可读性。
参考答案:(b)。
面试题6 int和Integer的区别是什么
考点:考察求职者对引用类型和原始类型的区分和理解。
出现频率:★★★★★
【面试题解析】Java提供引用类型和原始类型(或内置类型)两种不同的类型。另外,Java还为每个原始类型提供了封装类(Wrapper)。
表2.2列出了原始类型以及对应的对象封装类。
表2.2 原始类型和对应的封装类
引用类型和原始类型的行为完全不同,并且分别具有不同的语义。假定一个方法中有两个局部变量,一个变量为int原始类型,另一个变量是对一个Integer对象的对象引用,如下所示:
int i = 5; // 原始类型 Integer j = new Integer(10); // 对象引用
这两个变量都存储在局部变量表中,并且都是在Java操作数堆栈中被操作的。原始类型int和对象引用各占堆栈的32位(要表示一个int或一个对象引用,Java虚拟机实现至少需要使用32 位存储)。Integer对象对应的堆栈项并不是对象本身,而是一个对象引用。对象引用是指向对象存储所在堆中的某个区域的指针。Java中的所有对象都要通过对象引用访问。而当声明一个原始类型时,就为类型本身声明了存储。
引用类型和原始类型具有不同的特征和用法。以哪种类型的数据结构存储,决定了以此类型作为某个类的实例数据时所指定的默认值。对象引用实例变量的默认值为null,而原始类型实例变量的默认值与具体的类型有关。
许多程序的代码将同时包含原始类型以及它们的对象封装。程序员必须了解这两种类型是如何工作和相互作用的,以避免代码出错。
例如,不能对原始类型调用方法,但可以对对象调用方法。
int j = 5; j.hashCode(); // 错误 //... Integer i = new Integer(5); i.hashCode(); // 正确
使用原始类型无须调用new,也无须创建对象,这节省了时间和空间。混合使用原始类型和对象,也可能导致与赋值有关的意外结果,看起来没有错误的代码,可能无法完成预期工作。示例代码如下:
import java.awt.Point; class Assign { public static void main(String args[]) { int a = 1; int b = 2; Point x = new Point(0,0); Point y = new Point(1,1); // 1 System.out.println("a is " + a); System.out.println("b is " + b); System.out.println("x is " + x); System.out.println("y is " + y); System.out.println("Performing assignment and " + "setLocation..."); a = b; a++; x = y; // 2 x.setLocation(5,5); // 3 System.out.println("a is "+a); System.out.println("b is "+b); System.out.println("x is "+x); System.out.println("y is "+y); } }
这段代码生成以下输出:
a is 1 b is 2 x is java.awt.Point[x=0,y=0] y is java.awt.Point[x=1,y=1] Performing assignment and setLocation... a is 3 b is 2 x is java.awt.Point[x=5,y=5] y is java.awt.Point[x=5,y=5]
修改整数a和b后结果没意外。b的值被赋予整型变量a,a值增加了1。令人感到意外是在赋值并调用setLocation()函数之后,x和y对象的输出结果。我们在完成x=y赋值之后,特意对x调用了setLocation,x和y的值怎么会相同呢?将y赋予x,然后更改了x,这与我们对整数a和b进行的操作没什么不同。
这种混淆是由原始类型和对象的使用造成的。赋值对这两种类型所起的作用没什么不同。赋值运算符“=”左边的值等于右边的值,这一点对于原始类型(如前面的int类型值a和b)是显而易见的。对于非原始类型(如Point对象),赋值修改的是对象引用,而不是对象本身。
换句话说,x和y是对象引用,因此,在语句“x=y;”之后,x和y引用同一个对象,对x执行的所有方法与对y执行的方法都作用于同一个对象。
面试题7 哪些不属于Java的原始类型
请选择两个答案。
(a)"abc"
(b)'x'
(c)100.09F
(d)"hello"
(e)false
考点:考察求职者对Java原始类型的掌握。
出现频率:★★★★
【面试题解析】应该记住Java语言的8个原始类型:boolean、char、byte、short、int、long、float和double。
参考答案:
(a)、(d)。其他都是原始类型,而(a)、(d)是字符串,即一个String对象类型。
面试题8 String和StringBuffer的区别
考点:考察求职者对常用的字符串处理对象的掌握。
出现频率:★★★★
参考答案:
Java提供了两个字符串类:String和StringBuffer。它们可以储存和操作字符串,即包含多个字符的字符串数据。字符串String类提供了数值不可改变的字符串,而StringBuffer类提供的字符串对象可以进行修改。当知道字符数据要改变的时候,就可以使用StringBuffer类创建,典型地,可以使用StringBuffers来动态构造字符数据。
面试题9 指出Java的原始数据类型并说出其分类
考点:考察求职者对Java原始数据类型的掌握。
出现频率:★★★★
【面试题解析】Java的原始数据类型可以分为以下几种。
1.基本的整数类型
整数是从负无穷到正无穷之间的任意整型的数据,例如5、0、-128。因为计算机资源有限,并且需要存储器来存储变量,所以必须要灵活地定义数量。Java中有4 种已定义的整数类型:byte、short、int和long。每种类型以及它们的存储空间需求和取值范围,如表2.3所示。
整数类型的取值范围由各自的存储大小决定。例如,int类型需要32位,这使得一个int变量有232=4294967296个不同的取值。由于所有的Java变量都是有符号的(意思是它们必须隐性地传送正或负的值),有效范围变为-231(-2147483648)~231-1(2147483647)。Int类型变量的最大值是2147483647而不是2147483648,这是由于0作为一个有效值被包含进来了。
表2.3 整数类型范围
2.浮点类型
有时整型数据不够用,一些在数学和物理中使用的值通常用十进制小数表示。Java和C++一样,支持两种小数类型:float和double。表2.4给出了它们的存储方式和有效范围。
声明浮点变量的示例如下:
double pi = 2.141592653589793d; float velocity = 30.65f; double gravity = 9.81;
注意,声明一个float类型的值,必须以f(或F)作为后缀;否则,会被当作double类型。对于double值来说,d(或D)后缀是可选的。
表2.4 浮点类型范围
双精度数在本质上给出了相对于浮点数两倍的精度,但是,这是有代价的——通常是内存的消耗。在Java API中,大部分的方法返回类型和数据成员时使用double型。这在实际开发中值得注意。
3.Char类型
Java中一个字符(用char表达)表示Unicode字符集中的一个元素。Unicode字符由16位组成,因此,有65536个不同的字符可用,这与C++的标准128个ASCII字符不同。Unicode字符集提供了很大的灵活性,它能包含所有不同语言的字符以及常用符号。
字符由单引号括起来的单个字符表达,通常以16进制表示,范围为'\u0000'~'\uFFFF '(' u '告诉编译器用户在用两个字节字符信息表示一个Unicode字符)。正确使用字符的示例如下:
char letter; char lastInitial = 'R';
注意:与C++中不同,Java中一个字符数组没有必要组成一个字符串。Java API定义了自己的String类型。一般只有敏感信息,如密码字段,才会作为字符数组处理。这是因为,Java对象在没有被Java虚拟机作为不被引用的对象清空之前一直驻留在内存中,把敏感数据留在内存中可能会造成危险的局面。
4.布尔型
布尔型(以19世纪的数学家George Boole的名字命名)给了程序员为变量设置真值的能力。很多语言虽然使用boolean变量,但不把它看作一种独立的数据类型。在Java中,任何一个boolean变量只有两个有效值:true和false。boolean型没有等价的数值赋值,也不允许类型转换。还有,注意所有的if和while声明都相当于一个boolean结果。正确使用boolean型示例如下:
boolean isAlive = true; while(isAlive) { // 程序代码 }
参考答案:
Java的原始数据类型可以分为4类,如下所述。
• 整型:byte、short、int和long。
• 浮点型:float和double。
• Char型:char。
• 布尔型:boolean。
面试题10 理解和掌握Java语言中的变量初始化
编译并运行下面代码,请选择正确的一项。
public class TestVariableInit { public static void main(String[] args) { TestClass tc = new TestClass(); int j; System.out.println("tc.iStr = " + tc.iStr); System.out.println("tc.i =" + tc.i); System.out.println("j =" + j); } } class TestClass { int i; String iStr; }
(a)编译通过,输出:
tc.iStr = null tc.i =0 j =0
(b)编译通过,输出:
tc.iStr = tc.i =0 j =0
(c)编译错误,提示j未初始化。
考点:考察求职者对Java语言中的变量初始化的理解和掌握,特别是考察求职者对于对象变量的初始值null的理解。笔者在开发项目时,对这个问题深有体会,在项目试用阶段频繁产生错误,耗费了很多精力才找到症结,发现竟然是一个小小的null引发的。
出现频率:★★★★★
【面试题解析】Java语言中,变量存放着某一个具体类型的值,一般变量对应着一个名称标识符、指向一个类型和一个与之关联的值。Java变量的值有两种,一种是原始数据类型,另外一种是指向对象的引用,如图2.1所示。
图2.1 Java的变量类型示意图
在Java(TM) 编程语言中,变量的初始化依靠于其所在的上下文。请看下面代码:
int x; Dog fido;
假如x和fido都是实例变量,它们就分别被自动初始化为0和null。null是一个非凡的字面值,它能赋值给任何引用变量。一般说来,假如实例变量在定义的时候没有被显式地初始化,那么Java将变量自动初始化为“似零”的值,具体值由变量的数据类型决定,如表2.5所示。
表2.5 Java变量的默认初始化值
请参考如下代码:
public class TestVariableInit { public static void main(String[] args) { TestClass tc = new TestClass(); //打印出变量的初始化值 System.out.println("tc.iStr = " + tc.iStr); System.out.println("tc.i = " + tc.i); } } class TestClass { int i; // 初始化变量 String iStr; // 初始化变量 }
TestVariableInit运行后输出如下结果:
D:\>java TestVariableInit tc.iStr = null tc.i = 0
这种变量的默认初始化并不是在所有的情况下都适用,例如,一个局部变量(在方法体内声明的变量)假如没有显式初始化,根据所在Java环境不同,编译器会给出一个警告或者是报出一个错误。
实际情况是,以前有些Java环境对局部变量不提供初始化,也不给出警告或者错误。在这种情况下,值是垃圾,可能造成非常难于诊断的运行错误。
Oracle公司发布的Java开发包(JDK)中,编译器将在未初始化的局部变量的引用位置处报错。假如我们将TestVariableInit中的main()方法修改入下:
public static void main(String[] args) { TestClass tc = new TestClass(); String lStr; // 局部变量 int i; //局部变量 System.out.println("tc.iStr = " + tc.iStr); System.out.println("tc.i = " + tc.i); System.out.println("lStr = " + lStr); System.out.println("i = " + i); }
试图编译TestVariableInit会产生下面的输出:
D:\>javac TestVariableInit.java TestVariableInit.java:8: Variable lStr may not have been initialized. System.out.println("lStr = " + lStr); TestVariableInit.java:9: Variable i may not have been initialized. System.out.println("i = " + i); ^ 2 errors
对于此类情况,Java环境保证给出一个默认值,但是不答应开发者使用它,这有些不可思议。大部分的程序员都赞成为了可读性更好,实例变量应该初始化,并且局部变量必须初始化,这样不管在哪种Java环境中,源代码都可以被编译,而不必关心源代码的编写者是谁。
注意:对象的默认初始值为null,但是系统并没有创建一个相对应的对象,只是创建了一个可以存储对象引用的变量。这是Java程序员在软件开发中遇到的最常见的一个错误。令人恼火的是,这些错误只有在运行的时候才会出现。在一个大型软件项目的开发中,由于这个小小的错误导致大问题屡见不鲜。
例如,变量声明如下:
String str;
由于str是一个String类型的变量,系统会自动分配一个存储单元,用来存放String对象的引用,但是并没有创建一个String对象。代码如下:
public class TestVariableInit { public static void main(String[] args) { TestClass tc = new TestClass(); //千万注意,这里并没有编译错误,会产生运行时错误! System.out.println("tc.i =" + tc.iStr.length()); } } class TestClass { int i; String iStr; }
使用javac命令编译的时候是没有任何错误提示的,但是在运行该程序时,会返回一个空指针错误:
Exception in thread "main" java.lang.NullPointerException at TestVariableInit.main(TestVariableInit.java:10)
从这个示例可以看出,iStr的值为null,但不是一个String对象,所以tc.iStr.length()是错误的。
面试题11 哪几个是有效的声明语句
(a)char a='\u0061';
(b)char 'a'= 'a';
(c)char \u0061= 'a ';
(d)ch\u0061r a= 'a ';
(e)ch'a'r a='a';
考点:考察求职者对Java语言的变量声明和转义符的认识。
出现频率:★★★★
【面试题解析】在Java源代码中,可以使用Unicode值来表示字符型字,一般形式为\uxxxx,Java编译器会将这些Unicode值转换为字符来处理。
例如:
char \u0061='a ';
编译器会将其翻译为:
char a= 'a ';
表2.6给出了常见的Java转义符。
表2.6 Java常用的转义符
注意:在Java源代码中,不能使用\u000a和\u000d来替代换行和回车,这样编译器会将这些值解释为终止符,导致编译错误。
【面试题解析】参考前面介绍。
参考答案:(a)、(c)、(d)。
面试题12 选择正确的代码运行结果
编译运行下面代码,正确的运行结果是?
public class TestVariableInit { char \u0061='a'; String s="\u0061"; public static void main(String[] args) { TestVariableInit tc = new TestVariableInit(); System.out.println(tc.a); System.out.println(tc.s); } }
(a)编译错误;
(b)输出:a a;
(c)输出:a \u0061;
(d)编译正常,运行出现错误。
考点:考察求职者对Java语言的变量声明和转义符的认识。
出现频率:★★★★
参考答案:(b)。
面试题13 空文件是否为一个有效的Java程序源文件
考点:考察求职者对Java源文件结构的理解。
出现频率:★★★
【面试题解析】Java程序员最基本的知识之一就是掌握Java源文件的结构。Java源文件可以包括如下几个结构:
• package包;
• import内容;
• 类型声明。
其中,package用来制定该文件所处的包的名称,必须位于源文件顶端;import用来指定所引入的一个或者多个包;类型声明是任意的顶层类声明和接口的声明。
类和接口的定义次序是任意的,二者合起来称为类型声明。实际上,源文件可以不需要任何这样的定义。Java SDK要求一个源文件中最多只能定义一个公共类,同时该源文件的文件名必须同该类相同。例如,某个公共类名称为Hello,那么源文件名称必须为Hello.java。
参考答案:是。
面试题14 尝试编译代码并判断结果
编译下面的代码,检查结果。
import java.util.*; package com.dir; public Hello{ …… } Class Other{ …… }
请选择一个正确的答案。
(a)编译错误,类Hello和Other不能出现在一个源文件中。
(b)编译正确。
(c)编译错误,因为import不能位于源文件的顶端。
(d)编译错误,因为package必须在import之前。
(e)编译错误,因为Hello不能声明为公共的。
【面试题解析】从前面的讲解来看,明显的答案是(d),因为Java源文件的包声明必须在顶端。
参考答案:(d)。
面试题15 关于main()方法正确的描述是
(a)static void main(String[] args)。
(b)public static int main(String[] args)。
(c)public static void main(String args)。
(d)final static void main(String[] args)。
(e)public int main(String[] args,int argc)。
(f)static public void main(String[] args)。
考点:考察求职者对于Java源文件中的main()方法的掌握。
出现频率:★★★★
【面试题解析】在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第1个执行的方法就是main()方法。这个方法和其他的方法有很大的不同。方法的名字必须是main,方法必须是public static void类型的,方法必须接收一个字符串数组的参数等。
通过一个最简单的Java应用程序HelloWorld,来说明Java类中main()方法,程序的代码如下:
/** * Created by IntelliJ IDEA. * Date: 2013-08-03 * Time: 8:46:50 * Java中的main()方法详解 */ public class HelloWorld { public static void main(String args[]) { System.out.println("Hello World!"); } }
1.类
HelloWorld类中有main()方法,说明这是个Java应用程序,通过JVM直接启动运行的程序。既然是类,java允许类不加public关键字约束,当然类的定义只能限制为public或者无限制关键字(默认的)。
2.main()方法
这个main()方法的声明为:public static void main(String args[])。必须这么定义,这是Java的规范,和JVM的运行有关系。
当一个类中有main()方法,执行命令“java类名”,则会启动JVM执行该类中的main()方法。由于JVM在运行这个Java应用程序的时候,首先会调用main()方法,调用时不实例化这个类的对象,而是通过类名直接调用,因此需要是限制为公共(public)和静态(static)的。对于Java中的main()方法,JVM有限制,不能有返回值,因此返回值类型为void。
main()方法中需要一个输入参数,类型为String[],这个也是Java的规范,至于字符串数组的名字,是可以自己设定的。根据习惯,这个字符串数组的名字一般和Java规范范例中mian()方法的参数名保持一致(args)。
3.main()方法不能抛出异常
main()方法中的异常要么处理,要么不处理,不能继续抛出。public static int main(String args[]) throws Exception来定义main()方法是错误的。
4.main()方法中字符串参数数组作用
main()方法中字符串参数数组作用是接收命令行输入参数的,命令行的参数之间用空格隔开。下面给出一个例子,看看如何初始化和使用这个数组。
/** * Created by IntelliJ IDEA. * Date: 2013-08-03 * Time: 10:22:15 * 打印main()方法中的输入参数 */ public class TestMain { public static void main(String args[]){ System.out.println("打印main()方法中的输入参数!"); for(int i=0;i System.out.println(args[i]); } } }
执行方法和运行结果如下:
D:\Study\basetest\src>javac TestMain.java D:\Study\basetest\src>java TestMain 1 2 3 打印main()方法中的输入参数! 1 2 3
注意:main()方法作为一个特殊的规范,与普通的方法有很大区别,限制很多,理解其原理需要学习JVM相关知识。这是Java学习中大的障碍。
参考答案:(d)、(f)。