2.3 精选面试、笔试题解析
根据前面介绍的Java基础知识,本节总结了一些在面试或笔试过程中经常遇到的问题。通过本节的学习,读者将掌握在面试或笔试过程中回答问题的方法。
2.3.1 Java基本数据类型之间如何转换
题面解析:本题主要考查应聘者对基本数据类型的熟练掌握程度。看到此问题,应聘者需要把关于数据类型的所有知识在脑海中回忆一下,其中包括基本数据类型都有哪些、数据类型的作用等,熟悉了数据类型的基本知识之后,数据类型之间的转换问题将迎刃而解。
解析过程:数据类型之间的转换有两种方式:自动转换和强制转换。
1.自动转换
自动转换规则:从存储范围小的类型转换到存储范围大的类型,即byte→short(char)→int→long→float→double。
(1)存储范围小的类型自动转换为存储范围大的类型。如byte类型的数据可以赋值给short、int、long类型的变量;short、char类型的数据可以赋值给int、long类型的变量;int类型的数据可以赋值给long类型的变量等。
(2)存储范围大的类型转换为存储范围小的类型时,需要加强制转换符。
(3)byte、short、char之间不会互相转换,并且三者在计算时首先转换为int类型。
(4)实数常量默认为double类型,整数常量默认为int类型。
2.强制转换
强制转换规则:从存储范围大的类型转换到存储范围小的类型,即double→float→long→int→short(char)→byte。
语法格式:
(type)value
其中,type是要强制类型转换后的数据类型。
2.3.2 谈谈你对面向对象的理解
题面解析:本题是对面向对象知识点的考查,应聘者在回答该问题时,不能照着定义直接背出来,而是要阐述自己对面向对象概念的理解,另外,还要解释关于面向对象更深一层的含义。
解析过程:在解释面向对象之前,先介绍一下什么是对象。
在Java语言中,把对象当作一种变量,它不仅可以存储数据,还可以对自身进行操作。每个对象都有各自的属性及方法,Java就是通过对象之间行为的交互来解决问题的。
在我看来,面向对象就是把构成问题的所有事物分解成一个个的对象,建立这些对象去描述某个事物在解决问题中的行为。而类就是面向对象中很重要的一部分,类是很多个具有相同属性和行为特征的对象所抽象出来的,对象是类的一个实例。
类还具有三个特性,即封装、继承和多态。
(1)封装:将一类事物的属性和行为抽象成一个类,只提供符合开发者意愿的公有方法来访问这些数据和逻辑,在提高数据的隐秘性的同时,使代码模块化。
(2)继承:子类可以继承父类的属性和方法,并对其进行拓展。
(3)多态:同一种类型的对象执行同一个方法时可以表现出不同的行为特征。通过继承的上下转型、接口的回调以及方法的重写和重载可以实现多态。
2.3.3 Java中的访问修饰符有哪些
题面解析:本题主要考查应聘者对修饰符的掌握程度,知道访问修饰符有哪些以及它们的使用范围和区别等。
解析过程:Java中有四种访问修饰符,分别为public、private、protected和default。
(1)public:公有的。用public修饰的类、属性及方法,不仅可以跨类访问,而且允许跨包(package)访问。
(2)private:私有的。用private修饰的类、属性以及方法只能被该类的对象访问,其子类不能访问,更不允许跨包访问。
(3)protected:介于public和private之间的一种访问修饰符。用protected修饰的类、属性以及方法只能被该类本身的方法及子类访问,即使子类在不同的包中也可以访问。
(4)default:默认访问模式。在该模式下,只允许在同一个包中进行访问。
☆注意☆ protected修饰符所修饰的类属于成员变量和方法,只可以被子类访问,而不管子类是不是和父类位于同一个包中。default修饰符所修饰的类也属于成员变量和方法,但只可被同一个包中的其他类访问,而不管其他类是不是该类的子类。protected属于子类限制修饰符,而default属于包限制修饰符。
2.3.4 重载和重写
试题题面:什么是方法的重载和重写?它俩之间有什么区别?
题面解析:本题属于对概念类知识的考查,在解题的过程中需要先解释方法重载和重写的概念,然后介绍各自的特点,最后再分析方法重载和重写之间的区别。
解析过程:
1.方法重载
1)构成方法重载的必要条件
定义在同一个类中,方法名相同,参数的个数、顺序、类型不同构成重载。
2)方法重载的目的
为了解决参数的个数、类型、顺序不一致,但功能一致、方法名一致的重名问题的情况。
3)方法重载的特点
(1)发生在同一个类中。
(2)方法名称相同(参数列表不同)。
(3)参数的个数、顺序、类型不同。
(4)和返回值类型以及访问权限修饰符、异常声明没有关系。
(5)重载是多态的一种表现形式。
(6)重载的精确性原则,就是赋给变量值的时候要按照变量的规则赋值。
2.方法重写
如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程称为方法的重写。
1)方法重写的目的
父类的功能实现无法满足子类的需求,需要重写。
2)方法重写的特点
(1)发生在具有子父类两个关系的类中。
(2)方法名称相同。
(3)参数的列表完全相同。
(4)返回值类型可以相同或者是其子类。
(5)访问权限修饰符不能够严于父类。
(6)重写是多态的必要条件。
(7)抛出的异常不能比父类的异常大。
(8)私有修饰的方法不能够被继承,就更不可能被重写。
(9)构造方法不能被重写。
2.3.5 什么是构造方法
题面解析:本题主要考查应聘者对Java中构造方法的理解,因此应聘者不仅需要知道什么是构造方法、构造方法有哪些特点,而且还要知道怎样使用构造方法。
解析过程:构造方法是指定义在Java类中的用来初始化对象的方法。通常使用“new+构造方法”的方式来创建新的对象,还可以给对象中的实例进行赋值。
1)构造方法的语法规则
(1)方法名必须与类名相同。
(2)无返回值类型,不能使用void进行修饰。
(3)可以指定参数,也可以不指定参数;分为有参构造方法和无参构造方法。
例如:调用构造方法
Student s1; s1 = new Student();//调用构造方法
2)构造方法的特点
(1)当没有指定构造方法时,系统会自动添加无参的构造方法。
(2)构造方法可以重载:方法名相同,但参数不同的多个方法,调用时会自动根据不同的参数选择相应的方法。
(3)构造方法是不被继承的。
(4)当手动指定了构造方法时,无论是有参的还是无参的,系统都将不会再添加无参的构造方法。
(5)构造方法不但可以给对象的属性赋值,还可以保证给对象的属性赋一个合理的值。
(6)构造方法不能被static、final、synchronized、abstract和native修饰。
2.3.6 局部变量与成员变量有什么区别
题面解析:本题主要考查局部变量和成员变量的区别,应聘者需要掌握变量的基础知识,包括什么是变量、什么是常量、变量的命名规则以及它们之间的区别等内容。看到问题时,应聘者脑海中要快速想到关于变量的各个知识点,才能够快速、准确地回答出该问题。
解析过程:
(1)局部变量是指在方法或者方法代码块中定义的变量,其作用域是其所在的代码块。
(2)成员变量是指在类的体系结构的变量部分中定义的变量。
(3)局部变量和成员变量的区别
①定义的位置
局部变量:定义在方法的内部。
成员变量:定义在方法的外部,即直接写在类中。
②作用范围
局部变量:只适用于方法中,描述类的公共属性。
成员变量:整个类中都可以通用。
③默认值(初始化)
局部变量:没有默认初始值,需要手动进行赋值之后才能使用。
成员变量:有默认初始值,如int类型的默认值为0;float类型的默认值为0.0f;double类型的默认值为0.0。
④内存的位置
局部变量:位于栈内存。
成员变量:位于堆内存。
⑤生命周期
局部变量:在调用对应的方法时,局部变量因为执行创建语句而存在,超出自己的作用域之后会立即从内存中消失。
成员变量:成员变量随着对象的创建而创建,随着对象的消失而消失。
2.3.7 解释一下break、continue以及return的区别
题面解析:本题是在笔试中出现频率较高的一道题,主要考查应聘者是否掌握循环控制语句的使用。在解答本题之前需要知道break、continue和return的用法,经过对比,进而就能够很好地回答本题。
解析过程:
1.break
break用于完全结束一个循环,跳出循环体。无论是哪种循环,只要在循环体中有break出现,系统会立刻结束循环,开始执行循环之后的代码。
break不仅可以结束其所在的循环,还可结束其外层循环。在结束外层循环时,需要在break后加一个标签,这个标签用于标识外层循环。Java中的标签就是一个紧跟着英文冒号(:)的标识符,且必须把它放在循环语句之前才有作用。例如:
2.continue
continue用于终止本次循环,继续开始下次循环。continue后的循环体中的语句不会继续执行,下次循环和循环体外面的都会执行。
continue的功能和break有相似的地方,但区别是continue只是终止本次循环,接着开始下一次循环,而break则是完全终止循环。例如:
3.return
return并不是用于跳出循环,而是结束一个方法。如果在循环体内的一个方法内出现return语句,则return语句将会结束该方法,紧跟着循环也就结束。与continue和break不同的是,return将直接结束整个方法,不管这个return处于多少层循环之内。例如:
2.3.8 Java中的基本数据类型有哪些
题面解析:本题通常出现在面试中,考官提问该问题主要是想考查应聘者对基本数据类型的熟悉程度。数据类型是Java最基础的知识,只有掌握了基础知识,才能在以后的开发工作中应用自如。
解析过程:Java中的基本数据类型可以分为整数类型、浮点数类型、字符类型和布尔类型四种。
1.整数类型
1)byte
byte是数据类型为8位、有符号、以二进制补码表示的整数,用于表示最小数据单位;取值范围-27~27-1,其中默认值为0。
2)short
short是数据类型为16位、有符号、以二进制补码表示的整数;取值范围-215~215-1,其中默认值为0。
3)int
int是数据类型为32位、有符号、以二进制补码表示的整数;取值范围-231~231-1,其中默认值为0;一般整型变量默认为int类型。
4)long
long是数据类型为64位、有符号、以二进制补码表示的整数;取值范围-263~263-1,其中默认值为0;long主要使用在需要较大整数的系统上。
2.浮点数类型
1)float
float是数据类型为单精度、32位、符合IEEE 754标准的浮点数,其中默认值为0.0f;浮点数不能用来表示精确的值。
2)double
double是数据类型为双精度、64位、符合IEEE 754标准的浮点数,其中默认值为0.0d;浮点数的默认类型为double类型,double类型同样不能表示精确的值。
3.字符类型
字符(char)类型是一个单一的16位的Unicode字符;取值范围为\u0000(0)~\uffff(65 535);char数据类型可以储存任何字符,但需要注意不能为0个字符。
4.布尔类型
布尔(boolean)数据类型表示一位的信息;boolean数据类型只有true和false两个值,只作为一种标志来记录true/false的情况,其中默认值为false。
2.3.9 Java中this的用法
题面解析:本题不仅会出现在笔试中,而且在以后的开发过程中也会经常遇到。因此掌握this的用法是非常重要的。
解析过程:this在类中代表当前对象,可以通过this关键字完成当前对象的成员属性、成员方法和构造方法的调用。
Java的关键字this只能用于方法体内。当一个对象创建后,Java虚拟机就会给这个对象分配一个引用自身的指针,这个指针的名字就是this。因此,this只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现this,并且this只和特定的对象关联,而不和类关联,同一个类的不同对象有不同的this。
那么什么时候使用this呢?
当在定义类中的方法时,如果需要调用该类对象,就可以用this来表示这个对象。
this的作用:
(1)表示对当前对象的引用。
(2)表示用类的成员变量,而非函数参数。
(3)用于在构造方法中引用满足指定参数类型的构造方法,只能引用一个构造方法且必须位于开始的位置。
2.3.10 接口和抽象类
试题题面:接口是否可以继承接口?抽象类是否可以实现接口?抽象类是否可以继承实体类?
题面解析:本题属于在笔试中高频出现的问题之一,主要考查关于接口和抽象类的知识点,在解答本题之前需要了解什么是接口、什么是抽象类、什么是抽象方法,同时还需要把接口和抽象类区分开来,以防混淆。
解析过程:
1)接口
接口属于一种约束形式,只包括成员定义,不包含成员实现的内容。
2)抽象类
抽象类主要是针对看上去不同,但是本质上相同的具体概念的抽象。抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。一个类不能同时被abstract和final修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。
3)抽象方法
抽象方法是指一些只有方法声明而没有具体方法体的方法。抽象方法一般存在于抽象或接口中。抽象方法不能被声明成final和static类型;任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类;如果一个类包含若干个抽象方法,那么该类必须声明为抽象类,但抽象类可以不包含抽象方法;抽象方法的声明以分号结尾。
(1)接口可以继承(extends)接口。通过关键字extends声明一个接口是另一个接口的子接口。由于接口中的方法和常量都是public,子接口将继承父接口中的全部方法和常量。例如:
public interface InterfaceA{ } interface InterfaceB extends InterfaceA{ }
(2)抽象类可以实现(implements)接口。当一个类声明实现一个接口而没有实现接口中所有的方法,那么这个类必须是抽象类,即abstract类。例如:
public interface InterfaceA{ } abstract class TestA implements InterfaceA{ }
(3)抽象类可以继承(extends)实体类,但前提是实体类必须有明确的构造函数。例如:
public class TestA{ } abstract class TestB extends TestA{ }