最近在看《java编程思想》,其中有一句话:[图片说明](https://img-ask.csdn.net/upload/201507/02/1435824299_513845.png)
既然参数是引用类型,于是我就做了一些试验:
class A{
public void f(Integer i){
i = 10;
}
public void h(Data data){
data.i=2;
data.str="abc";
}
}
class Data{
int i=0;
String str = "0";
}
public class Test {
public static void main(String[] args) {
Data data = new Data();
new A().h(data);
System.out.println(data.i);
System.out.println(data.str);
Integer i = new Integer(1);
new A().f(i);
System.out.println(i);
}
}
打印结果:
2
abc
1
于是百思不得其解,Integer与自定义对象有什么不同之处,String的情况跟Integer一样,求解惑。
这是基本类型,string有点特殊,他们传递一个副本,你修改不了,如果是自定义的类实例,因为传递的是引用,所以你修改它是可以改变参数内部值得
这不是非常正常的吗?没什么不同之处,都是引用类型。
Integer.Valueof(String s)与Integer.parseInt(String s)的区别
他们有本质区别,Integer.valueof(String s)是将一个包装类是将一个实际值为数字的变量先转成string型再将它转成Integer型的包装类对象(相当于转成了int的对象)这样转完的对象就具有方法和属性了。
而Integer.parseInt(String s)只是将是数字的字符串转成数字,注意他返回的是int型变量不具备方法和属性。
java的传值还是传引用问题
Integer i = new Integer(1);
new A().f(i);
你的这句话其实是将i对象的引用传递给f方法里的参数i,而在f方法中i赋了一个整数值,此时i会自动拆箱成int,即在栈上定义一个int值为10,类似int i=10的效果。而对于传入的i引用本身没有发生任何改变,依然在堆中,所以你输出i的时候会得到1。integer是一个对象,但需要注意的是它和int会发生装箱和拆箱的操作,而普通对象是不会的。
楼下说的不错,new A().f(i)你这里之所以值没变,是因为方法中的i是引用类型,传递的只是一个地址,虽经过在方法中赋值操作,外面的i的值并没有改变。
而new A().h(data)这个有点不一样,data是和上面的i类似,但其内部的属性i不同,所以用到重新给data.i赋值时就发生改了,你可以做个实验在方法h(data)中加上这个
public void h(Data data){
data=new Data();
data.i=2;
data.str="abc";
}你这样再试试,还会不会变
上面的回答写的有点问题,把i传入到f方法里时,你又在f方法中将i=10了。这一过程相当于又new了一个 integer,在java中Integer i=10这种操作称之为自动装箱,即将整数10包装为Integer对象。由于java参数传递为值传递,你传给f的i其实是一个副本,存的是传入的i对象的地址的拷贝。当你在方法里把i的副本装箱之后,此时该副本已经指向了别的对象了,而你输出的时候的i其实没有发生改变。所以依然为1.
你理解的方向错了,String是字符窜,Integer为数字,不如String a="1";Integer b=1;a+a与a+b是不同的
String不不可变类。
这是java的源码
/**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value;
/**
* Constructs a newly allocated {@code Integer} object that
* represents the specified {@code int} value.
*
* @param value the value to be represented by the
* {@code Integer} object.
*/
public Integer(int value) {
this.value = value;
}
所以Integer 封装的整数是final型的。
在被调函数中i = 10 的自动装箱可以理解为i = new Integer(10)参数的指向已经改变了,而参数指向的封装值并没有改变