开发者

Can you pass by reference in Java?

Sorry if this sounds like a newbie question, but the other day a Java developer mention开发者_高级运维ed about passing a paramter by reference (by which it was ment just pass a Reference object)

From a C# perspective I can pass a reference type by value or by reference, this is also true to value types

I have written a noddie console application to show what i mean.. can i do this in 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; }
    }
}

If it java cannot do this, then its just passing a reference type by value? (is that fair to say)

Many thanks

Bones


No, Java cannot do this. Java only passes by value. It passes references by value too.


Pass by reference is a concept often misunderstood by Java devs, probably because they cannot do it. Read this:

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


From a C# perspective I can pass a reference type by value or by reference, this is also true to value types

It's relatively misleading to say "pass a reference type by value" in C#.

You cannot pass a reference type by value - you can pass a reference to the object, or a reference to the reference. In java, you cannot pass a reference to the reference.

Your noddie application makes the distinction a little clearer, however.


Technically, as we know, variables that reference objects are strictly pointers to the object. When passing an object as a parameter to a method, the pointer or reference gets copied to the parameter variable. Java calls this "pass by value".

So, you end up with at least two variables that reference the same object. If you set the parameter variable to null, other variables keep their value thanks to reference counting.

If you have the following method:

public void function(Person person) {};

And an object:

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

Calling the method like this:

function(marcus);

You basically get this in the method's local scope:

Person person = marcus;

If you set person = null, it doesn't affect the value of marcus. This is due to reference counting.

However, if you do this:

person.name = null;

This is also true:

marcus.name == null;

You do have a reference to the original object in the parameter variable. Affecting the parameter variable does affect the original object. You can do everything except set it to null and expect the original to be set to null also. Reference counting prevents that.


Yes, as you pointed out, Java is passing references by value. This makes a good interview topic for java programmers, most seem to get it wrong.


The closest you can do is pass AtomicReference. This can be altered by the caller. It is rather ugly, but IMHO it should be. Changing an argument in a method is a bad idea.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜