Можете ли вы перейти по ссылке в Java? - PullRequest
5 голосов
/ 17 ноября 2009

Извините, если это звучит как вопрос новичка, но на днях разработчик Java упомянул о передаче параметра по ссылке (по которому он просто передал объект Reference)

С точки зрения 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 ]

31 голосов
/ 17 ноября 2009

Нет, Java не может этого сделать. Ява проходит только по значению. Он также передает ссылки по значению.

10 голосов
/ 17 ноября 2009

Передача по ссылке - это концепция, которую Java-разработчики часто неправильно понимают, вероятно потому, что они не могут этого сделать. Читать это:

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

1 голос
/ 29 апреля 2010

Технически, как мы знаем, переменные, которые ссылаются на объекты, являются строго указателями на объект. При передаче объекта в качестве параметра методу указатель или ссылка копируются в переменную параметра. 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;

У вас есть ссылка на исходный объект в переменной параметра. Влияние на параметр параметр влияет на исходный объект. Вы можете делать все, кроме установки на ноль и ожидать, что оригинал будет также установлен на ноль. Подсчет ссылок предотвращает это.

1 голос
/ 17 ноября 2009

С точки зрения C # я могу передать тип ссылки по значению или по ссылка, это также верно для значения Типы

Относительно неверно говорить «передавать ссылочный тип по значению» в C #.

Нельзя передать тип ссылки по значению - вы можете передать ссылку на объект или ссылку на ссылку . В Java вы не можете передать ссылку на ссылку.

Однако ваше приложение noddie делает различие немного более ясным.

0 голосов
/ 17 ноября 2009

Самое близкое, что вы можете сделать, это передать AtomicReference. Это может быть изменено вызывающим абонентом. Это довольно некрасиво, но ИМХО так и должно быть. Изменение аргумента в методе - плохая идея.

0 голосов
/ 17 ноября 2009

Да, как вы указали, Java передает ссылки по значению. Это хорошая тема для интервью для Java-программистов, большинство, похоже, ошибаются.

...