Java 基础面试300题 (51-80)
051.Java中有那几种循环结构?
循环结构也被称为迭代语句,用于重复执行代码块。Java具有以下几种循环结构:
while
循环: while
语句检查条件,只要条件为真,就会重复执行代码块。它的语法如下:
while (condition){
//body of the loop
}
do while
循环:只要条件为真,do while
循环也会重复执行代码块。与while
不同,它在循环末尾检查条件,因此循环体至少执行一次。它的语法如下:
do{
//body here
} while(condition);
for
循环: for
循环用来在一组范围内的值上进行遍历。它如果条件为真,它会一直迭代,如果条件为假,则退出循环。 语法如下:
for(initialization;condition;iteration){
//body of the loop
}
for each
循环: for each
用于循环一个数组或对象集合。在循环的每次迭代中,它从数组或集合中获取下一个元素,并为该元素执行循环内的代码。如下示例:
for(datatype var: collection) {
//body of the loop
}
052.用示例解释if-else
语句的语法。
以下是if-else
语句的示例:
int iValue = 10;
if(iValue > 1000) {
System.out.println(“iValue is > 1000”);
}
else {
System.out.println(“iValue is < 1000”);
}
If
语句后面需要一个条件。如果条件求值为真,则执行if
语句后面的代码。如果条件求值为false
,则执行else
关键字后面的代码。在上述代码中,变量iValue
的值为10
,因此if
语句中的条件求值为false
,因此执行else
中的代码块, 从而输出以下结果:
iValue is < 1000
053.以下哪行代码将编译,哪行会导致错误?
int iValue=5;
while (iValue) {} //Line 1
while (false) {} //Line 2
while (iValue = 5) {} //Line 3
while (iValue == 5) {} //Line 4
第1行将导致错误,因为整数值无法传递给while
循环。它需要一个布尔值。
第2行没有语法错误,编译通过,因为在while
循环中使用了布尔值false
第3行会导致编译错误,因为表达式iValue=5
不是布尔值,它实际上是一个赋值语句
第4行没有语法错误,编译通过,因为表达式iValue==5
为布尔值。
054. 下面代码中,如果boolA
是false
,而boolB
是true
,输出会是什么?
public void foo( boolean boolA, boolean boolB) /* Line 1 */
{
if(boolA ) {/* Line 3 */
System.out.println(“X”); /* Line 5 */
}
else if(boolA && boolB) {/* Line 7 */
System.out.println( “X && Y”); /* Line 9 */
}
else { /* Line 11 */
if (!boolB ){ /* Line 13 */
System.out.println( “notY”); /* Line 15 */
}
else{ /* Line 17 */
System.out.println( “In here” ); /* Line 19 */
}
}
}
上述代码输出是:In here
。解释如下:
由于boolA
是 false
,因此第5行将永远不会执行, 同时第7行也不会执行, 控制将进入第11行的else
代码块 。由于boolB
为true
,第13行的if
语句不会被执行, 而执行第13行的 else
语句块。因而输出 In here
。
055.以下程序的输出是什么?
public class SwitchDemo
{
final static short caseVal = 2;
public static void main(String [] abc)
{
for (int iterNo=0; iterNo < 3; iterNo ++) {
switch (iterNo) {
case caseVal: System.out.print(“a “);
case caseVal–1: System.out.print(“b “);
case caseVal–2: System.out.print(“c “);
}
}
}
}
由于caseVal
是常量,因此在编译时对其进行计算。在第一次迭代时, iterNo = 0
,第3个case
语句为true
,因此打印c
,在第二次迭代时,iterNo = 1
,因此第二个case
语句为真,因此它打印b
,因为第二个case
语句后没有 break
语句,继续执行第三个case
语句,再次打印c
,在第三次迭代期间,iterNo = 2
,因此第一个case
为true
,因此打印a
, 由于其后没有 break
语句,将再次执行后面的两个case
语句,分别打印出b
和c
,最终输出结果是:
Output:c b c a b c
056. 编译并执行下面代码,输出是什么?
int iValue1 = 100;
int iValue2 = 200;
boolean isTrue() {
return true;
}
if(((iValue1 > iValue2) && (iValue2 < 50))
|| isTrue()) { //Line 1
System.out.println(“This is True”);
}
else {
System.out.println(“This is False”);
}
第1行的if
语句使用了OR
运算符。 当其任何一个操作数为true
时,OR
运算符返回true
。 由于 isTrue()
方法返回 true
,if
语句将返回 true
。 因此,无论AND(&&)
操作的结果如何,if
语句中的表达式都会返回true
,从而产生下面输出:
This is True
057. break
和 continue
语句有什么作用?
break
关键字可以在循环中使用。 当遇到break
语句时,循环会立即终止,控制权会转移到循环之外。
continue
关键字也可以在循环中使用,用来停止执行循环中当前迭代的下一个语句,并将控制权转移到循环的开始。
058. 编译并执行下面代码,输出是什么?
for(int iValue=0; iValue<5; iValue++) {
System.out.println(iValue); //line 1
continue; //line 2
System.out.println(iValue + 1);
}
代码编译并在执行时显示以下输出:
0
1
2
3
4
执行第1行的System.out
语句之后,开始执行第2行的continue
语句, 它会跳过循环主体的其余部分,将控制权转移到循环的开始,因而会忽略其后的System.out
语句。
059.编译并执行下面代码,输出是什么?
for(int iValue=0; iValue<5; iValue++) {
System.out.println(iValue);
break;
System.out.println(iValue + 1);
}
代码编译并在执行时显示以下输出:
0
它只输出了0
。这是因为break
语句停止执行循环中的下一个语句,并退出循环,控制权转移到循环之外。
060.编译并执行下面代码,输出是什么?
for (;;) {
System.out.println(“Will this get printed?”);
}
上述代码虽然编译通过,但它却执行了一个无限循环,因为没有循环控制变量,也没有要检查的条件。因此,此代码将一直打印输出Will this get printed?
061. 编译并执行下面代码, 输出是什么?
int iValue = 50;
for (;iValue < 100;) {
System.out.println(iValue);
}
在上述代码中,for
循环语句没有初始化语句和迭代语句,它虽然指定了一个终止条件, 但因为变量iValue
从未增加, 因此,终止条件形同虚设,实际上成了一个无限循环。 代码会无限地打印值 50
。
062.举一些 for-each
循环的例子。
以下是for-Each
循环的一些示例:
示例 1:
Integer [] integerArray = {10, 100, 1000};
for(Integer integer: integerArray) {
// do something here
}
示例2:
int [] iValue = {10, 100, 1000};
for(int iValue1: iValue) {
// do something here
}
示例 3:
Electronics [] electronics = {new Camera(), new Laptop()};
for(Electronics e: electronics) {
// do something here
}
示例 4:
List<Integer> numbers = Arrays.asList(4,10,12);
for(int num: numbers) {
// do something here
}
063.下面代码的输出是什么?
for(int iValue = 0; iValue < 10; iValue++) {
}
System.out.println(iValue); //Line 1
上述代码将无法编译。这是因为变量iValue
的范围仅在for
循环内,而不是在for
循环之外, 由此导致第1行出现编译错误。
064. 编译并执行下面代码,输出是什么?
int iValue = 10;
switch(iValue) {
case 5: System.out.println(“5”);
case 8: System.out.println(“5”);
default: System.out.println(“This is Default”);
case 9: { System.out.println(“9”); break; }
case 11: System.out.println(“11”);
}
上述代码没有语法错误,编译通过。虽然没有case 10
,但它会匹配 default
,并执行其内的代码块,因而会输出This is Default
。由于上述default
代码块最后没有break
语句,其后的case
语句也会被执行,输出9
,又由于case 9
中有break
语句 ,因而在输出 9
之后会立即中断swith
语句,控制转移到swith
语句外。 最终显示以下输出:
This is Default
9
Java 面试问题集- 类和方法
065. 编译和执行下面代码片段,输出是什么?
static void main(String argument[]) {
System.out.println(“This gets printed”);
}
上述代码编译得很好。但在执行时,会出现以下错误:
Error: Main method not found in class
这是因为主方法没有公共访问说明符,在类之外无法访问。因此,JVM无法访问主方法,从而发生错误。
066.实例变量可以声明为静态吗?
实例变量不能声明为静态。如果实例变量被声明为静态,那么该变量将成为类变量。
067. 编译和执行下面代码时会发生什么?
class Laptop {
Laptop(String laptopName) {
System.out.println(“Laptop Name is ....”);
}
public static void main(String argument[]) {
Laptop l = new Laptop();
}
}
答案:
代码将无法编译,并会出现以下编译错误:
The constructor Laptop() is undefined.
这是因为代码中没有定义默认的构造函数。由于有一个带参数的构造函数,因此Java不能自动创建默认的无参数构造函数。要使上述代码正常工作,需要添加以下显式构造函数:
Laptop() {
}
068.如果没有明确指定构造函数,幕后会发生什么?
如果未明确指定构造函数,编译器会自动生成默认的无参数构造函数。每当创建新对象时,都会使用此默认构造函数。
069. 编译执行下面代码时会发生什么?
class Electronics {
Electronics() {
}
public void displayPrice() {
Electronics();
}
}
编译上述代码时会出现显示错误:
The method Electronics() is undefined for the type Electronics.
这是因为像上述方式调用构造函数是非法的。
070.构造函数有哪些访问修饰符?
以下是构造函数的可能访问修饰符:
-
private: 表示构造函数只能从其类中访问
-
public: 表示构造函数可以从类外部任何其它包中的任何类中访问
-
protected: 表示构造函数可以从同样包中的任何其它类中访问
071.下面代码片段的输出是什么?
public class MyClass {
public void callMe(int a) {
System.out.println(“Call me with int argument”);
}
public void callMe(long a) {
System.out.println(“Call me with long argument”);
}
public static void main(String args[]) {
MyClass myClassObj = new MyClass();
int i = 6;
myClassObj.callMe(i);
}
}
由于方法callMe()
以整数值调用,因此接受整数参数的方法被调用。如果我们更改 i
为 long
的数据类型,则接受long类型参数的方法将被调用。因此代码的输出如下:
Call me with int argument
072. 如何定义构造函数?举例说明。
构造函数是一种特殊方法,名称与类名相同,但没有返回类型。创建新对象时,必须调用某个构造函数。构造函数中的代码逻辑在创建类对象后立即执行。所以构造函数经常用于设置对象的初始状态, 例如为实例变量设置初始值。如下面代码所示:
public class Electronics {
int price;
Electronics(int price) {
this.price = price;
} //constructor
public static void main(String argument[]) {
Electronics e = new Electronics(); //Line 1
}
}
在上述代码中,一旦执行第1行,JVM就会调用构造函数,执行其中的逻辑,从而初始化price
字段。
073. void
关键字有什么作用?
void
关键字用来说明方法没有返回值。 下面代码说明如何使用 void
关键字来说明方法没有返回值:
public void doSomething(){
}
074. 构造函数和普通方法之间有什么区别?
构造函数和普通方法之间有下面几个区别:
-
构造函数的名称必须与类名称相同,普通方法可以具有任何名称。
-
构造函数没有返回类型,但不必使用
void
关键字说明,而普通方法具有返回类型。如果方法不返回任何值,则需要使用void
关键字说明。 -
创建类对象时,会自动调用构造函数,普通方法需要显式调用。
-
如果一个类没有声明构造函数,Java会自动创建一个默认的构造函数。如果一个类没有方法,Java不会自动添加方法。
075. 用代码示例解释this
关键字。
this
关键字用于指代当前对象。它可用于引用与当前对象对应的字段或方法。如下代码示例:
public class Book {
private String name;
private String author;
public Book(String name, String author) {
this.name = name;
this.author = author;
}
public void doSomething(Book book) {
}
public void doSomethingElse(Book book) {
this.doSomething(book);
}
}
上述代码创建一个名为Book
的类,该类定义了一个构造函数,具有name
和 author
两个输入参数 (书名和作者), 并使用 this
关键字初始化当前对象的书名和作者。 从代码中可以看到, 使用this
关键字有助于区分实例字段和传入的参数变量,如果它们的名称相同的话。
this
关键词也可以与方法一起使用。如上代码所示,doSomethingElse
方法通过使用 this
关键字调用类中的doSomething
方法。
076. 类和对象之间有什么区别?
类和对象之间有下面几个区别:
-
类是一个模板,定义了一个新的数据类型, 对象是该数据类型的具体值。
-
Java不会为类分配任何内存, 创建对象时,需要为对象分配必要的内存。
-
类是一个逻辑实体,对象则是具体的物理存在。
-
类使用
class
关键字声明(定义),对象则使用new
关键字创建。 -
类没有状态,对象有状态。
077.用代码示例解释new
关键字。
new
关键字通过调用类的构造函数来创建对象,并为对象分配内存。如下代码所示:
Person person1 = new Person();
其中,Person
是类的名称,person1
是Person
类型的对象,new
关键字后跟Person
类的构造函数,然后为person1
对象分配内存。new
关键字只适用对象类型,不 适用基础数据类型,如int
、double
等。
078.下面代码片段的输出是什么?
public class MyClass2 {
private int field1 = 0;
private static int field2 = 0;
public static void main(String[] args) {
MyClass2 object1 = new MyClass2();
object1.field1++; //Line 1
object1.field2++; //Line 2
MyClass2 object2 = new MyClass2();
object2.field1++; //Line 3
object2.field2++; //Line 4
System.out.println(object2.field1); //Line 5
System.out.println(object2.field2); //Line 6
}
}
上述代码中,类MyClass2
有2个字段,field1
和field2
。field1
是一个实例字段,而field2
是一个静态字段。对于实例字段,类中的每个对象都有自己副本, 因此,对象object1
和对象object2
都会有自己的field1
副本,第1行和第3行增加该字段,并在第5行打印对象object2
的field1
的值,也就是1。 对于静态字段,只有一个静态字段的副本对应于类的所有对象。因此,只有一个field2
的副本对应于对象object1
和对象object2
。因此,第2行和第4行将增加相同的副本,并在第6行打印值2。
最终,上述代码将打印以下输出:
1
2
079. return
关键字的作用是什么?
return
关键字用于在方法结束前,返回一些计算结果的值。返回的值必须与方法的声明返回类型匹配。如下代码示例 :
public int add(int num1, int num2){
int sum = num1+num2;
return sum;
}
add
方法返回int
类型, 即两个操作数之和。
即使方法不返回任何内容,也可以选择性地指定return
关键字,而不带任何值。如下代码示例:
public void printSum(int a, int b) {
int sum = a+b;
System.out.println(sum);
return;
}
在上述情况下,方法必须声明为void
返回类型,表示此方法不返回任何内容。
080.什么是内部类?有哪几种不同类型的内部类?
内部类是在另一个类的主体内定义的任何类。内部类有4种类型,如下所示:
-
嵌套类:类在另一个类的主体中定义。它可以访问外部类的所有成员。
-
静态嵌套类:类在另一个类的主体中定义, 但它无法访问外部类的非静态成员。
-
方法局部内部类:在另一个类的方法中定义的类称为方法局部内部类。这样的内部类只能访问外部类的常量。
-
匿名内部类:一个没有名称且在定义时只能实例化一次的类被称为匿名内部类。它没有构造函数,因为它没有名称。它也不能是静态的。