当将一个方法的返回值分配给Java中的一个类类型变量时会发生什么?

huangapple go评论60阅读模式
英文:

What happens when assign a return value from a method to a Class type variable in Java?

问题

我有一个公共类Dog。

方法1:

public Dog getDog(Dog dog){
    if(dog.size > 0){
      return dog;
    }
    return null;
}

方法2:

public Dog getNewDog(){
   return new Dog();
}

最后,将方法返回值重新赋值:

Dog mydog = new Dog();
Dog d2 = new Dog();

Dog c = mydog.getDog(d2);   // 我们是将一个引用变量赋回另一个引用吗?
Dog k = mydog.getNewDog(); // 我们是将一个新的Dog对象本身赋给Dog类型的变量。

现在为什么我们总是将方法的返回值赋给引用变量我在Java中到处都看到这个


<details>
<summary>英文:</summary>

I have a public class Dog.

Method 1:

    public Dog getDog(Dog dog){
        if(dog.size&gt;0){
          return dog;
        }
        return null;
    }
        

Method 2:
    
    public Dog getNewDog(){
       return new Dog();
    }

Finally, assigning the method return value back:-

    Dog mydog = new Dog();
    Dog d2 = new Dog();
    
    Dog c = mydog.getDog(d2);   // are we assigning a reference variable back to another reference?
    Dog k = mydog.getNewDog(); // Are we assigning a new dog object itself to the Dog type variable.


now, why do we always assign back value from a method to a Reference variable? I have seen this everywhere in Java.


</details>


# 答案1
**得分**: 1

让我试着回答你提出的注释中的问题
A. 为什么我们总是将方法的返回值分配回一个引用变量- 不一定正确
有些类一旦给定了一个值就无法更改它这些被称为不可变”。例如,`String` 是不可变的所以一旦给它赋值就无法更改该字符串让我们看下面的例子

    String s1 = "1";
    String s2 = s1.concat("2")
    s2.concat("3");
    System.out.println(s2); // 输出 12

输出是 **12**原因是每当调用更改值的方法时您必须将其分配回去否则您将丢失新值对于一个不可变的对象正如您所见有必要重新分配但是这些是特殊的类`Dog` 的情况下您不必每次更改其属性时都进行分配除非您明确需要创建一个新的 `Dog` 对象

B. 我们是将一个新的狗对象本身分配给了狗类型的变量吗
无论何时声明一个类型为引用的变量它扩展自 Object 类),它都将被赋予 null如果您尝试访问其属性将会导致 `NullPointerException`。因此请记住您必须为其分配一个值

注意,`Dog k = mydog.getNewDog();` 在您的代码中等同于 `Dog k = new Dog();`。

C. 我们是将一个引用变量再次分配回另一个引用吗
让我们看看您的代码

    public Dog getDog(Dog dog){
        if(dog.size > 0){
            return dog;
        }
        return null;
    }
            
    Dog d2 = new Dog();
    Dog c = mydog.getDog(d2);

对于这段代码
 - 如果 `dog.size > 0` 为真`d2``c` 将引用同一个对象因此您对其中一个进行的任何更改都将反映在两者上
 - 如果 `dog.size > 0` 为假`c` 将被赋值为 `null`。

<details>
<summary>英文:</summary>

Let me try to answer the questions you have put as comments:
A. Why do we always assign back value from a method to a Reference variable? - Not necessarily true.
There are some classes once given a value, you can&#39;t change it. This are called `Immutable`. For instance, `String` is immutable, so once you assign it a value you can&#39;t change that same string. Let&#39;s see the following 
example:	

    String s1 = &quot;1&quot;;
    String s2 = s1.concat(&quot;2&quot;)
    s2.concat(&quot;3&quot;);
    System.out.println(s2); // print out 12
	
The output is **12**. The reason is that, whenever you call a method that changes the value you have to assign it back or you will lose the new value.
For an `Immutable` object, as you can see, it is necessary that you reassign. But, this are special classes. In the case of `Dog`, you don&#39;t have to assign it every time change its properties. Unless you explicitly needed to create a new `Dog` Object.

B. Are we assigning a new dog object itself to the Dog type variable?
Whenever you declare a variable of type reference(that extends Object), it will be assigned null. And if you try to access its properties, it results in `NullPointerException`. So, keep in mind that you have to assign a value to it.

Note that `Dog k = mydog.getNewDog();` is equivalent to saying `Dog k = new Dog();` in your code.

C. Are we assigning a reference variable back to another reference?
Let&#39;s see your code: 
	

    public Dog getDog(Dog dog){
    	if(dog.size&gt;0){
    		return dog;
    	}
    	return null;
    }
    		
    Dog d2 = new Dog();
    Dog c = mydog.getDog(d2);

For this piece of code:
 - if `dog.size &gt; 0` is true, `d2` and `c` will be referencing to the same object. So, any change you make to one of them will reflect on both.
 - if `dog.size &gt; 0` is false, `c` will be assigned `null`

</details>



# 答案2
**得分**: 0

所以你正在将新的 Dog 对象分配给变量 c 和 k这将导致覆盖先前保存的狗

虽然不一定非要这样做但至少在三种情况下这样做可能很有用
 - 有时这种方式可以减少代码行数
 - 如果你之前链接的对象在其他地方有使用可能不希望到处都进行更改如果一个方法返回一个新的经过转换的对象你可以确保旧对象仍然可以在其他地方使用
 - 这种模式可以用于构建器或链式调用如果一个方法返回一只狗无论是新的还是旧的),你可以直接在同一行上继续编写更多的方法调用例如mydog.getNewDog().bark();

<details>
<summary>英文:</summary>

So what you are doing is assignig new Dog objects to variable c and k, which results in overwriting the previously saved dogs.

It does not have to be done like this, but it can be useful in at least three cases:
 - sometimes this way results in less lines of code
 - if you used your previously linked object in other places, you might not want to change it everywhere. If a method returns a new (transformed) object, you can make sure the old object can still be used in other places
 - this pattern could be used for builders or chaining. if a method returns a dog (no matter if it is a new or an old one) you may directly continue writing more method calls on the same line. Example: mydog.getNewDog().bark();

</details>



huangapple
  • 本文由 发表于 2020年10月21日 02:25:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/64451241.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定