越是貌似简单的面试题其中的玄机就越多
1.对于String类型的数据进行"=="比较结果?
例题
String s1 = "AB";
String s2 = new String("AB");
String s3 = "A";
String s4 = "B";
String s5 = "A" + "B";
String s6 = s3 + s4;
System.out.println(s1 == s2);
System.out.println(s1 == s5);
System.out.println(s1 == s6);
解析
* ==:如果比较的对象时基本数据类型,则比较的是数值是否相等;如果比较的是引用数据类型,则比较的是地址值是否相等.
* String s1 = "AB";
最多创建一个String对象,最少不创建String对象.如果在方法区中的常量池中存在”AB”,那么s1直接引用,不需要创建String对象,否则先在常量池中创建”AB”,再引用
* String s2 = new String("AB");
最多创建两个String对象,至少创建一个String对象,先看常量池中是否有”AB”,如果没有先创建,然后在堆中创建一个String对象,引用常量池中”AB”的地址,再把自己的地址给s2.
new关键字绝对会在堆空间中创建内存区域,所以至少创建一个对象.所以s1和s2的地址值是不同的.s1 == s2返回的就是false.
* s1和s5都是常量池中的两个常量,常量相比较,值相同,则返回true;
* String s6 = s3 + s4;将产生一个String对象到堆中.而s1本身是常量池的一个常量.两者的地址值肯定是不相同的返回的就是false.
2.类型转换中的问题?
例题
short s1 = 1; s1 = s1 + 1; 有错吗?
short s1 = 1; s1 += 1; 有错吗?
解析
前者不正确,后者正确.对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算结果也是int型,需要强制转换类型才能赋值给short型.而short s1 = 1; s1 += 1;可以正确编译,是因为s1+=1;相当于s1 = (short) (s1 + 1);其中有隐含的强制类型转换.
3.Integer类型的数值比较?
例题
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 150;
Integer i4 = 150;
System.out.println(i1 == i2);
System.out.println(i3 == i4);
解析
如果整型字面量的值在-128~127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象.
4.String,StringBuffer,StringBuilder的区别?
* String:字符串常量,在修改时不会改变自身;若修改,等于重新生成新的字符串对象.
* StringBuffer:在修改时会改变对象自身,每次操作都是对StringBuffer对象本身进行修改,不是生成新的对象.
* StringBuilder:和StringBuffer一样.
* String:对象定义后不可变,线程安全;
* StringBuffer:是线程安全的(对调用方法加入同步锁),执行效率较慢,适用于多线程下操作字符串缓冲区大量数据.
* StringBuilder:是线程不安全的,适用于单线程下操作字符串缓冲区大量数据.
StringBuilder与StringBuffer有公共父类AbstractStringBuilder(抽象类).
5.Java中的值传递和引用传递?
值传递案例
public class Demo {
public static void main(String[] args) {
Demo demo = new Demo();
int a = 3;
demo.test1(a);
System.out.println("main方法中的a="+a);
}
private void test1(int a){
a = 5;
System.out.println("test1的方法中的a="+a);
}
}
运行结果是:
test1方法中的a=5;
main方法中的a=3;
解析
按值传递是指的是在方法调用时,传递的参数是按值的拷贝传递.
按值传递的重要特点:传递的是值的拷贝,也就是说传递后就互不相关了.
引用传递案例
public class Demo {
public static void main(String[] args) {
Demo demo = new Demo();
A a = new A();
a.age = 10;
demo.test1(a);
System.out.println("main方法中的age="+a.age);
}
private void test1(A a){
a.age = 20;
System.out.println("test1的方法中的age="+a.age);
}
}
class A{
public int age = 0;
}
解析
按引用传递是指的是在方法调用是,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址.传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间).