java 函数形参传值和传引用的区别

java方法中传值和传引用的问题是个基本问题,但是也有很多人一时弄不清。


  (一)基本数据类型:传值,方法不会改变实参的值。

  public class TestFun {
  public static void testInt(int i){
  i=5;
  }
  public static void main(String[] args) {
  int a=0 ;
  TestFun.testInt(a);
  System.out.println("a="+a);
  }
  }

  程序执行结果:a=0 。


  (二)对象类型参数:传引用,方法体内改变形参引用,不会改变实参的引用,但有可能改变实参对象的属性值。

  举两个例子:

  (1)方法体内改变形参引用,但不会改变实参引用 ,实参值不变。

  public class TestFun2 {
  public static void testStr(String str){
  str="hello";//型参指向字符串 “hello”
  }
  public static void main(String[] args) {
  String s="1" ;
  TestFun2.testStr(s);
  System.out.println("s="+s); //实参s引用没变,值也不变
  }
  }

  执行结果打印:s=1


  (2)方法体内,通过引用改变了实际参数对象的内容,注意是“内容”,引用还是不变的。

        import java.util.HashMap;
        import java.util.Iterator;
        import java.util.Map;
        import java.util.Set;

        public class Test {
public void a(Map a,String b)
{
a.put("test", b);
}

public void b()
{
Map a = new HashMap();
a.put("test", "a");
String b = "b";
//printMap(a);
a(a,b);
printMap(a);
}

public void printMap(Map a)
{
Set set = a.entrySet();
Iterator it = set.iterator();
while(it.hasNext())
{
Map.Entry e = (Map.Entry)it.next();
System.out.println("Key:"+e.getKey()+" Value:"+e.getValue());

}
}

public static void main(String avgs[])
{
Test t = new Test();
t.b();
}
}


  执行结果,打印:Key:test Value:b 。可见在方法a()内改变了实参的内容。


  (3)第二个例子是拿map举例的,还有经常涉及的是 StringBuffer :

  public class TestFun4 {
  public static void testStringBuffer(StringBuffer sb){
  sb.append("java");//改变了实参的内容
  }
  public static void main(String[] args) {
  StringBuffer sb= new StringBuffer("my ");
  new TestFun4().testStringBuffer(sb);
  System.out.println("sb="+sb.toString());//内容变化了
  }
  }


  执行结果,打印:sb=my java 。

  所以比较参数是String和StringBuffer 的两个例子就会理解什么是“改变实参对象内容”了。


  总结:

  第一:java方法基本数据类型是传值,对象类型传引用,这是千真万确的。

  第二:当参数是对象时,无论方法体内进行了何种操作,都不会改变实参对象的引用。

  第三:当参数是对象时,只有在方法内部改变了对象的内容时,才会改变实参对象内容。

<think>嗯,用户想了解Java引用区别,以及是否存在引用的概念。首先,我得回忆一下Java的参数递机制。记得Java里只有,没有引用,不过对于对象类型来说,递的是引用的副本,这可能会让人误解为引用。 然后,用户提到的几个引用资料,特别是引用[3]提到,无论是基本类型还是引用类型,参数都是的。基本类型的是的拷贝,而引用类型的是引用的拷贝。所以当你在方法里修改引用类型的成员变量时,会影响原对象,但如果直接修改引用本身,比如指向另一个对象,原来的实参不会变。这点需要解释清楚。 接下来,用户可能混淆了引用的概念,比如C++中的引用。需要明确说明Java中没有引用,只有,包括对象引用也是。可能还需要举例子,比如修改对象属性会影响原对象,而重新赋引用不会改变原引用。 另外,是否存在引用的概念?其实在Java中并没有这种术语,可能用户是听到过类似的说法,需要澄清这个术语的正确性,指出正确的说法是“引用的拷贝”,即的方式引用。 还要考虑用户可能的误区,比如认为对象参数是按引用递,但实际上只是递了引用的副本。需要强调这一点,避免误解。同时,结合引用[2]的内容,说明修改形参引用不会影响实参,但修改对象的属性会影响。 最后,确保回答结构清晰,分点解释,并附上示例代码,帮助用户理解。可能还需要生成相关问题,比如参数递在内存中的表现,或者与C++的区别,但用户已经提供了相关问题,可能需要调整。</think>### Java 引用区别引用概念解析 #### 一、Java 参数递的核心机制 Java 中**所有参数递均为**(pass-by-value),不存在统意义上的“引用”(pass-by-reference)。但对于对象类型,递的是**对象引用的拷贝**,而非对象本身[^3]。这一机制可通过以下两点解析: 1. **基本数据类型(如 `int`, `double`)** 递的是的副本,方法内修改不会影响原始变量: ```java void modify(int x) { x = 10; } int a = 5; modify(a); // 调用后 a 仍为 5 ``` 2. **引用数据类型(如对象、数组)** 递的是对象引用的拷贝,方法内修改对象属性会影响原对象,但重新赋形参引用不会影响实参: ```java class Person { String name; } void changeName(Person p) { p.name = "Alice"; } // 影响原对象 void resetRef(Person p) { p = new Person(); } // 不影响实参引用 ``` #### 二、引用的概念澄清 “引用”这一术语在 Java 中并不存在,实际是对“递对象引用拷贝”的通俗表述。关键区别在于: - ****:递参数的副本(基本类型直接拷贝引用类型拷贝引用地址)。 - **引用(其他语言)**:直接操作原变量地址(Java 不支持此机制)[^2]。 #### 三、示例对比 | 操作类型 | 基本类型参数 | 对象类型参数 | |----------------------|--------------------|------------------------| | 修改参数 | 不影响原 | 不影响原引用指向 | | 修改对象属性/元素 | 不适用 | 影响原对象内容 | | 重新赋参数引用 | 不适用 | 不影响原引用指向 | #### 四、内存模型视角 - **堆与栈的关系**:对象实例存储在堆(heap),引用变量存储在栈(stack)。传参时拷贝的是栈中的引用,而非堆中对象[^4]。 - **方法调用过程**:形参接收实参引用的副本,二者指向同一对象,但形参本身是独立变量。 #### 五、常见误区 - **误区 1**:“Java引用” **纠正**:仅引用的拷贝,本质仍是[^3]。 - **误区 2**:“修改形参引用会影响实参” **纠正**:形参重新赋后与原引用解耦,实参不受影响。 --- §§ 相关问题 §§ 1. Java 中 `String` 作为参数时为何表现出“不可变性”? 2. 如何通过内存模型解释方法调用时的对象递? 3. Java 与 C++ 在参数递机制上有何本质区别
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值