31、String s = new String("xyz");创建了几个StringObject?是否可以继承String类?
答:产生两个对象。一个是存储于常量池中的字符串常量xyz,另一个是由new产生的,存储于堆中。String类是不可变类,是不可以继承的。
32、String和StringBuffer的区别
答:String类的内容一旦声明后是不可改变的,改变的只是其内存的指向,而StringBuffer类的对象内容是可以改变的。
String对象不可修改指的是对象本身不可修改,而不是引用不可修改。
String a=”hello”,这行代码的意思是声明一个String类型的引用变量叫做a,在内存中创建一个String对象(值为"hello"),然后把这个对象的引用赋值给变量a。
a=”world”。如果继续执行这句话,是在内存中另外创建了一个String对象(值为"world"),然后把这个新对象的引用赋值给变量a,而不是把原来的内存中的那个“hello”的String对象值变为“world”。此时其实已经造成了前一个值hello的内存浪费,因为已经没有对象指向它了。
对于StringBuffer,不能像String那样直接通过赋值的方式完成对象实例化,必须通过构造方法的方式完成。StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入,删除等操作,使用StringBuffer要更加适合一些
33、下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d";
答:1个。”a”,”b”,”c”,”d”都是常量。对于常量,编译时就直接存储它们的字面值而不是它们的引用
在编译时就直接讲它们连接的结果提取出来变成了"abcde"
该语句在class文件中就相当于String s = "abcde" ,所以只是产生一个对象。
34、try {}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?
答:在try后面的finally里的code会被执行。关于执行时机,应该是处在中间状态。严格说是在return的前面。也就是说,程序先执行try中的语句,当执行到return的时候,此时要返回的结果已经准备好了。程序把这个要返回的结果临时存储起来,接下来转到finally中去执行。当把finally中的代码执行完成后,继续回到try中,执行return。把结果返回。
以上的情况是finally中没有return。如果finally中也有return。那执行到finally中的return后,程序就直接返回了。就不会再回到try中的return里去了。请看下列代码:
public int get(){
int a=1;
try {
a=2;
System.out.println("1");
return a;
} finally {
a=3;
System.out.println("finally");
return a;//去掉此行,则得到的a=2而不是3。虽然finally中改了a=3,但由于try中要返回的a值=2,已经保存到一个临时变量去了。所以finally中再改a的值是没有用的。程序最后返回的结果还是2。
//如果finally中有return,则最后返回的结果就从finally中return了,try中的return就不运行了。
}
}
35、final, finally, finalize的区别。
答:final在Java中可以用来修饰类,方法和变量。
当修饰类时,表明这是个最终类,此类不可以被继承,并且该类中的所有方法都被隐匿定义为final方法。
当修饰方法时,表明这个方法不能被子类所修改,即不能被重写。
当修饰变量时,表明这是个常量,这个常量只能被赋值一次,赋值后其值就不能被修改。
finally是异常处理中的关键字,只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下。
finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。也就是说是用来做垃圾回收的。
一个对象的finalize()方法只会被调用一次,而且finalize()被调用不意味着gc会立即回收该对象,所以有可能调用finalize()后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会调用finalize(),产生问题。 所以,推荐不要使用finalize()方法。
36、运行时异常与一般异常有何异同?
答:Java 提供了两类主要的异常 :runtime exception 和 checked exception 。 checked 异常也就是我们经常遇到的 IO 异常,以及 SQL 异常都是这种异常。 对于这种异常, JAVA 编译器强制要求我们必需对出现的这些异常进行 catch 。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆 catch 块去处理可能的异常。
Runtime exception即运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层。此时如果是多线程,就由Thread.run()抛出,如果是单线程,那就由main()方法抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。
运行时异常是Exception的子类,表明我们也可以用try-catch进行处理,只不过往往我们不去处理
37、error和exception有什么区别?
答:Exception和Error都是继承于Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。
Exception是java程序运行中可预料的异常情况,程序员可以获取到这种异常,并且对这种异常进行业务外的处理。
Error是java程序运行中不可预料的异常情况,这种异常发生以后,会直接导致JVM不可处理或者不可恢复的情况。所以这种异常不可能抓取到,比如OutOfMemoryError、NoClassDefFoundError等。
其中的Exception又分为检查性异常和非检查性异常。两个根本的区别在于,检查性异常必须在编写代码时,使用try catch捕获(比如:IOException异常)。非检查性异常 在代码编写时可以忽略捕获操作(比如:ArrayIndexOutOfBoundsException),这种异常是在代码编写或者使用过程中通过规范可以避免发生的。
附加:有一个比较经典的面试题目, 就是 NoClassDefFoundError 和 ClassNotFoundException 有什么区别?
NoClassDefFoundError是Error,ClassNotFoundException是Exception。
38、简单说说Java中的异常处理机制的简单原理和应用。
答:异常指Java程序运行时(非编译)所发生的非正常情况或错误。java对异常进行了分类,不同类型的异常使用了不同的java类,所有异常的根类为java.lang.Throwable。Throwable派生了2个子类:Error和Exception。
Error表示程序本身无法克服和恢复的一种严重错误。Exception表示能克服和恢复,其中又分为系统异常和普通异常。
系统异常是软件本身缺陷导致的问题,也就是软件开发问题考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但这种情况下可以选择让软件继续运行或死掉。如数组越界问题(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException),类转换异常(ClassCastException);普通异常是运行环境的变化或异常导致的问题,是用户能够克服的问题,如网路掉线、硬盘空间不足、IO异常发生。
39、Java 中堆和栈有什么区别?
答:栈内存用来存储局部变量和方法调用,堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中。
栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。
而堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。
栈的内存要远远小于堆内存。
40、能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象?
答:可以转换。如果int类型的值大于byte类型的范围,int类型的高位将被丢弃。
欢迎关注,下一篇将给大家带来集合中的一些问题,请大家持续关注!