Java传值还是传引用

一、 概述

    在编写Java代码时候,对于一个内部或者外部函数的调用,我们总是通过入参和返回值的方式进行数据交换和流转。有时候,我们传递的入参会本身被其他方法修改,有时候我们不得不通过返回值得方式传递处理的结果。那么这里我们就学习一下,具体何时入参会被调用方法修改,何时入参不会被调用的方法所修改。

二、 结论写在前面

    为了便于阅读,把经过测试推演得到的结论写在前面,具体的推演在第三小节。
  1.     Java中的方法是传值的
  2.     对于引用型对象,传递的是引用的值
  3.     在方法中对值的修改无效,因为修改的是值得拷贝
  4.     在方法中对引用指向的对象的修改是有效的,因为该地址内存储的对象发生了变化

三、 代码推演写在后面

下面我们就通过代码,来验证一下在方法的调用中,传递的到底是值还是引用,在方法中的修改会对入参产生怎样的作用。
测试程序
   
   
 
/**
* Created by ryan01.peng on 2017/6/21.
*/
public class LeCallByValue {
 
public static void main(String[] args) {
 
ToBeCalled toBeCalled = new ToBeCalled();
 
int a = 1;
String name = "唯品会开发指南";
 
System.out.println("调用函数前:"+a);
toBeCalled.passValue(a); // 传值,在方法中对值的修改不会影响,原来的值。
System.out.println("调用函数后:"+a);
 
Book book = new Book();
book.setId(a);
book.setName(name);
System.out.println("book调用函数前:"+book);
toBeCalled.passPointer1(book); //传递的是引用的值,在方法中对值的修改是对拷贝的修改,不会影响原来的值,所以这个引用还是指向原来的对象
System.out.println("book调用函数后:"+book);
 
Book book2 = new Book();
book2.setId(a);
book2.setName(name);
System.out.println("book2调用函数前:"+book2);
toBeCalled.passPointer2(book2); 这里我们没有用返回值对book进行赋值,book同样发生了改变,是因为引用指向的对象发生修改。
System.out.println("book2调用函数后:"+book2);
 
 
 
toBeCalled.testString(name);
System.out.println("调用函数后:"+name); //传递引用的值,这里没有发生改变
 
 
System.out.println("--------------------------------一下学习== 和equals----------------------------------------------");
 
int b = 1;
int c = 1;
Integer d = 1;
Integer e = 1;
Integer f = new Integer(1);
Integer g = new Integer(1);
String s1 ="yyyy";
String s2 ="yyyy";
String s3 = new String("yyyy");
String s4 = new String("yyyy");
String s5 = new String(s1);
 
System.out.println("b==c");
System.out.println(b==c); //基础类型之间的 == 比较的是值
 
System.out.println("d == e");
System.out.println(d == e); //这里虽然是包装类型的引用,但是赋值时候指向基础类型,所以其d和e的作为引用其值是相等的
 
System.out.println("b == e");
System.out.println(b == e); // 拆箱,比较值
 
System.out.println("d.equals(e)");
System.out.println(d.equals(e)); //比较的是值 ,下同
 
System.out.println("d.equals(a)");
System.out.println(d.equals(a));
 
System.out.println("b==f");
System.out.println(b==f); // 比较值
 
System.out.println("d==f");
System.out.println(d==f); //比较值
 
System.out.println("f==g");
System.out.println(f==g); // f和g分别指向了不同对象,f和g的值不同,但其指向的两个对象equals
 
System.out.println("d.equals(f)");
System.out.println(d.equals(f));
 
System.out.println("f.equals(g)");
System.out.println(f.equals(g));
 
System.out.println("s1==s2");
System.out.println(s1==s2); // 引用S1/s2指向同一个对象。
 
System.out.println("s1==s3");
System.out.println(s1==s3); // s3是new出来的,在堆中分配内存,故指向不同
 
System.out.println("s1==s5");
System.out.println(s1==s5); // 引用类型,指向不同
 
System.out.println("s1.equals(s2)"); // 以下均为true,equals比较的是字符串的内容
System.out.println(s1.equals(s2));
 
System.out.println("s1.equals(s3)");
System.out.println(s1.equals(s3));
 
System.out.println("s3.equals(s4)");
System.out.println(s3.equals(s4));
 
System.out.println("s3.equals(s5)");
System.out.println(s3.equals(s5));
 
}
}
被调用方法封装在这个类中
   
   
/**
* Created by ryan01.peng on 2017/6/21.
*/
public class ToBeCalled {
 
public String passValue(int a){
a=a+1;
return "processed:"+a;
}
 
public String passPointer1(Book book){
Book resultBook = new Book();
 
resultBook.setId(book.getId()+1);
resultBook.setName("processed"+book.getName());
book = resultBook;
return "succsess";
}
 
public String passPointer2(Book book){
book.setId(book.getId()+1);
book.setName("processed"+book.getName());
return "succsess";
}
 
public void testString(String s){
s = "春江花月夜";
}
}

演示代码中用到的实体类
   
   
/**
* Created by ryan01.peng on 2017/6/21.
*/
public class Book {
 
private int id;
private String name;
 
public int getId() {
return id;
}
 
public void setId(int id) {
this.id = id;
}
 
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
 
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}

输出内容:
   
   
com.vip.vcp.ryan.zhaunzheng.leBasic.LeCallByValue
调用函数前:1
调用函数后:1
book调用函数前:Book{id=1, name='唯品会开发指南'}
book调用函数后:Book{id=1, name='唯品会开发指南'}
book2调用函数前:Book{id=1, name='唯品会开发指南'}
book2调用函数后:Book{id=2, name='processed唯品会开发指南'}
调用函数后:唯品会开发指南
--------------------------------一下学习== equals----------------------------------------------
b==c
true
d == e
true
b == e
true
d.equals(e)
true
d.equals(a)
true
b==f
true
d==f
false
f==g
false
d.equals(f)
true
f.equals(g)
true
s1==s2
true
s1==s3
false
s1==s5
false
s1.equals(s2)
true
s1.equals(s3)
true
s3.equals(s4)
true
s3.equals(s5)
true
 
Process finished with exit code 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值