Java引用传递

首先明确

(1)堆内存:堆内存可以理解为一个对象的具体信息,每一个对象保存的知识属性信息,每一块堆内存开辟都需要new关键字来完成。

(2)栈内存:可以理解为一个整型变量(只能够保存一个数值),其中保存的是一块(只能保存一块)堆内存空间的内存地址数值,为了方便理解,现在可以假设其保存的是对象的名字。


个人理解,多个栈内存的对象的可以同时指向同一个堆内存中的一部分信息(即多对一),但通过其中一个栈内存的对象修改了堆内存的信息,其他栈内存的对象引用这部分信息时也发生变化了。

1.对象的实例化内存分配操作

class Book                     //定义类Book                 
{
    String title;
    double price;
    public void printInfo()
    {
        System.out.println("title:" + this.title);
        System.out.println("price:" + this.price);
    }
}
public class TestInstant
{
    public static void main(String args[])
    {
        Book book = null; // 声明对象
        book = new Book() ; // 实例化一个对象
        book.title = "Java程序设计"; // 设置了类中的title属性
        book.price = 39.8; // 设置price属性
        book.printInfo(); // 此处的方法使用对象调用,不是直接调用
    }
}
此时栈内存中有一个book,通过new将book实例化,然后堆内存中就有book的属性(title和price),然后book就指向了这块堆内存。

2.在函数中传递基本数据类型

public class TestValue 
{
    public static void change(int i, int j) //交换参数的值
    {
        int temp = i;                      //完成两个变量值的交换
        i = j;
        j = temp;
    }

    public static void main(String[] args) 
    {
        int a = 3;
        int b = 4;
        change(a, b);                       //调用方法
        System.out.println("a=" + a);
        System.out.println("b=" + b);
    }
}

输出:

a=3

b=4

引用数据类型的传递并没有改变数据本身的值。因为参数中传递的是基本类型a和b的备份,在函数中交换的也是那份备份的值而不是数据本身。

3.传递引用数据类型

public class TestValue01 
{
    public static void change(int[] count)
    {
        count[0]=0;
        System.out.println("在方法内部count[0]="+count[0]);
    }
    public static void main(String[] args) 
    {
        int[] count={1,2,3,4,5};
        System.out.println("方法执行前count[0]="+count[0]);
        change(count);
        System.out.println("方法执行后count[0]="+count[0]);

    }

}

输出:

方法执行前count[0]=1

在方法内部count[0]=0

方法执行后count[0]=0

在方法中传递引用数据类型int数组,实际上传递的是其引用count的备份,它们都指向数组对象,在方法中可以改变数组对象的内容。即:对复制的引用所调用的方法更改的是同一个对象。

4.对象的传递引用

class Person
{
    String name;
    int age;
}
public class TestRefDemo
{
    public static void main(String args[])
    {
        Person p1 = null;//声明对象p1,此对象值为null,尚未实例化
        Person p2 = null;//声明对象p2,尚未实例化
        p1 = new Person();//实例化对象p1
        p1.age = 20;
        p1.name = "Kimi";
        p2 = p1;//将p1的引用赋给p2
        System.out.println("姓名:"+ p2.name);
        System.out.println("年龄:"+ p2.age);
        p1 = null;
    }
}

输出:

姓名:Kimi

年龄:20

p2=p1;这句话将p1指向的堆内存空间,也让p2指向了同样的堆内存空间。即不同的栈内存知指向了同一块堆内存。

5.引用传递的使用

class Book                     //定义类Book                 
{
    String title;
    double price;
    public void printInfo()
    {
        System.out.println("title:" + this.title);
        System.out.println("price:" + this.price);
    }
}
public class TestRefDemo02
{
    public static void main(String args[]) 
   {
        Book bookA = new Book() ;// 实例化一个对象
        Book bookB = new Book() ;
        bookA.title = "Java程序设计" ;// 设置了类中的title属性
        bookA.price = 40 ;// 设置price属性
        System.out.println("引用传递前对象bookA:");
        bookA.printInfo() ;// 对象bookA调用方法printInfo
        bookB.title = "Java WEB开发" ;
        bookB.price = 60 ;
        bookB = bookA ;// 引用传递
        bookB.title = "Android开发" ;
        System.out.println("引用传递后对象bookA:");
        bookA.printInfo() ;// 对象bookA调用方法printInfo
    }
}
执行bookB=bookA这个引用传递之前,bookA、bookB是两个用new关键字创建的对象,分别指向各自独立的堆内存,属性值也不同。但执行bookB=bookA这个引用传递后,bookB指向了bookA的堆内存,所以bookB对这块堆内存的属性值设置就是对bookA相应的属性值的修改。

6.再看3个例子

class Message
{
	private double salary;
	public Message(double salary)
	{
		this.salary=salary;
	}
	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	
}

public class EX17_1 {

	public static void main(String[] args) {
		Message msg=new Message(800.0);
		System.out.println(msg.getSalary());
		fun(msg);
		System.out.println(msg.getSalary());
	}
	
	public static void fun(Message temp)//相当于Message temp=msg这样一个引用传递
	{
		temp.setSalary(2000.0);
	}

}
输出:

800.0
2000.0

public class EX17_2 {

	public static void main(String[] args) {
		String str="Hello";
		fun(str);
		System.out.println(str);
	}
     public  static void fun(String tmp)       //String是基本数据类型,不会改变str的内容
     {
    	 tmp="World";
     }
}
输出:

Hello

class Msg
{
	private String str;
	public Msg(String str)
	{
		this.str=str;
	}
	public String getStr() {
		return str;
	}
	public void setStr(String str) {
		this.str = str;
	}
	
}
public class EX17_3 {

	public static void main(String[] args) {
		Msg msg=new Msg("Hello");
		System.out.println(msg.getStr());
		fun(msg);
		System.out.println(msg.getStr());
	}
	public static void fun(Msg tmp)       //相当于Msg tmp=msg;这样一个引用传递
	{
		tmp.setStr("World");
	}
}
输出:

Hello
World





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Java中,参数传递有两种方式:值传递和引用传递。值传递是指将实际参数的值复制一份给形式参数,而引用传递是指将实际参数的引用(地址)复制一份给形式参数。 Java中的基本数据类型(如int、float等)都是采用值传递的方式进行参数传递。这意味着在方法内部修改形式参数的值不会影响到实际参数的值。 而对于对象类型,Java采用的是引用传递。当将一个对象作为参数传递给方法时,实际上传递的是对象的引用(地址),而不是对象本身。这意味着在方法内部修改对象的属性值会影响到实际对象的属性值。 需要注意的是,虽然对象的引用被传递给了方法,但是如果在方法内部将引用指向了一个新的对象,那么这个改变不会影响到原始对象。 下面是一个示例代码来说明Java中的引用传递: ```java public class Main { public static void main(String[] args) { Person person = new Person("Alice"); System.out.println("Before changeName method: " + person.getName()); changeName(person); System.out.println("After changeName method: " + person.getName()); } public static void changeName(Person p) { p.setName("Bob"); } } class Person { private String name; public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ``` 输出结果为: ``` Before changeName method: Alice After changeName method: Bob ``` 在上述代码中,通过引用传递将`person`对象传递给`changeName`方法,方法内部修改了对象的属性值,导致在方法外部也能看到修改后的结果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水之积也不厚,则其负大舟也无力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值