对于Java的值传递和引用传递的区别

Java下的值传递引用传递区别以及swap函数的四种实现方式 Java中的值传递引用传递 CJava使用参数传值是用其实参值来进行初始化形参的值。对于基本变量,CC++允许显式传递变量的地址(引用传递),在scanf函数中的参数前面的&地址符可以见得。而Java允许这样做,因为Java对普通类型变量支持引用传递Java的方法传递只有值传递一种,即将实际的参数值的副本传入方法,而参数受影响 所以我们写一个测试代码来试验一下: package tes... 阅读详情

我知道有人会说,Java只有值传递而没有引用传递,但是如果把引用地址也看成一个值的话,是可以这么说的。
对于两个传递的定义是什么呢?
第一,值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。(一般发生在基本数据类型当中)
第二,引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。 所以对该副本进行操作时,会同时改变原对象。(发生在引用类型当中)
很多时候,传递都是发生在往方法里传参的情况,这个时候,你是可以将方法的形参当成一个变量,实际上,形参就是局部变量。
我会根据几道例题,来说明他们之间的区别

这是一道面试题

public static void main(String[] args) {  
    MyClass myClass = new MyClass();  
    change(myClass);  
    System.out.println(myClass.val);  
}  

private static void change(MyClass myClass) {  
        myClass = new MyClass();  
    myClass.val = 2;  
}  
public static class MyClass{  
    int val = 1;  
}  

为了方便理解,画图时,形参我改为myClass2了
这里写图片描述
以上可以大致可以清楚的看见引用变量指向对象的改变,但是为什么注释掉第三步会影响结果?
看下图
这里写图片描述
一开始的第三步的作用是,重写new一个对象,所以myClass2被重新赋值地址值,并不是原来myClass传给它的对象地址值。
可以看见,因为没有了第三步,所以这两个引用都是指向同一堆上的对象,所以任意一个引用只要对该对象进行数据域的操作,都会影响到数据域的改变。

myClass.val=2;      //重新对变量val赋值

这便是引用传递。

再来看一道引用传递的面试题。
以下代码结果是什么?

  public class foo {

   public static void main(String sgf[]) {

   StringBuffer a=new StringBuffer(“A”);

   StringBuffer b=new StringBuffer(“B”);

   operate(a,b);

   System.out.println(a+”.”+b);

   }

   static void operate(StringBuffer x,StringBuffer y) {

   x.append(y);

   y=x;
   }
  }

看一下图
这里写图片描述

还是我刚才的那句话,你把形参看作是一个引用变量,引用传参的实际就是地址值的赋值。

  x.append(y);

上面这个操作对应着是第二步骤,是对同一个对象的数据域的操作。

 y=x;

这是再一次的引用传递,将x的地址赋值给了y,导致原来 y 放弃指向了 B字符 所在对象,而指向了 AB字符 所在的对象。
注意,很多新手误以为,x=y 就是b=a,这是编程,不是数学。
这里只是将 x 的地址赋值给了 y,与 b=a 没有一毛钱的关系, ba 的存储的地址未发生改变。

再来看一道值传递的例题

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);    
      System.out.println(b);   
}    

change方法是平常将数值互换的一种方法,但是前提必须是本值,而不是传递的值。
在main方法中调用了change方法,在将a和b的值传递过去,这时就要注意了,这是值传递,传递的只是一个副本,与原值无关。
也就是,无论change方法中如何操作这两个形参a和b,输出的始终是

3
4

到这里,其实还没有结束,因为,你要注意有一个特殊的数据类型,就是String。
先来说String到底特殊在那一方面:
第一,当new出新对象时,会产生两个对象,第一是在字符串常量区,第二是在堆上(new 出对象)
第二,String是不可改变的,任何试图改变String的行为都会产生新对象,所以无论是用”+”还是用toLowerCase()等方法,都会产生新对象。
第三,String是引用类型。
虽然我说的有一丁点的偏题,但这些是对String传递时前的铺垫。

进入正题,看下面这道题,会输出什么?

public static void change(String s) {     
    s = “123”;    
}     

public static void main(String args[]) {     
    String s = “abc”;     
    change(s);     
    System.out.println(s);  
}  

看下面的图

这里写图片描述

为什么第二步和第三步会不一样?
String不是引用吗?
引用传递不是说,操作对象的数据域应该会影响到指向同一对象的引用啊?

但是,看我上面说的第二句话,String是不可改变的,任何试图改变String的行为都会产生新对象。
所以,实际上到第三步,两个S的指向已经是不同对象了,并没有给S重新赋值为“ 123”

再来看一题,

public class Example {    
    String str = "abc";    
    char[] ch = { 'a', 'b', 'c' };    
    public static void main(String args[]) {    
        Example ex = new Example();    
        ex.change(ex.str, ex.ch);    
        System.out.println(ex.str);    
        System.out.println(ex.ch);    
    }    
    public void change(String str, char ch[]) {  
   *** //  ch = new char[]{'a','b','c'};    
        str = "change";    
        ch[0] = 'c';    
    }    
}  

输出的结果为:

abc
cba

str变量不用说,是上面一道题一样的,两个str,
形参 str 指向了”change”,
成员变量 str 指向了”abc”。
变量ch和引用传递是一样的,都是操作的为同一对象,如果有* * *的一行不注释的话,结果就为

abc
abc

因为change的形参变量ch被重新赋值了地址值()。

ch = new char[]{'a','b','c'};

它操作的不再是成员变量 char[] ch 指向的对象了。

笔者水平有限,如有缺点和不足,请各位指出,谢谢大家。

值传递引用传递区别Java程序员必须掌握的基础知识 值传递是指将实际参数的值复制一份传递给形式参数,在方法内部对形式参数的修改会影响实际参数。引用传递是指将实际参数的引用(地址)传递给形式参数,在方法内部对形式参数的修改会影响实际参数。Java只有值传递:无论是基本类型还是对象类型基本类型:传递值的副本,方法内修改影响原值对象类型:传递引用地址的副本,但指向同一对象,方法内修改会影响原对象String特殊性:由于可变性,修改会创建新对象,原引用变。 阅读详情

相关推荐

Nest的限流方案

多维度限流(如 IP、用户 ID、接口级别、请求类型)可配置化(支持同环境接口动态配置)可观测性(接入日志、监控系统)高性能分布式支持(Redis 限流器)与鉴权鉴权链路集成(结合 JWT、API Token)以下是一个“标准// 优先按用户ID限流,否则按IP在main.ts维度建议限流存储推荐 Redis 支持多实例限流 Key 设计支持 IP + 用户ID + 路由等多种维度限流策略精细化配置,接口粒度调整异常处理自定义响应体、日志告警观测性。

Bruce__taotao的博客 1156

java修改引用对象地址值原值变问题

今天写代码遇到了一个很离谱的问题,A方法传递List进B在B方法里面修改了List的引用,但是A方法里面的List没做改变见下代码 public class Test{ public void A(){ List<String> list = Lists.newArrayList("123","234"); System.out.println(list.size()); } public void B(List<String> list){ list = n.

weixin_47733858的博客 2355

动态表单设计

自定一表单数据结构。内容展示如有必要行转列。前端根据题目类型自定义组件后端跟俊题目类型用策略模式校验各种类型这样有统计功能的简单动态问卷就可以了展示时可能某些场景需要行转列。大概估摸使用的话有可能kmic_form_data_detail表的记录数比较大,后期再考虑数据或者表迁移或拆分。

zquwei的博客 3414

Java 值传递引用传递

Java参数传递机制深度解析:只有值传递,没有引用传递 本文系统阐述了Java参数传递的核心机制,明确指出Java中只有值传递存在引用传递。对于基本类型,传递的是值的副本;对于引用类型,传递的是对象引用地址的副本。文章通过内存模型分析、20+代码实例与其他语言的对比,揭示了以下关键点: 值传递的本质是传递副本,形参修改影响实参 引用类型看似"引用传递"的表现,实则是通过地址副本修改共享对象 Java选择单一值传递机制是为了简化设计、确保安全 开发中需注意可变对象、引用重新赋值等

果酱 の 博客 1535

java传值传址的区别_java传值传址

What is the output of the program shown in the exhibit?A. 300-100-100-100-100B. 300-300-100-100-100C. 300-300-300-100-100D. 300-300-300-300-100Answer: B涉及知识点:1.Java中的参数传递有传值传址两种;2.基本类型String型作为参数时,为...

weixin_34187444的博客 1349

值传递引用传递区别

一、值传递:是指在调用函数时将s实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将会影响到实际参数。 ​ 代码在内存中的执行流程: 1、首先加载main方法; ​ 2、接下来int number = 100; ​ 3、输出调用前的number,结果为100; ​ 4、调用change方法; ​ 5、在change方法中传参,传的是number,值为100; ​ 6、在change方法中对其number修改其值为200; ​ 虽然方法中的numb...

mengfanshaoxia的博客 1万+

Java中的值传递与地址传递

Java语言中存在的两种传递方式: 值传递:在方法调用中,只传递参数的值而与地址无关,传递参数并使地址发生改变,因此调用后存在值相同但地址同的现象。 地址传递:直接将地址传递,此时修改地址内的值原参数的值也将随之改变,因此调用后两个参数的值一起变化,且地址相同。 要理解值传递与地址传递区别首先要理解Java内存空间的分化: Java内存空间由两部分组成:“栈”“堆”。通俗地说,地址一般存储...

qq_46384325的博客 1172

Java值传递引用传递区别

原文 前景 关于这个问题,引发过很多广泛的讨论,看来很多程序员对于这个问题的理解都尽相同,甚至很多人理解的是错误的。还有的人可能知道Java中的参数传递值传递,但是说出来为什么。 在开始深入讲解之前,有必要纠正一下大家以前的那些错误看法了。如果你有以下想法,那么你有必要好好阅读本文。 错误理解一:值传递引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。 错误理解二: Java引用传递。 错误理解三:传递的参数如果是普通类型,那就是值传递,如果是对象,那就是引用

ss810540895的博客 845

Java里边什么是值传递引用传递?两个有什么区别

学过java基础的人都知道,在java中参数的传递过程中有值传递应用传递,那么这两个到底有什么区别呢,下面我通过例子为大家详细的介绍下。 我们都知道Java中有八种数据类型,基础数据类型分别是:byte,short,int,long,float,double,char,boolean,引用数据类型分别是:数组,类接口。方法传参的时候我们有两种,一种是形式参数(定义方法时写的参数),一种是实际...

坐看云起时_雨宣 8340

java中按值传递引用传递区别

java中传参方式

morgerton的博客 1万+

26. 值传递引用传递区别的什么?为什么Java中只有值传递

Java 采用值传递机制,基本类型传递的是值的副本,对象传递的是引用副本。方法内修改基本类型影响原值,但通过对象引用副本可修改对象状态(如属性更改)。Java 没有真正的引用传递,因为重新赋值对象引用会影响外部变量。这种设计确保了数据安全,避免意外修改外部变量。即便对象参数表现出类似引用传递的行为,本质仍是传递引用的副本(值传递),符合 Java 安全、简单的设计哲学。

思你日度难眠 917

java中形参实参的区别值传递 引用传递

形参实参的区别 形参 就是形式参数,用于定义方法的时候使用的参数,用来接收调用者传递的参数。形参只有在方法被调用的时候,虚拟机才会分配内存单元,在方法调用结束之后便会释放所分配的内存单元。 因此,形参只在方法内部有效,所以针对引用对象的改动也无法影响到方法外。 实参 就是实际参数,用于调用方法是传递给方法的参数。实参在传递给方法前是要被先赋值才能传递的。 在值传递的过程中,只能把实参传递给形参,而能把形参的值反作用给实参。在函数调用过程中·,形参的值发生改变,而实参的值会发生改变。 在引用传递调用的机

qq_32273965的博客 1178

c语言值传递引用传递区别_Java值传递还是引用传递

Java 到底是值传递还是引用传递?先说结论,Java 都是值传递存在引用传递。数据类型首先从 Java 数据类型入手,Java 的数据类型分为基础类型引用类型。基础类型声明时在栈空间开辟内存,数值直接存储在栈空间。引用类型声明时在栈上开辟内存,用于存储对象的地址,而对象的具体信息存储在堆空间。int num = 10;String str = "java";如图,num 是基本类...

weixin_39586825的博客 628

值传递引用传递的概念区别

值传递引用传递的概念区别 参考回答: 值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本影响原变量. 引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并是原对象本身。所以对引用对象进行操作会同时改变原对象. 一般认为java内的传递都是值传递. 分析: 这里首先要明白几个重要的概念: 基本类型引用类型的区别 “=”赋值运算的本质 1.基本类型引用类型...

weixin_44844089的博客 770

值传递引用传递区别

值传递引用传递区别 java中在参数传递时有2种方式,两者的区别: 1、按值传zhi递dao:值传递是指在调用函数时将实际参zhuan数复制一份传递到函数中,这样在函数中如果对参数进行修改,将会影响到实际参数。简单来说就是直接复制了一份数据过去,因为是直接复制,所以这种方式在传递时如果数据量非常大的话,运行效率自然就变低了,所以java传递数据量很小的数据是值传递,比如java中的各种基本类型:int,float,double,boolean等类型的。 结果: 2、按引用传递引用传递其实就弥补

qq_45136944的博客 1938

java值传递引用传递区别

1、按值传递:   值传递是指在调用函数时,将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将会影响到实际参数。   简单来说就是直接复制了一份数据过去,因为是直接复制,所以这种方式在传递时如果数据量非常大的话,运行效率自然就变低了,所以java传递数据量很小的数据是值传递,比如java中的各种基本类型:int,float,double,boolean等类型的。 2、按引用传递:   引用传递其实就弥补了上面说的足,如果每次传参数的时候都复制一份的话,如果这个参数占用的内存空间太大的

zhf的博客 3745

JAVA传值引用区别

基本类型(byte,short,int,long,double,float,char,boolean)为传值,传的是副本所以会影响原有的值对象类型(Object,数组,容器)为传引用,会影响原来的值String、Integer、Double等immutable类型因为类的变量设为final属性,无法被修改,只能重新赋值或生成对象。当Integer作为方法参数传递时,对其赋值会导致原有的引用被指向了方法内的栈地址,失去原有的的地址指向,所以对赋值后的Integer做任何操作都会影响原有值。...

LuckFairyLuckBaby的博客 1612

java值传递引用传递

当我们传递一个基本数据类型的参数时,实际上是将参数的值复制一份传递给方法,方法内部对参数的修改会影响到原始的参数。而当我们传递一个引用数据类型的参数时,实际上是将参数的引用复制一份传递给方法,方法内部对参数的修改会直接影响到原始的参数。需要注意的是,虽然引用传递中方法内部对参数的修改会影响到原始的参数,但是如果在方法内部将参数重新赋值,即改变了参数的引用指向的对象,那么这种改变会影响到原始的参数的。可以看到,对于基本数据类型的值传递,方法内部对参数的修改会影响到原始的参数。

牛肉胡辣汤 2035

103报文解析工具

电力101、103、104规约报文解析工具,方便调试人员现场使用。

下一篇: equals()方法和"=="区别
子杰小同学
博客等级 码龄10年 2粉丝 4原创
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值