public static void change(Boolean b) { b= new Boolean(true); }
public static void change(String s) { s= "true"; }楼主你看看我改过的代码,跟这个效果是一样的
用了这么久一直以为都是引用传递啊,譬如说 public class Person{ public int i = 0; public int j = 1; }void test(Person person) { person.i = 22; person.j = 33; }public static void main(String args[]) { Person p = new Person(); test(p); System.out.println(p.i); System.out.println(p.j); }输出结果应该是: 22 33这个作何解呢?void set(int value) { value = 4; } 这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。 到底如何界定哪些情况下是值传递还是引用传递呢?
用了这么久一直以为都是引用传递啊,譬如说 public class Person{ public int i = 0; public int j = 1; }void test(Person person) { person.i = 22; person.j = 33; }public static void main(String args[]) { Person p = new Person(); test(p); System.out.println(p.i); System.out.println(p.j); }输出结果应该是: 22 33这个作何解呢?void set(int value) { value = 4; } 这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。 到底如何界定哪些情况下是值传递还是引用传递呢?你这代码编译都过不了。 修正下,输出是22, 33对的啊。p是引用传递
用了这么久一直以为都是引用传递啊,譬如说 public class Person{ public int i = 0; public int j = 1; }void test(Person person) { person.i = 22; person.j = 33; }public static void main(String args[]) { Person p = new Person(); test(p); System.out.println(p.i); System.out.println(p.j); }输出结果应该是: 22 33这个作何解呢?void set(int value) { value = 4; } 这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。 到底如何界定哪些情况下是值传递还是引用传递呢?你这代码编译都过不了。 修正下,输出是22, 33对的啊。p是引用传递 恩,我临时手打的。。有说 java 里面全部都是值传递
用了这么久一直以为都是引用传递啊,譬如说 public class Person{ public int i = 0; public int j = 1; }void test(Person person) { person.i = 22; person.j = 33; }public static void main(String args[]) { Person p = new Person(); test(p); System.out.println(p.i); System.out.println(p.j); }输出结果应该是: 22 33这个作何解呢?void set(int value) { value = 4; } 这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。 到底如何界定哪些情况下是值传递还是引用传递呢?你这代码编译都过不了。 修正下,输出是22, 33对的啊。p是引用传递 不知道下面这个例子能不能说明问题 package org.bruce.foundation.test;/** * @author yang3wei * */ public class Person {
// Members private String name; private int age; private int grade;
// Constructors public Person() {
} public Person(String name, int age, int grade) { this.name = name; this.age = age; this.grade = grade; }
@Override public String toString() { StringBuffer sb = new StringBuffer(); sb.append("name = ").append(this.name); sb.append(", age = ").append(this.age); sb.append(", grade = ").append(this.grade); return sb.toString(); }
// getters & setters public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getGrade() { return grade; } public void setGrade(int grade) { this.grade = grade; } }package org.bruce.foundation.test;public class TestAgain {
public static void changePerson(Person p) { p = new Person("excellent", 18, 1); }
public static void changeInteger(Integer i) { i = 888; }
public static void main(String[] args) { // TODO Auto-generated method stub Person p = new Person("normal", 25, 3); System.out.println("原始:" + p);
假设调用如下:Boolean value = new Boolean(false); change(value); public static void change(Boolean bValue) { bValue = new Boolean(true); } 在调用这个方法的时候,会把你传的参数(value)指向的引用地址复制一份赋给方法参数(bValue),也就是这时调用方法时传递的参数(value)和定义方法时的参数(bValue)指向了同一个对象的引用地址,当执行bValue = new Boolean(true);时,会把新创建的对象也就是new Boolean(true)的地址赋给bValue,此时bValue已经不再指向value指向的对象了,而方法执行完毕,bValue作为方法的局部变量,会被销毁(这个change方法实际上是没有任何意义的)。所以value还是指向new Boolean(false)这个对象,所以打印出来还是false。
用了这么久一直以为都是引用传递啊,譬如说 public class Person{ public int i = 0; public int j = 1; }void test(Person person) { person.i = 22; person.j = 33; }public static void main(String args[]) { Person p = new Person(); test(p); System.out.println(p.i); System.out.println(p.j); }输出结果应该是: 22 33这个作何解呢?void set(int value) { value = 4; } 这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。 到底如何界定哪些情况下是值传递还是引用传递呢?楼主 Java中传递的都是值,不过有些是内容值,有些是地址值 你可以这样来考虑你的这个问题: p里存的是个指向person的地址,调用方法test,复制一份地址,两份地址都指向person对象,所以test方法中改变了person对象,那么原来的p那里的地址指向的person对象也就改变了。至于你一楼的问题,也是同样的道理: bValue里存放指向一个"false"的对象的地址,然后调用方法change,复制一份和bValue一样的地址给形参bValue(注意这两个bValue不一样,一个形参一个实参),然后形参指向了一个“true”的对象,但是和外面的实参没有任何关系。以上是个人的想法,到底Java的发明者怎么考虑的,权威书籍是怎么写的,我不知道,我只是觉得这样考虑好像能够说明运行的结果
基本上明了了,形参实际上会拷贝 value 中的值(这个值为堆对象 new String("false") 的地址), 然后,在 changeStr() 方法中,bValue 在接受赋值操作之后,又指向了一个新对象(new String("true"))的地址 所以对 value 中的值没有任何影响
楼上回答的很好了,我就补充一点: 楼主的例子中,确实是引用传递,但问题的关键不在于此,就拿String类来说String s = new String("a");//创建s对象,并赋值为"a",但s的值就无法再改变了!!所以String类中没有类似setValue()的方法 s = "b";//执行这一句,实际上并没有改变s对象中的值,而是把"b"的引用赋值给了s,也就是说已经没有引用指向以前的"a"了所以问题的关键在于String,Integer,Boolean等等这些对象的内容都是只读的。
这里是 Integer 和 Boolean 啊,不是 int , bool ,求解释包装类的拆装包概念。
用了这么久一直以为都是引用传递啊,譬如说 public class Person{ public int i = 0; public int j = 1; }void test(Person person) { person.i = 22; person.j = 33; }public static void main(String args[]) { Person p = new Person(); test(p); System.out.println(p.i); System.out.println(p.j); }输出结果应该是: 22 33这个作何解呢?void set(int value) { value = 4; } 这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。 到底如何界定哪些情况下是值传递还是引用传递呢? 你那个p.i=X;这个叫引用的调用,我记得在网上看到一篇文章是这样说的“java的按值传递是指:值传递是传递值的备份,按引用传递是传递引用的地址。换句话说,java中基本类型都是值传递,引用类型传递的是引用的地址(final修饰的除外)”
false
false
3
false
3 public static void change(Integer i) {
++ i;
}
public static void change(Boolean b) {
b= new Boolean(true);
}
public static void change(String s) {
s= "true";
}楼主你看看我改过的代码,跟这个效果是一样的
public class Person{
public int i = 0;
public int j = 1;
}void test(Person person) {
person.i = 22;
person.j = 33;
}public static void main(String args[]) {
Person p = new Person();
test(p);
System.out.println(p.i);
System.out.println(p.j);
}输出结果应该是:
22
33这个作何解呢?void set(int value) {
value = 4;
}
这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。
到底如何界定哪些情况下是值传递还是引用传递呢?
false
3基础知识,传值调用,老生常谈的话题了。
public class Person{
public int i = 0;
public int j = 1;
}void test(Person person) {
person.i = 22;
person.j = 33;
}public static void main(String args[]) {
Person p = new Person();
test(p);
System.out.println(p.i);
System.out.println(p.j);
}输出结果应该是:
22
33这个作何解呢?void set(int value) {
value = 4;
}
这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。
到底如何界定哪些情况下是值传递还是引用传递呢?你这代码编译都过不了。
修正下,输出是22, 33对的啊。p是引用传递
public class Person{
public int i = 0;
public int j = 1;
}void test(Person person) {
person.i = 22;
person.j = 33;
}public static void main(String args[]) {
Person p = new Person();
test(p);
System.out.println(p.i);
System.out.println(p.j);
}输出结果应该是:
22
33这个作何解呢?void set(int value) {
value = 4;
}
这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。
到底如何界定哪些情况下是值传递还是引用传递呢?你这代码编译都过不了。
修正下,输出是22, 33对的啊。p是引用传递
恩,我临时手打的。。有说 java 里面全部都是值传递
public class Person{
public int i = 0;
public int j = 1;
}void test(Person person) {
person.i = 22;
person.j = 33;
}public static void main(String args[]) {
Person p = new Person();
test(p);
System.out.println(p.i);
System.out.println(p.j);
}输出结果应该是:
22
33这个作何解呢?void set(int value) {
value = 4;
}
这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。
到底如何界定哪些情况下是值传递还是引用传递呢?你这代码编译都过不了。
修正下,输出是22, 33对的啊。p是引用传递
不知道下面这个例子能不能说明问题
package org.bruce.foundation.test;/**
* @author yang3wei
*
*/
public class Person {
// Members
private String name;
private int age;
private int grade;
// Constructors
public Person() {
}
public Person(String name, int age, int grade) {
this.name = name;
this.age = age;
this.grade = grade;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("name = ").append(this.name);
sb.append(", age = ").append(this.age);
sb.append(", grade = ").append(this.grade);
return sb.toString();
}
// getters & setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
}package org.bruce.foundation.test;public class TestAgain {
public static void changePerson(Person p) {
p = new Person("excellent", 18, 1);
}
public static void changeInteger(Integer i) {
i = 888;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Person p = new Person("normal", 25, 3);
System.out.println("原始:" + p);
changePerson(p);
System.out.println("加工后:" + p);
System.out.println("----------------- 分割线 ----------------");
Integer i = new Integer(250);
System.out.println("原始:" + i);
changeInteger(i);
System.out.println("加工后:" + p);
}}
public class Person{
public int i = 0;
public int j = 1;
}void test(Person person) {
person.i = 22;
person.j = 33;
}public static void main(String args[]) {
Person p = new Person();
test(p);
System.out.println(p.i);
System.out.println(p.j);
}输出结果应该是:
22
33这个作何解呢?void set(int value) {
value = 4;
}
这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。
到底如何界定哪些情况下是值传递还是引用传递呢?你这代码编译都过不了。
修正下,输出是22, 33对的啊。p是引用传递
恩,我临时手打的。。有说 java 里面全部都是值传递
第二段代码敲错了,更正:
package org.bruce.foundation.test;public class TestAgain {
public static void changePerson(Person p) {
p = new Person("excellent", 18, 1);
}
public static void changeInteger(Integer i) {
i = 888;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Person p = new Person("normal", 25, 3);
System.out.println("原始:" + p);
changePerson(p);
System.out.println("加工后:" + p);
System.out.println("----------------- 分割线 ----------------");
Integer i = new Integer(250);
System.out.println("原始:" + i);
changeInteger(i);
System.out.println("加工后:" + i);
}}输出结果为:
原始:name = normal, age = 25, grade = 3
加工后:name = normal, age = 25, grade = 3
----------------- 分割线 ----------------
原始:250
加工后:250
1、当执行第七行String str = new String("false");
的时候,内存是这样的:
2、当调用第28行的 change(String str)函数时:
public static void change(String str) {
str = "true";
}
内存如下所示,栈内存的特点是“由高向低扩展,且连续,复杂度为O(1),速度仅次于寄存器”,而堆内存的特点是“由低向高扩展,总是寻找静态链表中的闲置区域,复杂度为O(N),所以比栈内存慢,且不一定连续”:3、当change(String str)函数执行完毕,函数执行到14行的时候:
System.out.println(str);
change(String str)中的str将被立即回收,new String("true")已经没有引用指向它,gc线程的“引用计数收集器”会找机会回收它,但不一定立即回收,因为main线程可能正在run.可以用同样的思路去理解Boolean、Integer、Person,在研究面向过程、面向对象的同时,不要忘了去“面向内存”,甚至可以像@zhao4zhong1一样,去“面向汇编”、“面向二进制”。
这就同时解释了一个常见的面试题“String、StringBuffer的异同”,StringBuffer的实现类似于ArrayList,是一个可扩充的char[],在进行扩充的时候,执行了“申请新数组、释放旧数组”两个操作;而String在静态区所占的内存在整个程序中都不会被释放,所以频繁调用"+"运算符,造成效率低下。
change(value);
public static void change(Boolean bValue) {
bValue = new Boolean(true);
}
在调用这个方法的时候,会把你传的参数(value)指向的引用地址复制一份赋给方法参数(bValue),也就是这时调用方法时传递的参数(value)和定义方法时的参数(bValue)指向了同一个对象的引用地址,当执行bValue = new Boolean(true);时,会把新创建的对象也就是new Boolean(true)的地址赋给bValue,此时bValue已经不再指向value指向的对象了,而方法执行完毕,bValue作为方法的局部变量,会被销毁(这个change方法实际上是没有任何意义的)。所以value还是指向new Boolean(false)这个对象,所以打印出来还是false。
public class Person{
public int i = 0;
public int j = 1;
}void test(Person person) {
person.i = 22;
person.j = 33;
}public static void main(String args[]) {
Person p = new Person();
test(p);
System.out.println(p.i);
System.out.println(p.j);
}输出结果应该是:
22
33这个作何解呢?void set(int value) {
value = 4;
}
这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。
到底如何界定哪些情况下是值传递还是引用传递呢?楼主 Java中传递的都是值,不过有些是内容值,有些是地址值 你可以这样来考虑你的这个问题:
p里存的是个指向person的地址,调用方法test,复制一份地址,两份地址都指向person对象,所以test方法中改变了person对象,那么原来的p那里的地址指向的person对象也就改变了。至于你一楼的问题,也是同样的道理:
bValue里存放指向一个"false"的对象的地址,然后调用方法change,复制一份和bValue一样的地址给形参bValue(注意这两个bValue不一样,一个形参一个实参),然后形参指向了一个“true”的对象,但是和外面的实参没有任何关系。以上是个人的想法,到底Java的发明者怎么考虑的,权威书籍是怎么写的,我不知道,我只是觉得这样考虑好像能够说明运行的结果
str.append("true");
}
然后,在 changeStr() 方法中,bValue 在接受赋值操作之后,又指向了一个新对象(new String("true"))的地址
所以对 value 中的值没有任何影响
楼主的例子中,确实是引用传递,但问题的关键不在于此,就拿String类来说String s = new String("a");//创建s对象,并赋值为"a",但s的值就无法再改变了!!所以String类中没有类似setValue()的方法
s = "b";//执行这一句,实际上并没有改变s对象中的值,而是把"b"的引用赋值给了s,也就是说已经没有引用指向以前的"a"了所以问题的关键在于String,Integer,Boolean等等这些对象的内容都是只读的。
我的意思是,要区分final类和非final类,区分String和StringBuffer(StringBuilder)
public class Person{
public int i = 0;
public int j = 1;
}void test(Person person) {
person.i = 22;
person.j = 33;
}public static void main(String args[]) {
Person p = new Person();
test(p);
System.out.println(p.i);
System.out.println(p.j);
}输出结果应该是:
22
33这个作何解呢?void set(int value) {
value = 4;
}
这个的话肯定不会改变实参的值,但是对于上面那种对象类型的参数则会改变。
到底如何界定哪些情况下是值传递还是引用传递呢?
你那个p.i=X;这个叫引用的调用,我记得在网上看到一篇文章是这样说的“java的按值传递是指:值传递是传递值的备份,按引用传递是传递引用的地址。换句话说,java中基本类型都是值传递,引用类型传递的是引用的地址(final修饰的除外)”