Как вернуть ссылку на объект в качестве параметра в Java

хотя я запрограммировал C, C++ и C# в течение многих лет, я только поверхностно знаком с Java. Помогая моему сыну Comp Sci с проектом Java college, он должен был вернуть ссылки на два объекта из метода в Java. Я предложил вернуть один в качестве значения функции, а второй-в качестве ссылки. Он не знал, как это сделать. Я провел небольшое исследование и понял, что это может быть невозможно. Мой вопрос в Java, что является общим методом, используемым, когда метод должен возвращать больше чем одна ссылка на объект. Вот конкретный пример в случае с моими сыновьями.

// This method returns references to the head and tail objects from the passed in 
// linked list.  The head object is returned as the function value and the tail is 
// returned as a parameter.
public Static Node GetHeadTail(List list, Node tail)

Я понимаю, что вышеизложенное не работает в Java, так как хвост является ссылкой на узел, а в Java сама ссылка передается по значению. Каков наиболее распространенный способ борьбы с этим на Java? Решением моего сына было вернуть массив из 2 объектов узла для значения функции. Я сказал, что это плохое решение, потому что оно не документирует значение каждого элемента массива. Другой решением было бы создать объект, содержащий ссылки head и tail. Однако в конкретном примере наибольший интерес представлял указатель head, и если объект был возвращен, он создаст нежелательные накладные расходы на кодирование для вызывающего метода, если все, что им нужно, это head.

6 ответов


в этом случае программисты java обычно создают класс с 2 членами:head и tail. Это будет тип возврата для getHeadTail(List list) метод.


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


Java всегда является pass-by-value. Сложную вещь можно понять что Java передает объекты как ссылки, и эти ссылки передаются по значению. (на Java "передача по ссылке" и "передача по значению"?)

тем не менее, вы способны сделать что-то вроде этого:

public static void main(String[] args)
{
    Car c = new Car("Blue");
    System.out.println(c.getName());
    changer(c);
    System.out.println(c.getName());
}

public static void changer(Car c)
{
    c.setName("Red");
}

класс автомобиля.

public class Car 
{
    private String name;

    public Car(String n)
    {
        name = n;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String n)
    {
        name = n;
    }
}

выход будет:

Blue
Red

зная это, вы сможете изменить то, что tail указывает и все еще может вернуть head.


Java делает эту интересную вещь, которая является своего рода гибридом между pass-by-value и pass-by-reference. В принципе, параметр не может быть изменен функцией, но функция может попросить параметр изменить себя через вызов некоторого метода внутри него. этот ответ делает довольно хорошую работу по его объяснению.

в ответ на "каков наиболее распространенный способ борьбы с этим в Java?"ваше решение о создании класса, который содержит ссылку head и tail, - это наверное, самая распространенная и лучшая практика. Если возможно, лучше всего просто иметь отдельные методы getHead и getTail.


одно чуть менее очевидное решение: используйте один из встроенных типов, например Queue или LinkedList, у которого уже есть голова и хвост.

LinkedList list = new LinkedList();
head = list.getFirst();
tail = list.getLast();

есть куча типов, подобных этому, в зависимости от ваших потребностей. читать документацию.


немного суховато метод заключается в использовании массива в качестве параметра. Затем функция может изменить значение одного или нескольких элементов, чтобы" вернуть " его. Это не очень красиво, но выполняет работу и избегает необходимости создавать специальные объекты-оболочки для этой цели.

Так же, как Примечание, Scala решает эту проблему, позволяя вам возвращать кортежи.