2年前 (2022-08-24)  Java系列 |   抢沙发  253 
文章评分 0 次,平均分 0.0

今天,我们将看一看基本但棘手的面试问题,Java中的值调用引用调用。无论是初学者还是有经验的开发人员都会在面试中遇到这个问题。这是技术面试官最喜欢的问题。这篇文章不只是用一句话来回答你,而是试着解释它。

为什么按值调用和按引用调用???

方法或函数可以用两种方式调用。一种是按值调用,另一种是根据引用调用,这两种方式通常根据作为输入或参数传递给它们的值的类型来区分。

在开始之前,让我澄清一件事,在Java中,只有按值调用,而不是按引用调用

按值调用

按值调用是一种方法,通过复制给定变量(或常量或任何保存数据的东西)的实际值来将参数传递给函数

这意味着,当我们使用传递参数的参数值调用方法时,该参数值将被复制到内存的一部分(取决于类型),并将该值的副本传递给调用方法的参数。

⚠️ 在Java中,只有按值调用,而不是按引用调用。

引用调用

通过引用调用是一种将值的引用(即地址)传递给方法的方法。

这意味着,当我们通过将引用的副本(即地址)传递给该方法的值而不是值本身的副本来调用该方法时,则调用方法具有该值的引用(即地址)。

当调用方法更改值的引用时,原始引用也会更改。

为什么在Java中只有按值调用,而不是按引用调用???

根据定义,引用调用是我们传递该变量的引用(即地址)的地方。要做到这一点,我们需要首先存储地址,这将需要一个指针(在C中,它作为*.variableName传递)。正如我们在java中所知,我们没有指针,因此不可能传递引用(即地址)并逐个引用执行调用。

Java不支持指针,这就是为什么Java不支持引用调用。但是C/C++支持指针,因此这些语言支持引用调用。

您可能会问,为什么Java不支持指针?好吧,这是另一个有争议的话题,我们可以在其他文章中讨论,直到签出这个stackoverflow页面,它让您对它有了一些了解。

https://stackoverflow.com/questions/5298421/why-doesnt-java-support-pass-by-reference-like-c

但是,我们仍然可以在Java中借助对象行为实现引用调用

Java中的引用调用,但如何???

Java总是使用按值调用。这意味着该方法获取所有参数值的副本,并且该方法不能修改传递的变量的内容。Java使用两种方法参数:

  • Java基元类型
  • Java对象引用

这看起来非常简单明了,就像向方法传递基元类型一样。但在将对象传递给方法时,这是非常引人注目的。当一个对象被传递给一个方法时,该方法会获得一个对象引用的副本,并且原始和形式副本都引用同一个对象,因此在调用方法中,可以更改对象参数的状态。

因此,让我们通过一个示例详细了解上述两个方法参数。

将Java原始数据类型作为参数传递给方法

对于原始数据类型参数,原始值不变。让我们举一个简单的例子:

public class PrimitiveDataInAction {
  public static void main(String[] args) {

    int someValue = 50;

    System.out.println("Before method call :: " + someValue);
    
    modified(someValue);
    
    System.out.println("After method call :: " + someValue);
  }

  public static void modified(int someValue) {
    System.out.println("exiting name :: " + someValue);
    // modifying the parameter
    someValue = 15;

    System.out.println("modified name :: " + someValue);
  }
}

输出:

Before method call :: 50
exiting name :: 50
modified name :: 15
After method call :: 50

Process finished with exit code 0

当您将原始数据类型变量传递给一个方法时,它会为该方法创建一个本地副本,并在该变量从该方法中出来后执行方法中提到的任何操作,以便从内存中删除该方法的本地副本

&调用该变量之前加载的上一个值。

Java对象引用

在使用Java对象引用类型的按值调用的情况下,将更改原始值。让我们举一个简单的例子:

class JavaObjectReferencesInAction {
  public static void main(String[] args) {

    List <String> listOfString = new ArrayList < > ();
    listOfString.add("Mahesh");

    System.out.println("Before modified :: " + listOfString);

    modified(listOfString);

    System.out.println("After modified :: " + listOfString);
  }

  public static void modified(List < String > listOfString) {
    // modifying the string
    listOfString.add("Imran");
  }
} 

输出:

Before modified :: [Mahesh]
exiting listOfString :: [Mahesh]
modified listOfString :: [Mahesh, Imran]
After modified :: [Mahesh, Imran]

Process finished with exit code 0

让我们看看它是如何工作的。

在上面的示例中,我们创建了一个ArrayList对象,并在其中添加了一个字符串值Mahesh。现在列表中的数据是一个字符串,值为Mahesh

在下一行中,我们调用了modified方法,该方法获取一个列表,并向相同的给定列表中添加一个字符串Imran

但是,当我们调用修改后的方法时,会发生Java对象引用,而不是值。它传递list的引用,list只是list的实际对象

这也会导致修改原始列表。

 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/2746.html

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册