Java程序员面试秘笈
上QQ阅读APP看书,第一时间看更新

第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]

修改整数ab后结果没意外。b的值被赋予整型变量aa值增加了1。令人感到意外是在赋值并调用setLocation()函数之后,x和y对象的输出结果。我们在完成x=y赋值之后,特意对x调用了setLocation,xy的值怎么会相同呢?将y赋予x,然后更改了x,这与我们对整数ab进行的操作没什么不同。

这种混淆是由原始类型和对象的使用造成的。赋值对这两种类型所起的作用没什么不同。赋值运算符“=”左边的值等于右边的值,这一点对于原始类型(如前面的int类型值ab)是显而易见的。对于非原始类型(如Point对象),赋值修改的是对象引用,而不是对象本身。

换句话说,xy是对象引用,因此,在语句“x=y;”之后,xy引用同一个对象,对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)。