JAVA基础编程——引用传递

在C/C++中,值传递和指针传递是一组概念,两者作为参数用于不同的场合,也可能会有不同的使用效果。而与之对应的,JAVA中的对应概念就是引用传递。这里通过几个例子来说明一下应用传递在不同场景中的使用。

场景一:int

先看一段代码:

public class Demo {
	public static void main(String args[]) {
	    int num = 10;
		func(num);
		System.out.println("Num is " + num);
	}
	
	public static void func(int var) {
	    var = 100;
	}
}

结果为:

Num is 10

int类型为基本数据类型,在基本数据类型中,不存在为该变量在堆内存上开辟空间进行存储。因此main中的num和func中的var都属于栈内存,两者指向不同的位置,因此将num的值赋给var只是改变了var对应的栈内存的值,而func调用结束,var对应的内存释放,num仍然是10。

场景二:String

先看一段代码:

public class Demo {
	public static void main(String args[]) {
	    String str = "Hello";
		func(str);
		System.out.println("Str is " + str);
	}
	
	public static void func(String var) {
	    var = "world";
	}
}

结果为:

Str is Hello

JAVA中会对字符串在堆内存上开辟空间进行存储,因此Hello和world都在堆内存上有自己的空间,而str指向Hello,在func调用后,var也指向Hello,随后var的指向变为了world,但str的指向并没有发生变化,因此在func调用结束后,var释放掉,str仍然为Hello。

场景三:int属性

首先定义一个Book类:

class Book {
    private String name;
	private int price;
	
	public Book() {
	    System.out.println("This is Book's constructer.");
	}
	
	public Book(String name, int price) {
        this.name = name;
		this.price = price;
	}
	
	public void getInfo() {
	    System.out.println("Book name is " + name + ",book price is " + price);
	}
	
	public void setName(String var) {
	    name = var;
	}
	
	public String getName() {
	    return name;
	}
	
	public void setPrice(int var) {
	    price = var;
	}
	
	public int getPrice() {
	    return price;
	}
}

再看一段代码:

public class Demo {
	public static void main(String args[]) {
		Book bk = new Book("English",10);
		func(bk);
		System.out.println("Num is " + bk.getPrice());
	}
	
	public static void func(Book var) {
	    var.setPrice(20);
	}
}

结果为:

Num is 20

在上面的代码中,首先实例化了Book对象bk,bk.name指向English,bk.price指向10,然后调用func,使var和bk指向堆内存中相同的Book对象,然后通过var设置该Book对象price属性的值,因为int是基本数据类型,便直接修改了堆内存中的值,因此此时的bk.getPrice()结果为20。

场景四:String属性

先看一段代码:

public class Demo {
	public static void main(String args[]) {
		Book bk = new Book("English",10);
		func(bk);
		System.out.println("str is " + bk.getName());
	}
	
	public static void func(Book var) {
	    var.setName("Math");
	}
}

结果为:

str is Math

和上个场景是相似的,无非是在func中修改了函数体的内容。不过此时Math作为匿名对象传递,同样会存储在堆内存中,而setName方法的调用则是修改了bk中Name指向的堆内存。因此结果为Math。

上述几种场景其实也好区分:

  • 注意栈内存中变量的指向关系
  • 注意堆内存中变量的实际存储
  • 注意方法调用前后栈内存的建立和释放
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值