云栖问答

找不到答案?去提问题

Java核心技术 2018-10-30 00:04:30

[@倚贤][¥20]什么是值传递和引用传递?

什么是值传递和引用传递?

7个回答

0

1537445919627494

值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响实际参数的值。 引用传递:(形式参数类型是引用数据类型参数):也称为传地址。方法调用时,实际参数是对象(或数组),这时实际参数与形式参数指向同一个地址,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,这个结果在方法结束后被保留了下来,所以方法执行中形式参数的改变将会影响实际参数。

0

琥珀行者

1、值传递

    在方法的调用过程中,实参把它的实际值传递给形参,此传递过程就是将实参的值复制一份传递到函数中,这样如果在函数中对该值(形参的值)进行了操作将不会影响实参的值。因为是直接复制,所以这种方式在传递大量数据时,运行效率会特别低下。

2、引用传递

    引用传递弥补了值传递的不足,如果传递的数据量很大,直接复过去的话,会占用大量的内存空间,而引用传递就是将对象的地址值传递过去,函数接收的是原始值的首地址值。在方法的执行过程中,形参和实参的内容相同,指向同一块内存地址,也就是说操作的其实都是源数据,所以方法的执行将会影响到实际对象。

作者:Norte_L
来源:CSDN
原文:https://blog.csdn.net/Norte_L/article/details/80250057
版权声明:本文为博主原创文章,转载请附上博文链接!

0

倚贤

在 C/C++ 中,区分点是传值和传址。传值很好理解,就是把一个变量的值传递给另外一个变量。那变量的本质是什么,变量是指代一个内存的区域。值就是这个内存区域里的值。那凭什么变量能指代这个内存区域呢?这是编译器帮我们搞定的,编译期其实变量就会变成一个指向内存区域的地址。变量其实是一个地址。好,那传址是啥意思呢?就是把一个变量所指代的地址赋值给另外一个变量。注意是变量所指代的地址,不是地址对应内存区域的值。

理解了传值和传址的区别,我们再来看 java 里的传引用。传值和传址在汇编层面就有的功能,其实是底层机器码就支持的。C/C++ 只是向上保留了这个功能。那 Java 凭什么又多出来了一个传引用。其实本质上传引用就是传址。只是 Java 做了个阉割,变量所指代的地址不能取出来赋给另外一个变量做为值。有没有发现 Java 中没有指针型变量?Java 的原生类型都是值变量,只能传值。对象型变量都是一维指针。不允许出现高维指针。因为都是一维指针,那也没有必要加个 * 号特别标记是指针变量了。

0

禅师

"值传递"和"引用传递"这个称谓,一般是 .NET 平台(C#, F#, VB.NET 等等) 使用的术语。

  1. 默认对于 class 类型变量传参是引用传递 - 传递的参数实例的引用;
  2. 对于 struct 类型变量的传参是值传递,也可以在加在 ref 声明,指定使用为引用传递;
  3. 注意 string 类有那第一点点不寻常,虽然也是按引用传递,但对 string 参数的赋值实际上是将其指向了另一个 string 实例,所以表现起来比较像是按值传递,而实例是按引用传递。
using System;

namespace Demo
{
    public struct Student
    {
        public long Id { get; set; }
        public string Name { get; set; }
    }

    public class Contact
    {
        public string Name { get; set; }
        public string Email { get; set; }
    }

    public static class Program
    {

        public static void TestStruct(Student student, int number) // 默认按值传递
        {
            student.Name = "student name";  //  此修改不会影响到方法调用者中的 stuct
            ++number;
        }

        public static void TestStructByRef(ref Student student, ref int number) // ref 强制改为按引用传递
        {
            student.Name = "student name";  //  此修改*会*影响到方法调用者中的 student
            ++number;
        }

        public static void TestClass(Contact contact) // 默认按引用传递
        {
            contact.Name = "contact name";  //  此修改*会*影响到方法调用者中的 contact
        }

        public static void TestString(String hello) // 默认按引用传递
        {
            hello = "hello, world";   //  此修改不会影响到方法调用者中的 hello
            Console.WriteLine(hello); //  will print "hello, world;
        }

        public static void TestStringOut(out String hello) // 默认按引用传递
        {
            hello = "hello, world";   //  此修改不会影响到方法调用者中的 hello
            Console.WriteLine(hello); //  will print "hello, world;
        }

        static void Main(string[] args)
        {
            Student student = new Student();
            student.Name = "new student";
            Console.WriteLine(student.Name);

            int number = 0;
            TestStruct(student, number);     // struct 默认按值传递
            Console.WriteLine(student.Name); // will write "new student" ##
            Console.WriteLine(number);       // will write 0
            Console.WriteLine();

            number = 0;
            TestStructByRef(ref student, ref number);
            Console.WriteLine(student.Name); // will write "student name" ##
            Console.WriteLine(number);       // will write 1
            Console.WriteLine();

            Contact contact = new Contact();
            contact.Name = "new contract";
            Console.WriteLine(contact.Name); // will write "new contact"

            TestClass(contact);              // class 默认按引用传递
            Console.WriteLine(contact.Name); // will write "contact name" ##
            Console.WriteLine();

            String hello = "hello";
            TestString(hello);
            Console.WriteLine(hello);        // will write "hello";

            hello = "hello";
            TestStringOut(out hello);
            Console.WriteLine(hello);        // will write "hello world";
        }

    }
}

0

静静-nancy

理解这两者区别之前先理解这两种数据存储的方式:
1、值类型(也称基本类型):一般包含number,string,bool,undefined,是将数据直接存储在变量中
2、对象类型(也称引用类型):一般包含array,object,基本上能new的都是,此类型一般存储复杂数据,无法直接存储在变量中,而是在内存中单独划一块空间,将这个对象放在空间内,并将这块内存空间的地址给变量
所以:值传递可以直接将自己的值复制给另一变量或函数的参数,内存中就会有两个变量是同样的值;而引用传递,则是将自己的引用地址给对方,对方通过地址找到的是同一个对象

0

janius

这个问题主要体现在方法入参上。
如果方法的入参是基本数据类型,那就是值传递,方法里如果对该入参的值做了变更,方法执行后该入参保持原来的值不便。
如果方法的入参是对象,则反之。

0

xwaby

传值参数:普通的非引用类型的参数通过复制对应的实参实现初始化。当用实参副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值。

引用形参直接关联到其所绑定的对象,而并非这些对象的副本。定义引用时,必须用与该引用绑定的对象初始化该引用。引用形参完全以相同的方式工作。每次调用函数,引用形参被创建并与相应实参关联。

1
GO
6769
浏览
0
收藏
邀请他人回答
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...

RDS是一种稳定可靠、可弹性伸缩的在线数据库服务。支持MySQL、SQL Server、PostgreSQL、高...