【java】论integer是地址传递还是值传递

本文通过实例探讨了Java中Integer作为参数传递的方式。首先通过synchronized关键字锁定Integer对象并调用wait方法来证明Integer是地址传递;其次,通过Integer不可变性的特点解释了为何在方法中修改Integer值不会影响到原始变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://www.tuicool.com/articles/AraaQbZ

论integer是地址传递还是值传递

Integer 作为传参的时候是地址传递 , 可以参考如下例子,在程序刚启动的时候把 Integer 的index 对象锁住 ,并且调用了 wait方法,释放了锁的资源,等待notify,最后过了5秒钟,等待testObject 调用notify 方法就继续执行了。大家都知道锁的对象和释放的对象必须是同一个,否则会抛出  java.lang.IllegalMonitorStateException 。由此可以证明 Integer作为参数传递的时候是地址传递,而非值传递。

public class IntegerSyn {
  
  public static void main(String[] args) throws InterruptedException {
    Integer index = 0;
    TestObject a = new TestObject(index);
    synchronized (index) {
      new Thread(a).start();
      index.wait();
    }
    System.out.println("end");
  }
}

class TestObject implements Runnable {
  private Integer index;
  
  public TestObject(Integer index){
    this.index = index;
  }
  
  public void run() {
    try {
      TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    synchronized (index) {
      index.notify();
    }
  }
}

那就会有人问了,为什么执行如下代码的时候两次的输出结果是一样的?

public static void main(String[] args) throws InterruptedException {
    Integer index = 0;
    System.out.println(index);
    test(index);
    System.out.println(index);
  }
  
  public static void  test(Integer index){
    index++;
  }

理由很简单,可以看到 Integer 类中final的value字段,说明一旦integer类创建之后他的值就不能被修改,在 index++ 的时候Integer是创建一个新的类,所以这个第二次输出的时候结果是一样的!

private final int value;

<think>嗯,用户问Java中的Integer值传递还是引用传递。这个问题看起来简单,但其实需要仔细分析Java的参数传递机制以及基本类型和对象的不同处理方式。 首先,我得回忆一下Java的参数传递规则。记得Java总是按值传递的,不管是基本类型还是对象引用。对于基本类型,比如int,传递的是实际值的副本。而对于对象,比如Integer这样的包装类,传递的是引用的副本,而不是引用本身。所以这里可能会有混淆的地方,因为虽然传递的是引用的副本,但有些人可能会误以为是引用传递。 接下来,我需要明确值传递和引用传递的区别。值传递意味着传递的是变量值的拷贝,对拷贝的修改不会影响原变量。引用传递则是直接传递变量本身的内存地址,函数内的修改会影响原变量。在Java中,即使传递的是对象引用,它仍然是按值传递,因为传递的是引用的拷贝,而不是原始的引用变量。 然后,考虑Integer的情况。Integer是包装类型,属于对象。当作为参数传递时,传递的是引用的拷贝。但Integer是不可变的,所以任何修改都会生成新的对象,而原引用不会改变。这时候可能需要通过例子来说明,比如在方法内部改变Integer的值,但外部变量不受影响。 另外,用户可能存在的误区是认为对象是按引用传递的,但实际上Java的机制是按值传递引用的副本。这时候需要举具体的例子来澄清,比如创建一个方法,尝试修改Integer参数的值,并展示外部变量的不变性。 最后,总结时应该强调Java中参数传递的规则,以及Integer作为不可变对象的特点,如何影响实际的值传递效果。同时,可能需要对比String等其他不可变对象的情况,进一步巩固理解。</think>在Java中,所有参数的传递方式均为**值传递**(Pass by Value),包括`Integer`类型。以下分步说明原因和现象: --- ### 一、基本概念 1. **值传递(Pass by Value)** - 方法调用时,传递的是变量的**拷贝值**。 - 对拷贝值的修改**不会影响**原始变量。 2. **引用传递(Pass by Reference)** - 方法调用时,传递的是变量的**内存地址**。 - 对参数的修改**直接影响**原始变量。 - **Java不支持引用传递**。 --- ### 二、`Integer`的特殊性 `Integer`是包装类(对象类型),但因其不可变性(Immutable),行为可能引起误解: 1. **传递的是引用的拷贝** ```java void modify(Integer num) { num = 100; // 修改的是拷贝的引用,原始引用不变 } public static void main(String[] args) { Integer a = 10; modify(a); System.out.println(a); // 输出10(未改变) } ``` 2. **不可变性的影响** `Integer`对象一旦创建,值不可修改。 任何赋值操作(如`num = 100`)会生成新对象,与原对象无关。 --- ### 三、对比示例 #### 1. 基本类型(值传递) ```java void changeInt(int x) { x = 20; // 修改拷贝值 } public static void main(String[] args) { int a = 10; changeInt(a); System.out.println(a); // 输出10(原值未变) } ``` #### 2. 对象类型(值传递引用的拷贝) ```java class Holder { int value; Holder(int v) { this.value = v; } } void changeHolder(Holder h) { h.value = 20; // 修改引用指向的对象内容 h = new Holder(30); // 修改拷贝的引用(不影响原始引用) } public static void main(String[] args) { Holder h = new Holder(10); changeHolder(h); System.out.println(h.value); // 输出20(对象内容被修改) } ``` --- ### 四、总结 - **Java只有值传递**:无论是基本类型还是对象类型,传递的均是值的拷贝。 - **对象类型的“值”是引用**:传递对象时,拷贝的是引用(内存地址),而非对象本身。 - **`Integer`的特殊性**:由于其不可变性,无法通过赋值修改原对象的值,但可以通过反射等特殊手段破坏不可变性(不推荐)。 --- ### 五、常见误区 - **误区**:“对象是引用传递。” **正解**:对象传递的是引用的拷贝(即值传递),而非原始引用本身。 - **误区**:“`Integer`作为对象,可以在方法内修改外部值。” **正解**:`Integer`的不可变性导致赋值操作会创建新对象,原对象不受影响。 通过以上分析,可以明确Java中`Integer`的行为本质是值传递
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值