1、 java内存分配:
a) 栈:速度快,java需要知道存储在其中所有项的生命周期,一般用于存放对象引用。
b) 堆:速度次于栈,java系统不需要知道其生命周期,用于存放java对象
c) 常量池:存放常量;
2、 java方法参数
参数传递给方法分为两种情况:一种是值调用,一种是引用调用。在java中都是采用的值调用,也就是方法得到的参数都是一个值得拷贝。
在java中数据类型有:
A) 基本数据类型:int、short、long、char、double、float、byte、boolean
B) 引用数据类型:对象的引用;
1) 基本数据类型的参数情况:
对于基本数据类型,java是直接存放在常量池的。
public voidadd(int x){
x = x + 10;
}
int a = 10;
System.out.println(add(a));
有过一定编程经验的都知道这个输出结果是10,而不是20。但是为什么?
这里将a传递方法add,add方法中x获得的是一个a的拷贝,当add方法执行后,x就直接丢掉了。所以并没有对a做什么改变:
2) 引用数据类型:
对于引用数据类型情况就不一样了。看下面的例子:
public class StudentInfro {
private int score;
public StudentInfro(int score) {
super();
this.score = score;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
public static void scoreAdd(StudentInfro si){
si.setScore(si.getScore()+5);
}
StudentInfro si = new StudentInfro(80);
scoreAdd(si);
System.out.println(si.getScore());
这时打印出来的值就是85,而不是80了,下面我们看看他的原理:
这里,传给scoreAdd方法的依旧是si的一个拷贝,但是不管si还是si的拷贝,他们都是指向的同一个对象,对si拷贝指向的对象的操作也是对si指向的对象的操作。
但是如果方法是交换两个对象的值呢?比如:
StudentInfro si1 = new StudentInfro(80);
StudentInfro si2 = new StudentInfro(90);
swap(si1,si2);
你会发现swap这个方法也是没用的,为什么?因为只是两个引用的拷贝交换了。
3) 一个特例String类型。
创建String有两种方式:
A) String str1 = “str1”;这种方式是直接将str1存放在常量池的,和基本数据类型一样,就不说了。
B) String str2 = new String(“str2”);
主要说下B这种情况:
public static voidstringMethod(String str){
str = str + " add!";
}
String str2 = new String("str2");
stringMethod(str2);
System.out.println(str2);
这个输出结果并不是“str2 add!”,而是“str2”!为什么?str2和str2的拷贝不是操作的同一个对象么?的确是同一个对象,,但是,字符串是不可变的!