21、当一个对象被当做参数传递给一个方法后,此方法可以改变这个对象的属性,并且可返回变化后的结果,那么这里到底是值传递还是引用传递?
值传递。Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中的时候,参数的值就是该对象的引用,对象的属性可以在被调用的过程中修改,但对对象引用的改变是不会影响到调用者的。
22、重载(overload)和重写(override)的区别?
方法的重载和重写都是实现多态的方式。区别在于,重载实现的是编译时的多态性,重写实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同、或者二者都不同)则视为重载;重载对返回类型没有特殊要求。重写发生在子类和父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常。方法重写要求参数列表必须完全与被重写方法的一致,构造方法不能被重写,声明为final的方法不能被重写,声明为static的方法不能被重写。重写方法的访问权限不能比父类中被重写的方法的访问权限更低。
23、为什么函数不能根据返回类型来区分重载?
函数的返回值只是作为函数运行之后的一个“状态”,他是保持方法的调用者与被调用者进行通信的关键,并不能作为某个方法的标识。方法在调用时,并不一定要指定返回类型信息,所以编译器不知道你要调用那个函数。若编译器可以根据上下文语境明确判断出含义,比如有两个函数,“void f() {}”和“int f() {}”,在int x = f();中,编译器可以根据上下文语境明确判断出含义,这么做完全没问题,然而有时候,我们可能调用一个方法的时候,会忽略他的返回值类型,因为我们关心的不是返回值,而是方法调用后的其他效果,由于这一类的存在,所以函数不能根据返回类型来区分重载。
24、char型变量能不能存储下一个中文汉字?
char类型变量可以存下一个中文汉字。在Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一方法),一个char类型占2个字节,16个比特位,所以存放一个中文汉字是没有问题的。
使用Unicode意味着字符在JVM内部和外部有不同的表现形式,在JVM内部都是Unicode,当这个字符被从JVM内部转移到外部时,例如存入文件系统的时候,就需要进行编码转换了,所以在Java中有字节流和字符流,以及在字符流和字节流之间进行转换的转换流,比如InputStreamReader和OutputStreamReader;这两个类是字节流和字符流之间的适配器,承担了编码转换的任务。
25、调用下面的方法,得到的返回值是什么?
public int getNum(){ 1
try{ 2
int a = 1/0; 3
return 1; 4
}catch (Exception e){ 5
return 2; 6
}finally{ 7
return 3; 8
}
}
答案是3。分析:代码在执行到第三行的时候,遇到MathException,这时候第四行的代码就不会执行了,代码直接跳到catch代码块中去,程序走到了第六行,异常机制有这么一个原则,那就是如果在catch中遇到return或者是异常能使该函数终止的话,那么如果有finally就必须要先执行完finally代码块里的代码,然后再返回值。因此代码又跳到了第八行,可惜的是第八行直接是一个return语句,这个时候方法执行结束了,因此第六行代码就不会被执行了。如果finally里面仅仅是处理了一些释放资源的操作,并不是返回,那这道题的结果就是2,。因此返回值是3.
26、Error和Exception的区别?
Error类和Exception类的父类都是Throwable类,他们的区别如下:
Error类一般是指与虚拟机有关的问题,比如系统崩溃、虚拟机错误、内存空间不足、方法调用栈溢出等,对于这类错误导致的应用程序中断,仅靠程序本身是无法恢复的,遇到这样的错误,建议程序终止运行。
Exception类表示程序可以处理的异常,可以捕获且可能恢复,遇到这样的异常,应该尽可能处理异常,使程序恢复运行,而不是随意终止异常。
Exception类下面又分了两个子类:运行时异常(RuntimeException)和受检查的异常(CheckedException),运行时异常在编译的时候可以通过,但是一执行就终止了,程序不会处理运行时异常,出现这类异常,程序会终止。受检查的异常(CheckedException)要么是呀try-catch捕获处理,要么使用throws字声明抛出,交给他的父类去处理,否则编译时通不过的。
27、switch是否能作用在byte上?是否可以作用在long上?是否可以作用在String上?
Java5以前的switch(expr)中,expr只能是byte、short、char、int。从Java5开始,Java中引入了枚举类型,expr也可以是enum类型。从Java7开始,expr还可以是字符串(String)类型,但是长整型long在目前所有版本都是不支持的。
28、throw和throws的区别?
throw:throw语句用在方法体内,表示抛出异常,有方法体内的语句处理;throw是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行throw一定是抛出了某种异常。
throws:throws语句是用在方法声明声明后面,表示如果抛出异常,交由该方法的调用者来进行异常的处理;throws主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的异常的类型;throws表示出现异常的一种可能性,并不一定会发生这种异常。
29、final、finally、finalize的区别?
final:用于声明属性、方法和类分别表示属性不可变、方法不可覆盖、被其修饰的累不可继承。
finally:异常处理语句结构中的一部分,表示总要执行!
finalize:Object类的一个方法,在垃圾回收器执行的时候会调用被回收对象的这个方法,也可以覆盖此方法提供垃圾收集时的其他资源回收,例如文件关闭等。该方法更像是一个对象生命周期的临终方法,当该方法被系统调用的时候,则代表该方法即将死亡。需要注意的是,我们主动上去调用该方法并不会导致该对象的死亡,这是一个被动的方法(其实就是回调方法),不需要我们自己调用。
30、String、StringBuilder、StringBuffer的区别?
Java平台提供了两种类型的字符串:String和StringBuilder/StringBuffer;他们都可以存储和操作字符串,区别在于:
String是只读字符串,也就意味着String引用的字符串内容是不可以改变的。初学者可能会有如下误解:
String str = "abc";
str = "bcd";
字符串str明明是可以改变的啊!其实不然,str仅仅是一个引用对象,它开始的时候指向一个字符串对象“abc”,第二行代码让str重新指向了一个新的对象“bcd”;而“abc”对象并没有任何改变,但是该对象便成为了一个不可达对象。
StringBuilder/StringBuffer表示字符串对象可以直接进行修改。
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的;StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。因此效率上,StringBuilder理论上也比StringBuffer更高。