Java中如何以参数形式返回对对象的引用 虽然我已经编程C、C++和C多年,但我对java只是表面上熟悉。帮助我的同事完成一个Java大学项目时,他需要从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指针,如果返回了一个对象,那么如果方法的调用方只需要head,那么它将为调用方创建不希望的编码开销 在Java中只能按值传递。您最好的解决方案是您儿子建议的第二个解决方案,即返回具有头部和尾部的对象。在这种情况下,java程序员通常会创建一个包含两个成员的类:Java中如何以参数形式返回对对象的引用 虽然我已经编程C、C++和C多年,但我对java只是表面上熟悉。帮助我的同事完成一个Java大学项目时,他需要从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,reference,parameter-passing,Java,Reference,Parameter Passing,我意识到上述方法在Java中不起作用,因为尾部是对节点的引用,而在Java中,引用本身是通过值传递的。Java中最常见的处理方法是什么?我儿子的解决方案是为函数值返回一个由2个节点对象组成的数组。我说这是一个糟糕的解决方案,因为它没有记录数组中每个元素的含义。另一个解决方案是创建一个包含头部和尾部引用的对象。然而,在特定的示例中,最感兴趣的是head指针,如果返回了一个对象,那么如果方法的调用方只需要head,那么它将为调用方创建不希望的编码开销 在Java中只能按值传递。您最好的解决方案是您儿
head
和tail
。这将是getHeadTail(List)
方法的返回类型
LinkedList list = new LinkedList();
head = list.getFirst();
tail = list.getLast();
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");
}
class MyCrazyClass {
private static void myCrazyMethod(Future<String> returnVal1, Future<Integer> returnVal2, Future<Float> returnVal3) {
returnVal1.set("We are cool!");
returnVal2.set(123);
returnVal3.set(321F);
}
public static void main(String[] args) {
Future<String> strRetVal = new Future<>();
Future<Integer> intRetVal = new Future<>();
Future<Float> floatRetVal = new Future<>();
myCrazyMethod(strRetVal, intRetVal, floatRetVal);
System.out.println(strRetVal.get());
System.out.println(intRetVal.get());
System.out.println(floatRetVal.get());
}
}
汽车类
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做了一件有趣的事情,它是按值传递和按引用传递的混合体。基本上,函数不能更改参数,但函数可以通过调用其中的某个方法来要求参数自行更改
在回答“Java中最常见的处理方法是什么?”时,您创建包含head和tail引用的类的解决方案可能是最常见和最佳实践。如果可能的话,最好只使用单独的getHead和getTail方法。一个稍微不那么明显的解决方案:使用一种内置类型,如Queue或LinkedList,它已经有了head和tail
LinkedList list = new LinkedList();
head = list.getFirst();
tail = list.getLast();
根据你的需要,有很多像这样的类型 一种有点老套的技术是使用数组作为参数。然后,函数可以更改一个或多个元素的值以“返回”它。它并不漂亮,但可以完成工作,并且避免为此目的创建特殊的包装器对象
作为旁注,Scala通过让您返回元组解决了这个问题。如果您试图实现一个返回多个值作为参数的方法,您可以使用如下方法:
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");
}
class MyCrazyClass {
private static void myCrazyMethod(Future<String> returnVal1, Future<Integer> returnVal2, Future<Float> returnVal3) {
returnVal1.set("We are cool!");
returnVal2.set(123);
returnVal3.set(321F);
}
public static void main(String[] args) {
Future<String> strRetVal = new Future<>();
Future<Integer> intRetVal = new Future<>();
Future<Float> floatRetVal = new Future<>();
myCrazyMethod(strRetVal, intRetVal, floatRetVal);
System.out.println(strRetVal.get());
System.out.println(intRetVal.get());
System.out.println(floatRetVal.get());
}
}
公共类未来{
私人T实例;
公共部门得不到{
返回此.instance;
}
公共无效集(T值){
this.instance=值;
}
}
然后像这样使用它:
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");
}
class MyCrazyClass {
private static void myCrazyMethod(Future<String> returnVal1, Future<Integer> returnVal2, Future<Float> returnVal3) {
returnVal1.set("We are cool!");
returnVal2.set(123);
returnVal3.set(321F);
}
public static void main(String[] args) {
Future<String> strRetVal = new Future<>();
Future<Integer> intRetVal = new Future<>();
Future<Float> floatRetVal = new Future<>();
myCrazyMethod(strRetVal, intRetVal, floatRetVal);
System.out.println(strRetVal.get());
System.out.println(intRetVal.get());
System.out.println(floatRetVal.get());
}
}
事实上,常见的解决方案是您已经知道的:a)将要返回的对象封装在一个对象中,或b)返回一个数组。您真的需要在一次调用中获得这两个吗?在大多数情况下,我只会使用两种方法:
getHead
和getTail
。我认为你儿子的解决方案是好的,但是根据它的情况创建一个对象是很好的。根据我个人的说法,我发现了你暗示的神秘方法,但我从来没有真正喜欢C++。我会将头部和尾部包装在某个命名有意义的类(您描述的解决方案之一)的对象中。其他JVM语言会给你更多的选择(比如Scala,以及它在语法和类型上处理元组的方式),但我担心这和你在Java中得到的一样好。将其拆分为两个单独的方法听起来也像是一个计划。拆分为两个单独的调用并不是一个好的解决方案,因为在本例中查找head和tail在计算上很重要,一旦方法返回,结果就会丢失。也就是说,必须再次遍历列表才能找到尾部。我在这里看到的最好的建议是创建一个独特的类来包含head和tail。