English 中文(简体)
Can you pass by reference in Java?
原标题:

Sorry if this sounds like a newbie question, but the other day a Java developer mentioned 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.





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签