public class Test {
public static void changeStr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
}
Please write the output result :
(请高手帮忙写出详细解答,谢谢!)
public static void changeStr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
}
Please write the output result :
(请高手帮忙写出详细解答,谢谢!)
public static void changeStr(String str)中STR是一个局部变量,不会影响到外部变量的直
如果是这样改的话:
public class A {
public static String changeStr(String str){
return str="welcome";
}
public static void main(String[] args) {
String str="1234";
str=changeStr(str);
System.out.println(str);
}
} 结果就会是welcome了,而且好像跟static没有太大的关系,主要还是在考值传递的问题。我觉得
这种说法不成立。
public class Test {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("OLD");
changeStringBuffer(sb);
System.out.println(sb.toString());
}
public static void changeStringBuffer(StringBuffer sb) {
sb = new StringBuffer("NEW");
}
}
java 中 原始类型 如int 等都是值传递. String 是对象,是引用传递 .只不过 String 和StringBuffer的区别在于,String是可读的.
public class Test {
public static void changeStr(String str1){
str1="welcome";
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
}
上面这段代码, 注意其中的红色的两个变量. 首先说str .str变量存放的是对"1234"的字符串对象的引用地址.在调用changeStr(str) 方法的时候. 是str把引用地址传递给str1这个变量. 由于java中string 是只读的,所以无法修改"1234"这个字符串对象的值. str1="welcome"; 则是又创建了一个"welcome"的字符串对象.并修改str1的引用地址. 而str还是指向原来的"1234"的地址. 所以结果是1234. 这个面试题的重点在于 考察 string对象的只读属性. final class
public class Test {
public static void changeStr(String str1){
str1="welcome";
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
}
上面这段代码, 注意其中的红色的两个变量. 首先说str .str变量存放的是对"1234"的字符串对象的引用地址.在调用changeStr(str) 方法的时候. 是str把引用地址传递给str1这个变量. 由于java中string 是只读的,所以无法修改"1234"这个字符串对象的值. str1="welcome"; 则是又创建了一个"welcome"的字符串对象.并修改str1的引用地址. 而str还是指向原来的"1234"的地址. 所以结果是1234. 这个面试题的重点在于 考察 string对象的只读属性. final class
public static void changeStr( String str1){
str1="welcome";
}
public static void main(String[] args) {
String str = "1234";
changeStr(str);
System.out.println(str);
}
} 上面这段代码, 注意其中的红色的两个变量. 首先说str .str变量存放的是对"1234"的字符串对象的引用地址.在调用changeStr(str) 方法的时候. 是str把引用地址传递给str1这个变量. 由于java中string 是只读的,所以无法修改"1234"这个字符串对象的值. str1="welcome"; 则是又创建了一个"welcome"的字符串对象.并修改str1的引用地址. 而str还是指向原来的"1234"的地址. 所以结果是1234. 这个面试题的重点在于 考察 string对象的只读属性. final class
public static void changeStr(String str){
String str1 = new String("welcome");
str = str + str1;
System.out.println(str);
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
}的结果是
1234welcome
1234得出结论:changestr方法中str变量是这个方法的局部变量,方法运行完毕,该局部变量即被销毁,更何况该方法是void类型,没有任何返回值。这个变量和main方法中的变量str没有任何关系。public class Test {
public static String changeStr(String str){
String str1 = new String("welcome");
str = str + str1;
return str;
}
public static void main(String[] args) {
String str="1234";
str = changeStr(str);
System.out.println(str);
}
}
呵呵,大家都知道这个程序打印什么了吧?
深叹一口气……Java里函数调用时,对于对象是传递引用的值拷贝,可以说是传递引用。和C、C++里说的引用传递有区别。我举StringBuffer的例子是说,这个和String类本身没有关系。
按着我的逻辑,怎么推导出“welcome”来?
首先回到开始,5楼的说法是错的。即便参数是String,传入函数、压栈的是这一String对象的引用,仍和Primitive type不一样。
其实,这个问题和String是不可更改这一点毫无关系。上两段引自The Java Virtual Machine Specification,第一段说,当一个方法被调用时,会创建一个新的frame;第二段说的是,参数会依次压入local variable(从位置1开始),而这个临时变量表自然是属于函数的。也就是说,传入的对象的引用在函数的frame中做了一份值拷贝。这时,就是一个简单的作用域问题了。以此证实我的逻辑,没问题了吧?
strArg="welcome";
} 1. String sInstance="1234";
2. changeStr(sInstance);
当执行第2步时,方法帧中产生一个变量符号(方法原型中的atrArg),和方法外的sInstance共同指向堆上的"1234";
它们确实指向同一对象,所以说引用对象传递的是引用(相当于传递了C指针).这时如果"改变这个对象",外部的变量符号sInstance指向的对象也改变了,因为他们都是同一对象,但String本身是不能改变的.注意改变这个对象不是改变变量符号,是指改变他们指向的对象,而上面的方法中并没有修改指向的那个对象1234,而是
将一个新值赋给了方法内的变量符号,简单说只上让方法内的atrArg重新指向了一个新的对象,根本没有影响sInstance
指向1234这个事实.执行1: sInstance->"1234";
执行2: strArg->"1234",strArg->"welcome";
所以 sInstance->"1234";没有改变.
而如果在方法内修改了对象本身,比如是StringBuffer,因为sInstance和strArg都指向它,修改会在外部调用sInstance
当然就修改了.其实这和方法调用传什么没有关系.简单成这样: String s1 = "1234";
String s2 = s1;
s2 = "5678";
System.out.println(s1);s2相当于那个方法的参数.它在方法帧生成的时候先和s1一样都指向1234,但随即它就指向了"5678",这时s1根本没有任何改变.
但如果是
StringBuffer s1 = new StringBuffer("1234");
StringBuffer s2 = s1;
s2.append("1111");//这一句是对象本身在改变
System.out.println(s1);
s2当然也根着改变了.我们是通过变量符号来操作对象,因为对象在堆上你无法告诉JVM我要操作第几段第几号那个对象,所以用一个变量名操作.
s2.append("1111");不是变量符号被加长了而是它指向的对象被加长了,但s2 = xxxx是让变量符号重新指向一个其它对象了.就这点事.
public static void test(Object o){
System.out.println(o);
}
public static void main(String[] args) throws Exception{
Object o = new Object();
System.out.println(o);
test(o);
}
结果:
java.lang.Object@6b97fd
java.lang.Object@6b97fd因为方法外的变量和方法参数两个变量都指向同一地址的对象. public static void test(Object o){
System.out.println(o);
o = new Object();
System.out.println(o);
}
public static void main(String[] args) throws Exception{
Object o = new Object();
System.out.println(o);
test(o);
System.out.println(o);
}java.lang.Object@6b97fd
java.lang.Object@6b97fd
java.lang.Object@1c78e57
java.lang.Object@6b97fd第三行因为方法内的o已经指向一个新对象.
而并不方法外的o并没有改变(第四行)如果再看不懂就别学JAVA了
在java中你用C的名词来说 "传入的对象的引用的值"被复制在方法帧中.
我KAO,这话没有错,但你直接说 方法帧产生的方法参数的那个变量符号和外部的变量符号指向同一对象不就更清楚了.
严重同意30楼的说法
原因看注解:public class Test {
public static void changeStr(String str){
str="welcome"; //str是局部变量,虽然曾指向1234,但是这里改变了对象的内容,指向了welcome对象。
}
public static void main(String[] args) {
String str="1234";//指向1234的事实一直没有改变。
changeStr(str);
System.out.println(str);
}
}
Please write the output result :
改变了对象的内容是指堆中原来存放"1234"对象的那个地址中内容改变了.
事实上它并没有改变,也无法改变,str只是重新指向了另一个对象welcome.还有大家不要说传址,传引用,传值,这是不准确的,别人也不能明白.计算机这个模型它只能传值,只是那值的意义不同.
那个值是数据本身,就是我们说的传值,如果那个值表示数据所在的地址,就是我们说的传址,或者表示数据所在的地址的地址
的地址的........................................................................................
地址.但本质上它就是传一个值,所以光说传值,表达不了意义.
Java中所有的参数传递都是值传递,只不过,对于类实例而言,是引用类型的值传递。
如果使用StringBuffer.append等方法,那是另一回事,跟这个没关系。
但从语法上,在函数内部给一个形参重新赋值,有的语言中会直接引起实参变量的所代表的内存单元的变化,而有的语言中则不会引起实参变量的任何变化,于是才有了“传值”,“传引用”的区别。
Java语言中参数传递都是传值的。
public static void changeStr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
}
Java中是值传递, public static void changeStr(String str)中的str是局部变量,你只要记好只要是局部变量就分配在栈内存上,方法调用完毕它就在内存中销毁了。
这题与静态不静态到没有多大关系。此方法写成静态的是因为在mian方法里不用new Test()了!
在mian()方法里调用 changeStr(str),但是此方法在定义时是void的。根本就没有返回值。最重要的还是JAVA是值传递,在被调方法中不能改变原值。所以在mian()中还输出1234