1. 请问如下代码的输出结果是什么?
public class MethodTest {
public static void main(String[] args) {
String str = "6";
test(str);
System.out.println(str);
}
public static void test(String str){
str += "10";
}
}
A. 610 B. 6 C.16 D. 10
看运行结果:
这是因为在java 方法中都是值传递,String str = 6 的str和test方法中传的参数str根本就不是一个变量,形参str是在栈上新开辟了一块空间,指向了原str所指向的堆内存地址。后续的操作与原str根本没有关系。看下面的图就明白了。
2. 请问下面的程序在运行过程中创建了几个对象
public class MethodTest {
public static void main(String[] args) {
String str1 = new String("abc");
String str2 = new String("abc");
String str3 = new String("abcd");
}
}
A. 3 B. 4 C.5 D. 6
正确答案是5个。程序在执行的时候都是从等号右边开始向等号左边执行的。也就是系统先读到"abc",会创建一个字符串对象,再读到new String(),又会在栈上开辟一块空间创建一个对象。第二行,先读到"abc",此时由于第一行已经在常量池中产生了一个"abc"对象,故不再产生对象,再次new,又创建一个对象,第三行,在常量池创建“abcd”对象,再new。一共创建5个对象。
3. 请说出下列程序的执行结果
public class MethodTest {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "ab";
String str3 = "c";
String str4 = str2 + str3;
String str5 = str2 + str3;
String str6 = new String("abc");
String str7 = str2 + "C";
String str8 = "ab" + "c";
System.out.println(str1 == str6);
System.out.println(str1 == str4);
System.out.println(str4 == str5);
System.out.println(str1 == str7);
System.out.println(str1 == str8);
}
}
字符串拼接,其实是StringBuilder的append操作
最后要把StringBuilder再返回成String,返回时用StringBuilder的toString()方法,此方法返回了一个new对象
字符串拼接时,只有纯常量的"+“不会转为StringBuilder
直接在常量池内寻找是否存在已有值
否则,只要存在一个字符串变量的”+",都会转为StringBuilder调用append
4. 求以下代码的输出结果
public class MethodTest {
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
int i = 0;
try{
i = 1;
return i;
}catch(Exception e){
i = 2;
return i;
}finally{
i = 3;
}
}
}
答案为1。异常体系中,若finally代码块中存在return语句,则try…catch语句失效。
若finally无return,try…catch有return语句,则try…catch代码块先暂存代码块中的值,然后执行finally代码块,最后返回暂存值。
5. 读程序写结果
// 假设thread1一定先启动
class Task implements Runnable{
@Override
public void run() {
if(Thread.currentThread().getName().equals("A")){
testA();
}else{
testB();
}
}
// synchronized作用于普通成员方法,锁的是当前对象
private synchronized void testA(){
System.out.println("A");
//testB(); 若将这句释放掉注释,则会输出B,因为虽然A拿到了锁,调用B的仍然是线程A,
B发现持有锁的线程就是他自己,自然能执行
while(true){}
}
private synchronized void testB(){
System.out.println("B");
}
}
public class MethodTest{
public static void main(String[] args) throws InterruptedException {
Task task = new Task();
Thread thread1 = new Thread(task,"A");
Thread thread2 = new Thread(task,"B");
thread1.start();
thread2.start();
}
}
输出为A。因为synchronized在修饰方法时,相当于锁的是当前对象,只有一个对象,被A拿到了,A在死循环,B就拿不到。