你能通过Java引用吗?

时间:2009-11-17 12:19:26

标签: c# java parameters pass-by-reference

很抱歉,如果这听起来像是一个新手问题,但是前几天Java开发人员提到了通过引用传递参数(通过引用传递参考对象)

从C#的角度来看,我可以按值或引用传递引用类型,这也适用于值类型

我写了一个noddie控制台应用程序来显示我的意思..我可以用Java做到这一点吗?

namespace ByRefByVal
{
    class Program
    {
        static void Main(string[] args)
        {
            //Creating of the object
            Person p1 = new Person();
            p1.Name = "Dave";
            PrintIfObjectIsNull(p1); //should not be null

            //A copy of the Reference is made and sent to the method
            PrintUserNameByValue(p1);
            PrintIfObjectIsNull(p1);

            //the actual reference is passed to the method
            PrintUserNameByRef(ref p1);    //<-- I know im passing the Reference
            PrintIfObjectIsNull(p1);

            Console.ReadLine();
        }

        private static void PrintIfObjectIsNull(Object o)
        {
            if (o == null)
            {
                Console.WriteLine("object is null");
            }
            else
            {
                Console.WriteLine("object still references something");
            }
        }

        /// <summary>
        /// this takes in a Reference type of Person, by value
        /// </summary>
        /// <param name="person"></param>
        private static void PrintUserNameByValue(Person person)
        {
            Console.WriteLine(person.Name);
            person = null; //<- this cannot affect the orginal reference, as it was passed in by value.
        }

        /// <summary>
        /// this takes in a Reference type of Person, by reference
        /// </summary>
        /// <param name="person"></param>
        private static void PrintUserNameByRef(ref Person person)
        {
            Console.WriteLine(person.Name);
            person = null; //this has access to the orginonal reference, allowing us to alter it, either make it point to a different object or to nothing.
        }


    }

    class Person
    {
        public string Name { get; set; }
    }
}

如果java不能这样做,那么它只是按值传递引用类型? (这是公平的说法)

非常感谢

6 个答案:

答案 0 :(得分:31)

不,Java不能这样做。 Java只按值传递。它也按值传递引用。

答案 1 :(得分:10)

通过引用传递是一个经常被Java开发者误解的概念,可能是因为他们不能这样做。阅读本文:

http://javadude.com/articles/passbyvalue.htm

答案 2 :(得分:1)

  

从C#的角度来看,我可以传递一个   按值或按引用类型   参考,这也是真实的价值   类型

在C#中说“按值传递引用类型”是相对误导的。

您无法按值传递引用类型 - 您可以将引用传递给对象,或者引用引用。在java中,您无法传递对引用的引用。

然而,你的noddie应用程序使区别更加清晰。

答案 3 :(得分:1)

从技术上讲,正如我们所知,引用对象的变量是对象的严格指针。将对象作为参数传递给方法时,指针或引用将复制到参数变量。 Java称之为“按值传递”。

因此,您最终得到至少两个引用同一对象的变量。如果将参数变量设置为null,则由于引用计数,其他变量将保留其值。

如果您有以下方法:

public void function(Person person) {};

一个对象:

Person marcus = new Person();
marcus.name = "Marcus";

调用这样的方法:

function(marcus);

你基本上在方法的本地范围内得到这个:

Person person = marcus;

如果您设置person = null,则不会影响marcus的值。这是由于引用计数。

但是,如果你这样做:

person.name = null;

这也是如此:

marcus.name == null;

您确实在参数变量中引用了原始对象。影响参数变量会影响原始对象。除了将其设置为null之外,您可以执行所有操作,并且还希望将原始设置为null。引用计数可以防止这种情况。

答案 4 :(得分:0)

是的,正如您所指出的,Java正在按值传递引用。这为java程序员提供了一个很好的面试主题,大多数人似乎都错了。

答案 5 :(得分:0)

您可以做的最接近的是通过AtomicReference。这可以由呼叫者改变。这是相当丑陋的,但恕我直言应该是。更改方法中的参数是个坏主意。