内存的讲解
我们想学习对象的引用和传递,就得先来复习两块内存空间
栈内存:可以理解为每块栈内存都是一个整型变量,它能存放一块堆内存的物理地址数值(仅能存放一块)
堆内存:堆内存可以存放一个对象的具体信息,每一块堆内存空间的开辟都需要通过关键字new完成。
我们来举个实例,来看看内存空间的状态
代码演示:
package demo;
class Book{
private String title;
private double price;
public Book(){
}
public Book(String title,double price){
this.title = title;
this.price = price;
}
public String getTitle() {
return title;
}
public double getPrice() {
return price;
}
public void setTitle(String title) {
this.title = title;
}
public void setPrice(double price) {
this.price = price;
}
public String toString() {
return "Book [title=" + title + ", price=" + price + "]";
}
}
public class InStantDemo {
public static void main(String[] args) {
Book book; //声明一个对象
book = new Book(); //实例化一个对象
book.setTitle("java"); //对titlt属性赋值
book.setPrice(65.0); //对price属性赋值
System.out.println(book.toString());
}
}
内存空间:
代码讲解:在第二个图,我们可以看到对象调用无参构造实例化的时候,属性值都会有一个默认值。
值传递和址(地址)传递
面向对象编程中,都应该记得:面向对象编程 = 对象 + 消息的传递。所以学习面向对象编程(java)最为重要的就是学习消息的传递
在java中,三大特征之一的封装,就将很多的方法封装成了一块一块的代码块,还将一类型的事务封装成类,
而方法都是一个入口(参数的传递)一个出口(return关键字)。
学习参数前,我们先来学习参数的传递,可分为:值(基本数据类型)传递和址(引用数据类型)传递
代码演示:
package demo;
public class ParamTransmitDemo {
//定义一个方法用来交换a和b的数值
public static void change(int a,int b){
System.out.println("传入时形参a的值="+a);
System.out.println("传入时形参b的值="+b);
//定义一个第三方变量,实现a和b的数值交换
int temp = a;
a = b;
b = temp;
System.out.println("修改后形参a的值="+a);
System.out.println("修改后形参b的值="+b);
}
public static void main(String[] args) {
int a = 10;
int b = 20;
//调用方法交换a和b的数值
change(a, b);
System.out.println("实参a的值="+a);
System.out.println("实参b的值="+b);
}
}
代码结果:
代码讲解:能够发现,并没有实现,参数传入方法后,就称为形参,我们能够看到在方法体内,确实实现了a和b的值的交换,但是实参a和b并没有交换,我来给大家先来解释一下实参和形参。
实参:实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值。
形参:形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量。形参类似于实参的副本,我们调用函数修改的只是实参的副本,并不会对实参有任何改变。
需要注意:
1.实参和形参在数量上,类型上、顺序上应严格一致,否则就会发生类型不匹配的错误。
2.实参--->形参:在参数的传递上,如果参数类型是基本数据类型,参数传的就是实参的数值,分配的形参存放的是实参的副本,修改后不会改变实参。
3.实参--->“实参”:在参数的传递上,如果参数类型是引用数据类型,此时参数的传递一定是地址值,即实参和形参指向的是同一块地址空间,当形参修改,实参也会跟着改变。
我们还是使用上述例子,使用包装类,修改代码,完成实参--->“实参”
代码演示:
package demo;
public class ParamTransmitDemo {
public static void change(int[] num){
int temp = num[0];
num[0] = num[1];
num[1] = temp;
}
public static void main(String[] args) {
int[] num = new int[2];
num[0] = 10;
num[1] = 20;
change(num);
System.out.println(num[0]); //20
System.out.println(num[1]); //10
}
}
代码讲解:上述代码就用了引用数据类型——数组传递,演示了实参--->“实参”。
bigdodo给大家出个题
下面代码使用了引用类型变量实现址传递
代码演示:
package demo;
public class ParamTransmitDemo {
public static void change(Integer m,Integer n){
Integer c = null;
c = m;
m = n;
n = c;
}
public static void main(String[] args) {
//使用包装类,定义两个引用类型对象并赋值
Integer x = new Integer(10);
Integer y = new Integer(20);
change(x, y);
System.out.println(x); //10
System.out.println(y); //20
}
}
提问:数据为什么没有交换?欢迎评论留言回答,实现想不出,也可以留言提问bigdodo!