面试官常问的 Java 基础题 31-40
- 31.String s = new String("xyz");创建了几个 String 对象? 二者之间有什么区别?
- 32.String 和 StringBuffer 的区别
- 33.如何把一段逗号分割的字符串转换成一个数组?
- 34.数组有没有 length() 方法? String 有没有 length() 方法?
- 35.try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally{}里的 code 会不会被执行,什么时候被执行,在 return 前还是后?
- 36.下面的程序代码输出的结果是多少?
- 37.final, finally, finalize 的区别。
- 38.运行时异常与一般异常有何异同?
- 39.error 和 exception 有什么区别?
- 40.Java 中的异常处理机制的简单原理和应用。
31.String s = new String(“xyz”);创建了几个 String 对象? 二者之间有什么区别?
分两种情况: 1、如果String常量池中,已经创建"xyz",则不会继续创建,此时只创建了一个对象new String(“xyz”),此时为一个对象; 2、如果String常量池中,没有创建"xyz",则会创建两个对象,一个对象的值是"xyz",一个对象new String(“xyz”),此时为两个对象;这里需要了解几个概念:
-
栈:由JVM分配区域,用于保存线程执行的动作和数据引用。
-
堆:由JVM分配的,用于存储对象等数据的区域。
-
常量池constant pool :在堆中分配出来的一块存储区域,用于存储显式 的String,float或者integer.这是一个特殊的共享区域,可以在内存中共享的不经常改变的东西,都可以放在这里。
32.String 和 StringBuffer 的区别
String :值不可变,有equals方法。 StringBuffer :值可变,没有equals方法。
JAVA 平台提供了两个类:
String 和 StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个 String 类提供了 数值不可改变的字符串。 而这个StringBuffer类提供的字符串进行修改。
当你知道字符数据要改变的时候你就可以使用StringBuffer,可以使用StringBuffers来动态构造字符数据。
另外, String实现了equals方法, newString(“abc” ).equals(newString(“abc” ) 的结果为 true,而 StringBuffer 没有实现 equals 方法,所以, newStringBuffer(“abc” ).equals(newStringBuffer(“abc” )的结果为 false。
33.如何把一段逗号分割的字符串转换成一个数组?
用正则表达式
代码为:
String orgStr="a,b,c,d,e,f";
String [] result = orgStr.split(",");
34.数组有没有 length() 方法? String 有没有 length() 方法?
数组没有 length() 方法,String 有 length() 方法。
数组没有 length()这个方法,有 length 的属性。String 有 length()这个方法。
35.try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally{}里的 code 会不会被执行,什么时候被执行,在 return 前还是后?
finally{}里的 code 会被执行 ,在return中间执行。
try 中的 return 语句调用的函数先于 finally 中调用的函数执行,也就是说 return 语句先执行,finally 语句后执行,但 return 并不是让函数马上返回,而是 return 语句执行后,将把返回结果放置进函数栈中,此时函数并不是马上返回,它要执行 finally 语句后才真正开始返回!但此时会出现两种情况:
①、如果finally中也有return,则会直接返回并终止程序,函数栈中的return不会被完成!;
②、如果finally中没有return,则在执行完finally中的代码之后,会将函数栈中的try中的return的内容返回并终止程序;
catch同try;
36.下面的程序代码输出的结果是多少?
返回的结果是 2。
我可以通过下面一个例子程序来帮助我解释这个答案,从下面例子的运行结果中可以发现,try 中的 return 语句调用的函数先于 finally 中调用的函数执行,也就是说 return 语句先执行,finally 语句后执行,所以,返回的结果是 2。
Return 并不是让函数马上返回,而是 return 语句执行后,将把返回结果放置进函数栈中,此时函数并不是马上返回,它要执行 finally 语句后才真正开始返回。
在讲解答案时可以用下面的程序来帮助分析:
结论:finally 中的代码比 return 和 break 语句后执行
37.final, finally, finalize 的区别。
final 用于声明属性、方法和类,分别表示属性不可变(属性一旦被分配内存空间就必须初始化并且以后不可变)、方法不可覆盖(方法一旦定义必须有实现代码并且子类里不可被覆盖)和类不可被继承(不能再派生出新的子类);
finally 是异常处理的一部分,只能在try/catch语句中,并且附带一个语句块表示这段语句最终一定被执行;
finalize 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM 不保证此方法总被调用。
final属性:
被final修饰的变量不可变。不可变有两重含义:一是引用不可变,二是对象不可变。
final指的是引用不可变,即它只能指向初始时指向的那个对象。所以,被final修饰的变量必须被初始化。
final属性初始化可以通过以下几种方式:
-
在定义的时候初始化。
public class Test{ public final int a=0; private Test(){} }
-
final成员变量可以在初始化块中初始化,但不可在静态初始化块中初始化。
public class Test { public final String color; { color = "red"; } }
初始化块会先于构造方法执行。
-
静态final成员变量可以在静态初始化块中初始化,但不可在初始化块中初始化。
public class Test{ public static final int a; static{ a=0; } }
-
在类的构造器中初始化,但静态final成员变量不可以在构造函数中初始化。
public class Test{ public final int a; private Test(){ a=0; } }
当a这个属性被修饰为final,而非static的时候,它属于类的实例对象的资源,当类被加载进内存的时候这个属性并没有给其分配内存空间,而只是定义了一个变量a,只有当类被实例化的时候这个属性才被分配内存空间,而实例化的时候同时执行了构造函数,所以属性被初始化了,也就符合了当它被分配内存空间的时候就需要初始化。
final方法: 当一个方法声明为final时,该方法不允许任何子类重写这个方法,但子类仍然可以使用这个方法。
final参数: 用来表示这个参数在这个函数内部不允许被修改
public void testBaseType(final int i){
int n = i;
i = 9; //编译报错
System.out.println("i = "+i);
System.out.println("n = "+n);
}
final 类当一个类被声明为final时,此类不能被继承,所有方法都不能被重写。但这并不表示final类的成员变量也是不可改变的,要想做到final类的成员变量不可改变,必须给成员变量怎加final修饰。
一个类不能既被声明为abstract,又被声明为final !!!
finally 作为异常处理语句结构的一部分,它只能在try/catch语句中,并且附带一个语句块表示这段语句最终一定被执行,经常被用在需要释放资源的情况下。
Connection conn=null;
Statement stmt=null;
try{
conn=DriverManager.getConnection(url,uName,pwd);
stmt=conn.creatStatement();
stmt=executeUpdate(update);
}catch(Exception e)finally{
if((stmt!=NULL)
stmt.close();
if(conn!=NULL)
conn.close();
}
不管程序运行是否出现异常,finally中的代码一定会执行,这样能保证在任何情况下数据库的连接资源都能够被释放。
finalize : finalize 是 Object 类的一个方法,在垃圾回收器执行时会调用被回收对象的finalize()方法,可以覆盖此方法来实现对其他资源的回收。
一旦垃圾回收器准备好释放对象占用的空间,将首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。
38.运行时异常与一般异常有何异同?
异常表示程序运行过程中可能出现的非正常状态,
运行异常 表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。
一般异常 java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。
比如:我们从来没有人去处理过 NullPointerException 异常,它就是运行时异常,并且,这种异常还是最常见的异常之一。RuntimeException 体系包括错误的类型转换、数组越界访问和试图访问空指针等等。处理 RuntimeException 的原则是:假如出现 RuntimeException,那么一定是程序员的错误,例如,可以通过检查数组小标和数组边界来避免越界访问异常。
一般异常:定义方法时必须声明所有可能会抛出的checked exception;
在调用这个方法时,必须捕获它的checked exception,不然就得把它的exception传递下去;
checked exception是从java.lang.Exception类衍生出来的。
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。
java 编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
39.error 和 exception 有什么区别?
error 表示恢复不是不可能但很困难的情况下的一种严重问题,比如说内存溢出,不可能指望程序能处理这样的情况。
exception 表示 一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。
40.Java 中的异常处理机制的简单原理和应用。
当 JAVA程序违反了 JAVA 的语义规则时,JAVA 虚拟机就会将发生的错误表示为一个异常。
违反语义规则包括 2 种情况:
① JAVA 类 库内置的语义检查。
例如数组下标越界,会引发 IndexOutOfBoundsException;访问 null 的对象时会引发 NullPointerException。
② JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用 throw 关键字引发异常。
所有的异常都是 java.lang.Thowable 的子类。
异常是指java程序运行时(非编译)所发生的非正常情况或错误。
与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间、地点、人物、情节等信息,可以用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。
Java对异常进行了分类,不同类型的异常分别用不同的Java类来表示,
所有异常的根类为 java.lang.Throwable,Throwable,下面又派生了两个子类:Error和Exception,
Error 表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。
Exception 表示程序表示程序还能够克服和恢复的一种严重问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉,例如,数组脚本越界(ArrayIndexOutOfBoundsException)、空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不应该死掉。
java为系统异常和普通异常提供了不同的解决方案,编译器强制普通异常必须try···catch处理或用throws声明继续抛给上层调用方法处理,所以 普通异常也称为 checked异常 ,而系统异常可以处理也可以不处理,所以,编译器不强制用try…catch处理或用throws声明,所以系统异常也称为unchecked异常。
异常 | 说明 |
---|---|
ArithmeticException | 由于除数为0引起的异常 |
StackOverflowError | 堆栈溢出异常 |
ArrayStoreException | 由于数组存储空间不够引起的异常 |
ClassCastException | 当把一个对象归为某个类,但实际上此对象并不是由这个类创建的,也不是其子类创建的,则会引起异常 |
IllegalMonitorStateException | 监控器状态出错引起的异常 |
NegativeArraySizeException | 数组长度是负数,则产生异常 |
NullPointerException | 程序试图访问一个空的数组中的元素或访问空的对象中的方法或变量时产生异常 |
OutofMemoryException | 用new语句创建对象时,如系统无法为其分配内存空 间则产生异常 |
SecurityException | 由于访问了不应访问的指针,使安全性出问题而引起异常 |
IndexOutOfBoundsExcention | 由于数组下标越界或字符串访问越界引起异常 |
IOException | 由于文件未找到、未打开或者I/O操作不能进行而引起异常 |
ClassNotFoundException | 未找到指定名字的类或接口引起异常 |
CloneNotSupportedException | 程序中的一个对象引用Object类的clone方法,但 此对象并没有连接Cloneable接口,从而引起异常 |
InterruptedException | 当一个线程处于等待状态时,另一个线程中断此线程,从而引起异常 |
NoSuchMethodException | 所调用的方法未找到,引起异常 |
Illega1AccessExcePtion | 试图访问一个非public方法 |
StringIndexOutOfBoundsException | 访问字符串序号越界,引起异常 |
ArrayIdexOutOfBoundsException | 访问数组元素下标越界,引起异常 |
NumberFormatException | 字符的UTF代码数据格式有错引起异常 |
IllegalThreadException | 线程调用某个方法而所处状态不适当,引起异常 |
FileNotFoundException | 未找到指定文件引起异常 |
EOFException | 未完成输入操作即遇文件结束引起异常 |