第一个题不知道,我都是在eclipse里面写的
第二个题
sf1 = ”A“ sf2 = “B” 就会产生一个在内存中对应的值,在进入aMethod的时候,append对字符串本身产生了修改,而“=”赋值其实只是个引用,在跳出这个方法后,内部变量的引用消失了。但是append修改了字符串本身,这个内存中的字符串发生了变化,成了AB,外部变量sf1对它的引用引用这个地址的值,就是AB了
第二个题
sf1 = ”A“ sf2 = “B” 就会产生一个在内存中对应的值,在进入aMethod的时候,append对字符串本身产生了修改,而“=”赋值其实只是个引用,在跳出这个方法后,内部变量的引用消失了。但是append修改了字符串本身,这个内存中的字符串发生了变化,成了AB,外部变量sf1对它的引用引用这个地址的值,就是AB了
sf = null; //清除sf对象的内存引用,而不是清除这个内存地址中的值
sf_arr[0] = null; //这里如果申明的大小不是1的话,就不会在这行被回收了第一题我也不会
sf_arr[0] = null; //这里如果申明的大小不是1的话,就不会在这行被回收了这句话将错了,我原本想说的是对象sf_arr被回收,debug后发现定义成10的大小也没被回收
第二题:要注意java在堆和栈的分配和参数传递是引用传递(当然是对复杂类型):tr2=str1是引用变换,这时候aMethod中的str2变量引用了str1,但是main方法中的str2的引用并没用变化,你把aMethod中参数名字换下可能就明白了。sf1.append(sf2); 这个改变了字符池中的值了,也就更改了栈中的内容。
第三题:垃圾回收机制,你看引用sf_arr[0] = sf; 被占用了,sf=null,不会马上回收的。(这个是我的理解,有待考究)
第四题:这个你去找找继承的相关内容,会明白的,继承的构造器怎么调用的。
C:\>java YourClassName 参数1 [参数2 参数3 ....]
参数之间用一个空格作为间隔符。
你可以把它理解成一个字符串,
java MyClass 1 2 3 4
String args[]="1 2 3 4".split(" ");
System.out.printin("myStr =" + s2 + myStr); 加号是字符串的连接符,"myStr =" + s2 + myStr 这是新的字符串,打印的是 myStr = 23 ;
main方法中的参数和普通的数组参数没什么区别;
想请问下 为什么声明的大小是1 的话才会 被回收 ,而别的就不会么, 请教下 sf=null; 和sf_attr[0]=null; 有什么区别
第二题:Java中,所有的参数都是传值的,方法中参数变量的值是调用者指定值的拷贝。对于两个相同类型的引用型变量,如果具有相同的引用,就会用同样的实体,因此,改变参数变量所引用的实体,就会导致原变量的实体发生同样的改变,但是,改变参数中存放的“引用”不会影响向其传值的变量中存放的“引用”。
第三题:只要Object还能被访问,就不会成为garbage collection的对象。
第四题:不懂,Mark,等大神解答
class Super{
int i=10;
Super(){
System.out.println("Super中的Super()方法");
print();
i = 20;
System.out.println("super.i = " + i);
} void print(){
System.out.println("Super中的print()方法");
System.out.println("i = " + i);
}
} class MyClass extends Super{
int i = 55;
int j = 30;
MyClass(){
System.out.println("MyClass中的MyClass()方法");
print();
j = 40;
}
void print(){
System.out.println("MyClass中的print()方法");
System.out.println(j);
}
public static void main(String[] args){
System.out.print(new MyClass().j);
}
}
加了一些输出语句进行控制,看看流程。结果为:
Super中的Super()方法
MyClass中的print()方法
0
super.i = 20
MyClass中的MyClass()方法
MyClass中的print()方法
30
40分析:子类先调用父类的构造方法,输出Super中的Super()方法是没有问题的。当调用Super()方法中的print()方法时,调用的是子类的print()方法(个人以为是只要子类覆盖了父类的方法或者变量,调用的方法或者变量是子类的,但是通过i这个变量的测试,在子类中覆盖了父类的变量i,父类还是输出super.i = 20,说明了以上想法的错误),当调用子类MyClass中的print()方法时,输出j=0;为什么等于0而不是等于初始化的30,个人理解是MyClass类的这个初始化还未开始,所以j就等于0了。所以先输出0.当把父类Super()方法调用完后,就调用子类的MyClass()方法,接着再输出30,再在主函数中输出40,所以结果为03040.总结:先调用父类构造函数,父类的构造函数中调用的方法被子类重写,就运行子类的这个方法,当运行子类的方法时,子类的变量还未被初始化,运行完父类的构造方法,再运行子类的构造方法。
《Effective Java》第79页,为了允许继承,类还必须遵循一些约束。构造器绝不能调用可被覆盖的方法,无论是直接调用还是间接调用。超类构造器在子类构造器之前运行,所以,子类中覆盖的方法将会在子类的构造器之前就被调用,所以答案第一个数字为0。
String s2 = args[1];
String myStr = args[2];
System.out.println("myStr =" + s2 + myStr);
命令行传入1 2 3 4,放在了args[]中,所以s2是2,myStr是3