📜  用Java传递和返回对象

📅  最后修改于: 2020-04-02 06:07:47             🧑  作者: Mango

尽管Java 严格按值传递,但传递原始类型还是引用类型的精确效果有所不同。
当我们将原始类型传递给方法时,它会按值传递。但是,当我们将对象传递给方法时,情况发生了巨大变化,因为对象是通过有效的按引用调用传递的。Java做了一件有趣的事情,即按值传递和按引用传递之间的混合。基本上,函数无法更改参数,但是函数可以通过调用其中的某些方法来要求参数更改自身。

  • 在创建类类型的变量时,我们仅创建对对象的引用。因此,当我们将此引用传递给方法时,接收该方法的参数将引用与参数所引用的对象相同的对象。
  • 这实际上意味着对象的行为就像通过引用调用将它们传递给方法一样。
  • 方法内部对象的更改确实会反映在用作参数的对象中。

在Java中,我们可以将对象传递给方法。例如,考虑以下程序:

// Java将对象传递给方法
class ObjectPassDemo
{
    int a, b;
    ObjectPassDemo(int i, int j)
    {
        a = i;
        b = j;
    }
    // 如果o等于被调用的对象,返回true
    boolean equalTo(ObjectPassDemo o)
    {
        return (o.a == a && o.b == b);
    }
}
// 测试代码
public class Test
{
    public static void main(String args[])
    {
        ObjectPassDemo ob1 = new ObjectPassDemo(100, 22);
        ObjectPassDemo ob2 = new ObjectPassDemo(100, 22);
        ObjectPassDemo ob3 = new ObjectPassDemo(-1, -1);
        System.out.println("ob1 == ob2: " + ob1.equalTo(ob2));
        System.out.println("ob1 == ob3: " + ob1.equalTo(ob3));
    }
}

输出:

ob1 == ob2: true
ob1 == ob3: false

上述程序的说明图

  • 创建了三个对象“ ob1″,“ ob2″和“ ob3″:
    ObjectPassDemo ob1 = new ObjectPassDemo(100, 22);
    ObjectPassDemo ob2 = new ObjectPassDemo(100, 22);
    ObjectPassDemo ob3 = new ObjectPassDemo(-1, -1);

  • 从方法方面,声明了名称为a的类型为Foo的引用,并将其最初分配为null。
    boolean equalTo(ObjectPassDemo o);

  • 当我们将方法称为equalTo时,会将引用“ o”分配给作为参数传递的对象,即在执行以下语句时,“ o”将引用“ ob2″。
    System.out.println("ob1 == ob2: " + ob1.equalTo(ob2));

  • 现在我们可以看到,对’ob1’调用了equalTo方法,而’o’则指的是’ob2’。由于两个引用的’a’和’b’值均相同,因此if(condition)为true,因此将返回布尔值true。
    if(o.a == a && o.b == b)
  • 再次执行以下语句时,“ o”将重新分配给“ ob3″。
    System.out.println("ob1 == ob3: " + ob1.equalTo(ob3));

  • 现在我们可以看到,在’ob1’上调用了equalTo方法,而’o’则是指’ob3’。由于两个引用的’a’和’b’值都不相同,因此if(condition)为false,因此else块将执行,并且false将返回。

定义一个将其类的对象作为参数的构造函数

对象参数最常见的用途之一是设计构造函数。在实践中,经常需要构造一个新对象,使其最初与某些现有对象相同。为此,我们可以使用Object.clone()方法或定义一个将其类的对象作为参数的构造函数。下例说明了第二个选项:

// Java展示定义一个将其类的对象作为参数的构造函数
class Box
{
    double width, height, depth;
    // 构造函数接收Box的对象
    Box(Box ob)
    {
        width = ob.width;
        height = ob.height;
        depth = ob.depth;
    }
    // 另一个构造函数
    Box(double w, double h, double d)
    {
        width = w;
        height = h;
        depth = d;
    }
    // 计算并返回值
    double volume()
    {
        return width * height * depth;
    }
}
// 测试代码
public class Test
{
    public static void main(String args[])
    {
        // 所有box的信息已经给出,构造一个对象
        Box mybox = new Box(10, 20, 15);
        //  创建一个box的copy
        Box myclone = new Box(mybox);
        double vol;
        // 获取box的容量
        vol = mybox.volume();
        System.out.println("box的容量 " + vol);
        // 获取myclone的容量
        vol = myclone.volume();
        System.out.println("myclone的容量 " + vol);
    }
}

输出:

box的容量 3000.0
myclone的容量 3000.0

返回对象
在Java中,方法可以返回任何类型的数据,包括对象。例如,在下面的程序中,incrByTen()方法返回一个对象,其中a(整数变量)的值比调用对象中的值大十倍。

// Java展示返回对象
class ObjectReturnDemo
{
    int a;
    ObjectReturnDemo(int i)
    {
        a = i;
    }
    // 此方法返回对象
    ObjectReturnDemo incrByTen()
    {
        ObjectReturnDemo temp =
               new ObjectReturnDemo(a+10);
        return temp;
    }
}
// 测试代码
public class Test
{
    public static void main(String args[])
    {
        ObjectReturnDemo ob1 = new ObjectReturnDemo(2);
        ObjectReturnDemo ob2;
        ob2 = ob1.incrByTen();
        System.out.println("ob1.a: " + ob1.a);
        System.out.println("ob2.a: " + ob2.a);
    }
}

输出:

ob1.a: 2
ob2.a: 12

注意:将对象引用传递给方法时,引用本身将通过按值调用来传递。但是,由于传递的值引用一个对象,因此该值的副本仍将引用其相应参数引用的同一对象。这就是为什么我们说Java 严格按值传递