Java 基础面试300题 (111-140)
111.什么是Java包? 有什么优点?
包是相关Java类型的集合。包中可以包括相关的类、接口和枚举。使用包来组织软件代码有几方面的优点:
- 包有助于将相关代码保存在一起。
- 包有助于避免命名冲突。不同的包中可以拥有相同名称的类或其他Java类型。
- 包还有助于访问控制。如果不通过声明
public
关键字来明确允许,否则包外的代码无法访问包中的代码。
112. Java中有哪几种访问说明符?
访问说明符控制特定类成员可以从哪里访问 。可以为实例字段和方法指定访问说明符。Java有如下4种类型的访问说明符:
- Private: 此种类成员只能从声明它的类中访问。
- **Protected:**此种类成员可从包内的所有类访问,以及包外的子类进行访问。
- Public: 此种类成员可以从包之内和之外的所有类访问。
- Default: 此种类成员可以在包内访问,但不能在包外访问。
113.如何创建包?
使用package
关键字来创建包, 它后面是给包的名称。包名称应该是有效的Java标识符。package
语句应该是java源码文件中的第一个语句。如下代码示例:
java
package demo;
public class MyClass {
//instance fields and methods
}
上述代码中,package
语句创建了一个名称是demo
的包。 然后在包中创建了一个名为MyClass
的类。 如前所述,package
语句是代码中的第一个语句。
114. JDK中有哪些主要内置默认包?
以下是Java JDK中的一些内置包:
-
java.util.Collection
: 此包包括所有Collection API类。因此,List、ArrayList、Set、HashSet、Map、HashMap等类/接口都是此包的一部分。 -
java.io
: 此包包含输入/输出操作的类,如InputStream、FileInputStream、FileOutputStream、BufferedReader、BufferedWriter等。 -
java.awt
: 此包包含用于创建组件、容器、框架等图形用户界面的所有类。 -
java.util.concurrent
: 此包包含所有并发编程相关的类,如Future、Executor、ExecutorService等。
115. 下面代码有效吗?
java
package demo1;
public class Base {
protected int a;
}
package demo2;
public class Sub extends Base {
public void doSomething() {
System.out.println("Value of a is "+a);
}
}
上述代码是有效的,不会导致任何编译或运行时错误。此代码创建了一个名为Base
的超级类,以及一个名为Sub
的 子类。
这两个类位于不同的包中。基类有一个protected
的字段,子类的doSomething()
方法中访问了该字段。根据Java的访问规则,上述访问是有效的。子类不能够访问自基类的private
字段, 但可以访问基类的protected
字段,即使子类和基类在不同的包中也是如此。
116. import
关键字的作用是什么?
import
关键字用于在代码中导入其他包, 从而可以使用它们的功能。可以使用import
导入标准Java 包,如java.util
等,也可以导入其它用户定义的包。
import
关键字后面需要跟包的名称。如果要导入特定的类,则需要指定类的名称。为了导入整个包, 可以在包名称后使用通配符*
。以下是一些使用import
的例子:
java
import.java.util.List; //导入 List 接口
import java.io.*; //导入 java.io 包的全部类
117.访问说明符protected
和default
的区别是什么?
这两个访问说明符有下面几个区别:
-
protected
访问说明符是一个关键字,说明成员的访问级别是受保护的,即protected
。 而default
则表示默认的访问级别, 它没有单独的关键字。如果类成员没有任何访问说明符, 那么它就具有默认的访问级别。 -
当成员是受保护的访问级别(使用
protected
访问说明符)时,可以从包内的所有类以及包外的子类访问该成员 。 -
当成员具有默认访问级别时(没有任何访问说明符), 该成员仅可允许包内的所有类访问,无法在包外访问。
118.下面代码片段有效吗?为什么?
java
package demo1;
public class MyClass1 {
int a; //Line 1
}
package demo2;
public class MyClass2 {
public void doSomething() {
MyClass1 obj = new MyClass1(); //Line 2
obj.a = 5; //Line 3
}
}
上述代码第3行将导致编译错误。类MyClass1
位于一个名为demo1
的包中,它有一个字段a
,由于没有明确访问说明符,因此该字段具有默认访问权限。类MyClass2
位于一个名为demo2
的包中,它的doSomething()
方法在第3行访问 MyClass1
类的对象的字段a
, 因为该字段具有默认访问权限,无法在软件包外访问,因此第3行将导致编译错误。
119. 编译执行以面代码时会发生什么?
java
package com.questions;
public class CoreJava {
private String getQuestion() {
return "Question1";
}
}
package com.questions;
class JSP extends CoreJava {
public void getJSPQuestion() {
Sytem.out.println(getQuestion());
}
}
上述代码将出现编译错误。类CoreJava
定义了私有方法getQuestion()
,子类的getJSPQuestion()
方法中调用了基类getQuestion()
方法。由于该方法是私有的, 无法在子类中访问,因此会发生编译错误。
120. Java的java.lang
包主要是什么内容?
java.lang
包含许多对Java编程语言很重要的类,如下是一些示例:
- 基础数据的包装类,用于基础数据的装箱和拆箱。如
Byte
、Boolean
、Integer
、Double
等类。 - 字符串相关类,用于字符串处理。如
String
、StringBuffer
和StringBuilder
等重要的类。 - 线程相关类,用于创建和管理多线程应用。 如
Thread
、Runnable
等类。 - 异常处理相关类,用于Java的异常处理。 如
Throwable
,Exception
等类。
121.解释throw
、throws
和throwable
。
这几个关键字都与java语言的异常处理机制有关。
throws
关键字用于指定特定方法抛出未处理的异常或需要单独处理的多个异常。它说明, 你不想在当前方法中处理错误条件,而是希望将异常处理委托给代码的其他部分。
throw
关键字用于在方法内显式抛出异常。
Throwable
是异常层次结构中的基类。可以通过扩展Throwable
类可以创建自定义异常。
122. 编译并执行以面代码时,输出是什么?
java
class Test {
try {
System.out.println("This is try block");
}
System.out.println("Try block is executed"); //Line 1
catch(Exception exp) {
System.out.println("This is catch block");
}
}
上述代码会出现编译错误。这是因为第1行的代码是在try
语句块结束之后,但在catch
语句块之前, Java不允许在try
语句块和catch
语句块之间输入代码,所有代码要么在try
语句块之内,要么在 catch
语句块之内,而不能在它们中间。
123.编写代码演示try/catch/finally
结构。
以下代码演示如何使用try/catch/finally
语句块处理异常 :
java
try {
System.out.println("This is try block");
} catch {
System.out.println("This is catch block");
}
finally {
System.out.println("This is finally block");
}
所有可能出现异常的代码都应放在try
语句块中, 在try
语句块之后, 需要指定一个或多个catch
子句。在每个catch
语句块中,需要指定要捕获的异常类型,以及发生异常时要执行的代码,也就是异常处理代码。finally
子句是可选的,需要放在try
语句块或者最后一个 catch
语句块之后。无论是否发生异常,finally
语句块中的代码都会执行。
124. 下面代码的输出是什么?
java
class ExceptionTest {
public static void main(String argument[]) {
callMethod();
}
static void callMethod() {
int intValue = 100 / 0;
System.out.println("intValue is: "+intValue);
}
}
上述代码编译时没有任何错误。 但在执行时,会抛出一个带有堆栈跟踪信息(错误信息或报告)的ArithmeticException
,如下所示:
Exception in thread "main" java.lang.Arithmetic Exception-- / by zero
at ExceptionTest.callMethod(ExceptionTest.java:12)
at ExceptionTest.main(ExceptionTest.java--9)
这是因为除数不能够为0。
125. 在Java中如何处理异常?
在Java中进行使用try-catch-finally
这三个语句进行异常处理。 将可能出现错误的语句放在try
块中。发生异常时需要执行的代码应放在可选的一个或多个catch
捕获块中,此外,还需要指定希望捕获的异常类型。可以为不同类型的异常指定多个catch
捕获块。在所有捕获块之后,可以指定一个可选的finally
块, 无论是否抛出异常, 该语句块中代码都会执行。
以下代码演示了try-catch-finally
语句:
java
try {
// Code to be monitored for exceptions
}
catch (ExceptionType 1) {
// Instructions to follow if an exception occurs
}
catch (ExceptionType 2) {
// Instructions to follow if an exception occurs
}
catch (ExceptionType n) {
// Instructions to follow if an exception occurs
}
finally {
// this block is definitely executed even if an exception is thrown or not
}
126.下面代码片段的输出是什么?
java
public class MyClass1 {
public static void main(String abc[]) {
try {
int no;
no = 52 / 0; //Line 1
} catch (ArithmeticException e) { //Line 2
System.out.println("ArithmeticException");
} catch (ArrayIndexOutOfBoundsException e) { //Line 3
System.out.println("Array Out Of Bound");
} catch (Exception e) { // any other exception //Lin2 4
System.out.println("Sorry Unhandled Exception");
} finally { // this will be executed //Line 5
System.out.println("I am done!");
}
System.out.println("Thank You!!"); //Line 6
}
}
}
第1行除数是0,导致ArithmeticException
,被第2行的 catch
块捕获,其中的代码打印 ArithmeticException
,因为finally
总是执行,所以无论是否发生错误,最后控制会转移到第5行的finally
块并打印I am done
,最后控制 转移到第6行,代码打印Thank You!!
因此代码最终打印如下输出:
java
ArithmeticException
I am done!
Thank You!!
127. 如何在代码中处理抛出检查的异常?
如果一个方法抛出了检查异常,有两种方法可以处理它:
方式A :在方法主体中使用try/catch
,如下代码所示:
java
public void myMethod(){
try {
//code here
}
catch (CheckedException e) {
}
}
在上述代码中,当抛出CheckedException
时,将被方法中的catch
块捕获并进行处理。
方式B : 在方法声明中 throws
子句
java
public void myMethod () throws CheckedException{
//code here
}
在上述代码中 ,当代码中出现CheckedException
时,因为定义来了throws
语句, 异常将被抛出到方法之外,由调用此方法的代码进行处理。
128. finally
子句的作用是什么?
无论是否发生异常都需要始终执行的代码应放在finally
子句中。例如,关闭打开的文件,或者关闭数据库连接等等这些清理代码都应该放在finally
子句中。如果这些代码没有放在finally
子句中,比如说放在try
语句块中,如果发生异常,Java不能够保证会执行这代码 ,从而导致潜在资源泄露。
129. Error
和Exception
之间有什么区别?
在Java 异常处理模型中,java.lang.Throwable
是所有异常类的超类。它有两个子类,Exception
和 Error
, 这两者之间有几个区别:
-
Exception
表示由应用程序本身引起的编程错误,如访问空值、除以0、写入文件时出错等。Error
表示在运行时环境中在代码之外发生的错误,例如内存不足等。 -
Exception
是应用程序可以处理和恢复的条件。另一方面,Error
是不正常的情况,表明应用程序出现了无法恢复的严重问题。 -
Exception
即可以是检查的(Checked
),又可以是非检查的(Unchecked
)。检查的异常需要处理,或者在方法声明中的 指定throws
子句。另一方面,Error
总是非检查的,不需要在throws
子句中声明。
130.什么是RuntimeException
?
java.lang.RuntimeException
是java.lang.Exception
类的子类。RuntimeException
及其子类也被称为非检查异常。这是因为编译器不会强迫你处理此类异常。因此,即使编写了可能抛出非检查异常的代码,编译器也不会导致错误。RuntimeException
的一些示例是ArithmeticException
、NullPointerException
、ArrayIndexOutOfBoundsException
131.什么是字符串字面量?
字符串字面量是一组用双引号括起来的字符,可以直接赋值给字符串变量。下面代码显示如何将字符串字面量"I'm a literal"分配给字符串变量 name
:
java
String name = "I'm a literal";
132. 下面代码的输出是什么?
java
class StringDemo {
public static void main (String strArgs[]) {
String strVar = "Welcome";
strVar.concat(" to Java");
System.out.println(strVar);
}
}
此代码打印以下输出:
Welcome
Java字符串是不可变的对象, 方法concat()
只是将值附加到变量 strVar
,但不会将附加后的字符串分配回给变量strVar
。
为了打印字符串Welcome to Java
,代码需要修改如下:
java
strVar = strVar.concat(" to Java");
133.执行以下代码时,输出会是什么?
java
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("Core ");
stringBuffer.append("Java");
System.out.println("The resultant StringBuffer Value is:"+stringBuffer);
StringBuffer.append()
方法将指定值附加到StringBuffer
中, 上述代码将打印以下输出:
The resultant StringBuffer Value is:Core Java
134.以下代码片段的输出是什么?
java
String xValue = "xyz";
String yValue =
xValue.concat("qrs").toUpperCase().replace('Z', 'c');
System.out.println(yValue);
上述代码中,首先将变量xValue
与值qrs
连接形成新的值 xyzqrs
,然后,将新值转换为大写, 变为XYZQRS
, 然后,将其中的字符 Z
替换为c
,因此最终代码将打印 以下输出 :
XYcQRS
135.由哪些方式将字符串字面量分配给字符串变量 ?
以下几种方式都可以将字符串字面量分配给字符串变量:
java
a. String strValue1 = "String Literal 1";
b. String strValue2 = new String("String Literal 2");
c. String strValue3 = new String(); strValue3 = "String Literal 3";
d. String strValue4 = strValue3;
方法a通过分配一个字符串字面量来创建字符串变量strValue1
。方法b通过使用接受字符串值的字符串构造函数创建变量strValue2
。方法c使用默认字符串构造函数创建变量strValue3
,然后为其分配一个值。方法d通过为变量strValue4
分配另一个字符串变量来创建变量strValue4
。
136. String
类有哪些常用方法?
以下是String
类中一些常用的方法:
方法 | 描述 |
---|---|
concat() | 将值附加到当前字符串。 |
length() | 返回字符串的长度,即字符串中的总字符数。 |
replace() | 将字符串中的特定字符或字符串替换为其他值。 |
substring() | 获取当前字符串从指定位置开始的子字符串。 |
trim() | 移除字符串中的空格。 |
toUpperCase() | 将字符串中的所有字符转换为大写。 |
toLowerCase() | 将字符串中的所有字符转换为小写。 |
equals() | 将当前字符串与指定字符串进行比较。它返回一个布尔值,即比较的结果。 |
equalsIgnoreCase() | 不考虑大小写,比较当前字符串与指定字符串, 它返回一个布尔值,即比较的结果。 |
137. StringBuffer
类和StringBuilder
类有什么区别?
StringBuffer
和StringBuilder
这两个类都可用于处理字符串,它们都是可变的,与不可变的java.lang.String
不同。 二者的主要差别是,StringBuilder
类不是线程安全的,StringBuffer
类是线程安全的。这意味着,当应用程序中执行两个或多个线程时,不应使用StringBuilder
。此外,由于StringBuilder
没有同步负担, 它比StringBuffer
的性能更好。
138.如何不使用循环即可反转字符串?
有几种方法可以在不使用循环的情况下反转字符串。方法之一是在StringBuilder
类上使用反转方法。如下代码所示 :
java
StringBuilder sBuilder = new StringBuilder("Core Java");
sBuilder.reverse();
System.out.println(sBuilder);
上述代码将打印以下输出:
java
avaJ eroC
同样,也可以使用StringBuffer
类的reverse()
的方法,实现反转字符串。
139. 如何将字符串转换为大写?
String
类有一个toUpperCase()
方法,用于将字符串转换为大写。如下代码示例:
java
String myStr = "Hello World";
myStr = myStr.toUpperCase();
System.out.println(myStr);
上述代码打印以下输出:
java
HELLO WORLD
140. 如何将整数转换为字符串?
下面几种方法都可以将整数转换为字符串:
- 直接将整数括在引号中:可以将数字括在引号中,然后分配给字符串变量:
java
String strNum = "10";
- 使用
String.valueOf
方法:String
类有一个valueOf
方法 , 使用它可以将整数转换为字符串,如下所示:
java
String strNum = String.valueOf(10);
- 使用
Integer.toString()
方法:Integer
类有一个toString()
方法,可用于将整数转换为字符串,如下所示:
java
String numStr2 = new Integer(10).toString();