一、以下代码输出结果是:
public class Example{
String str = new String("good");
char[ ] ch = { 'a' , 'b' , 'c' };
public static void main(String args[]){
Example ex = new Example();
ex.change(ex.str,ex.ch);
System.out.print(ex.str + " and ");
System.out.print(ex.ch);
}
public void change(String str,char ch[ ]){
str = "test ok";
ch[0] = 'g';
}
}
运行结果:good and gbc
解析:
首先说下String确实是个不可变对象,这个不可变是JDK特有的,写JAVA的人特意针对的。
但是这与本题无关,题目中的形参str只是原引用ex.str的一个引用副本,传的是一个副本地址值,这个值与ex.str地址值是不一样的,但是它们同时指向了堆中的对象new String(“good”),当你在函数中改变形参也就是地址的副本值也就是这句str=“test ok"只是将副本地址指向常量"test ok”,并没有改变原ex.str的指向方向,它还是指向对象new String(“good”)的。
char数组与String一样传的也是地址的副本,但是关键是形参ch它没有新的指向 ch[0]只是ch在指向原对象时改变了对象的内部结构, 所以在ex.ch指向与它是同一个对象的情况下当然也会随之变化。
二、java提供了一个系统级的线程,即垃圾回收器线程。用来对每一个分配出去的内存空间进行跟踪。当JVM空闲时,自动回收每块可能被回收的内存,GC是完全自动的,不能被强制执行。程序员最多只能用System.gc()来建议执行垃圾回收器回收内存,但是具体的回收时间,是不可知的。当对象的引用变量被赋值为null,可能被当成垃圾。
三、在java的多态调用中,new的是哪一个类就是调用的哪个类的方法。(错误)
解析:
1.成员变量:编译和运行都参考左边。
2.成员函数(非静态):编译看左边,运行看右边
3.静态函数:编译和运行都看左边。
举例:
public class Father {
public void say(){
System.out.println("father");
}
public static void action(){
System.out.println("爸爸打儿子!");
}
}
public class Son extends Father{
public void say() {
System.out.println("son");
}
public static void action(){
System.out.println("打打!");
}
public static void main(String[] args) {
Father f=new Son();
f.say();
f.action();
}
}
输出:son
爸爸打儿子!
原因:
当调用say方法执行的是Son的方法,也就是重写的say方法
而当调用action方法时,执行的是father的方法。
普通方法:运用的是动态单分配,是根据new的类型确定对象,从而确定调用的方法;
静态方法:运用的是静态多分派,即根据静态类型确定对象,因此不是根据new的类型确定调用的方法
四、Collection接口是List接口和Set接口的父接口,通常情况下不被直接使用
ConcurrentHashMap键不能重复,值可以重复
五、String str = ""; System.out.print(str.split(",").length);
运行结果:
str.split(",")方法是把str字符串根据分割符",“划分成一个字符串数组,如果str字符串中找不到分隔符”,",则把整个str字符串放入字符串数组的第一个元素。因此str.split(",").length=1。
六、以下代码定义了一个变量,如何输出这个变量的值?
方法一:
<% String myBean = (String)pageContext.getAttribute(“stringBean”,PageContext.PAGE_SCOPE);
%>
<%=myBean%>
方法二:
<bean:write name=“stringBean”/>
方法三:
<%=stringBean%>
七、类的加载顺序。
public class Test
{
public static Test t1 = new Test();//静态变量
//构造块
{
System.out.println("blockA");
}
//静态块
static
{
System.out.println("blockB");
}
public static void main(String[] args)
{
Test t2 = new Test();
}
}
(1) 父类静态对象和静态代码块
(2) 子类静态对象和静态代码块
(3) 父类非静态对象和非静态代码块
(4) 父类构造函数
(5) 子类 非静态对象和非静态代码块
(6) 子类构造函数
其中:类中静态块按照声明顺序执行,并且(1)和(2)不需要调用new类实例的时候就执行了(意思就是在类加载到方法区的时候执行的)