变量的实质是一小块内存单元,这一小块内存里存储着变量的值
而当变量指向一个对象时,这个变量就被称为引用变量
比如 A a=new A();
a 就是引用变量,它指向了一个A对象,也可以说它引用了一个A对象
我们通过操纵这个a来操作A对象。此时,变量a的值为它所引用对象的地址
A a=new A();
对此语句更进一步的理解详见java中对象创建、初始化、引用
引用数据类型为java两大数据类型之一(另一个是基本数据类型)
引用数据类型包括:类,接口类型,数组类型,枚举类型,注解类型,字符串型
引用数据类型在被创建时,首先要在栈上给其引用分配一块内存,而对象的具体信息都存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。
引用中存的就是对象的地址
引用可能是局部变量,也可能是成员变量
只有一个空的引用,访问对象的实例相关的数据出现空指针异常
参数传递
1.基本类型作为参数传递
public class test00 {
public static void main(String[] args) {
int n=3;
System.out.println("Before change,n="+n);
changeData(n);
System.out.println("After changeData(n),n="+n);
}
public static void changeData(int nn){
nn=10;
}
}
运行结果:
Before change,n=3
After changeData(n),n=3
基本数据类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的
2.对象作为参数传递
public class test00 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("Hello");
System.out.println("Before change,sb="+sb);
changeData(sb);
System.out.println("After changeData(sb),sb="+sb);
}
public static void changeData(StringBuffer strBuf){
strBuf.append("World!");
}
}
运行结果:
Before change,sb=Hello
After changeData(sb),sb=HelloWorld!
public class test00 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("Hello");
System.out.println("Before change,sb="+sb);
changeData(sb);
System.out.println("After changeData(sb),sb="+sb);
}
public static void changeData(StringBuffer strBuf){
strBuf=new StringBuffer("Hi");
strBuf.append("World!");
}
}
运行结果:
Before change,sb=Hello
After changeData(sb),sb=Hello
在没有执行到changeData方法的strBuf=new StringBuffer(“Hi”)之前,对象在内存中的图和上例中的“图2”是一样的,而执行此语句之后,则:
此时,strBuf中存放的不再是指向"Hello"的地址,而是指向"Hi"的地址。
new操作符操作成功后总会在内存(堆内存)中新开辟一块存储区域
执行完:strBuf.append(“World!”)
String类是一个特殊的类,对它的一些操作符是重载的,如:
String str="Hello";//等价于String str=new String("Hello");
str=str+"World!";//等价于str=new String((new StringBuffer(str)).append("World!"));
String对象和基本类型一样,一般情况下作为参数传递,在方法内改变了值,而原对象是不会被改变的。
在Java中对象作为参数传递时,是把对象在内存中的地址拷贝了一份传给了参数。
public class test00 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("Hello");
System.out.println("Before change,sb="+sb);
changeData(sb);
System.out.println("After changeData(sb),sb="+sb);
}
public static void changeData(StringBuffer strBuf){
StringBuffer sb2=new StringBuffer("Hi");
strBuf=sb2;
sb2.append("World!");
}
}
运行结果:
Before change,sb=Hello
After changeData(sb),sb=Hello
执行完strBuf=sb2;后
new操作原理,比如:
StringBuffer sb2=new StringBuffer("Hi");
1.首先在堆内存中开辟一块存储区域存放"Hi"
2.把内存地址复制给对象sb2