当前位置: 首页 > 知识库问答 >
问题:

在Java中,什么时候方法调用可以和不能更改参数?[重复]

霍修筠
2023-03-14

这是java语言。我试图在这里搜索这个问题的答案,但找不到足够的答案,所以如果这是重复的,我很抱歉。我对改变输入参数的方法背后的规则感到困惑。例如,考虑下面的例子

public static void messWithArray(int[] array)
{
     array[0] = 100;
     array[0] += 5;

     // make new array
     int[] array2 = new int[10];
     for(int i = 0; i < 10; i++)
     {
         array2[i] = 5+i;
     }
     array = array2
 }
 public static void main(String[] args)
 {
     int[] a = new int[10]
     for(int i=0; i < 10; i++)
     {
         a[i] = i*10
     }
     messWithArray(a);
     System.out.println(a[0]);
     System.out.println(a[1]);

这表明a[0]是105,a[1]是10,因此在messWithArray方法中使数组[0]等于100并加上5会产生效果。然而,分配array=array2没有做任何事情(因为[1]是10)。我还尝试过处理int,但没能让它工作。

我想更具体/更清楚地知道一个方法是否会改变数组的属性背后的逻辑。

共有3个答案

堵浩波
2023-03-14
class Arrays
{
public static void messWithArray(int[] array)
{
     array[0] = 100;
     array[0] += 5;

     // make new array
     int[] array2 = new int[10];
     for(int i = 0; i < 10; i++)
     {
         array2[i] = 5+i;
    System.out.println(array2[i]);
     }
     array = array2;
System.out.println("CHANGED VALUE --->"+array[0]);
 }
 public static void main(String[] args)
 {
     int[] a = new int[10];
     for(int i=0; i < 10; i++)
     {
         a[i] = i*10;
     }
     messWithArray(a);
     System.out.println(a[0]);
     System.out.println(a[1]);
 }
}

您应该从messWithArray()函数返回更新的数组,这将更新数组值。

居英资
2023-03-14

我可以从内存的角度来解释它。数组就像一个指针指向一个特定的内存块(让我们说一个内存地址作为一个Long值)。当你把它传递给内存时,你就把这个指针传递给函数。数组[5]就像点5,意思是数组显示后的第五个内存单元。当您执行array2时,您实际上更改了内存单元的值,该单元指向array2显示位置之后的第五个单元。因此,您实际上更改了array内部的值。但是array2是指向内存中另一个单元的指针。因此,当您执行array2时,您只需将指针更改为新位置。因此,由于指针是通过方法调用复制的,因此函数外的原始指针保持不变,并且您仍然可以看到array2的元素

汪阿苏
2023-03-14

在Java中,方法参数总是按值传递。然而,所有对象(包括数组,甚至原语数组)都由指针引用,指针允许通过对象的方法(或通过数组访问数组)修改对象,指针通过值传递。

您永远不能重新定位调用者中引用的参数,但始终可以对可变的内容进行变异。

public void someMethod(int param1, List<String> param2, double[] param3) {
  // In here, I can change what 'param1', 'param2', or 'param3' refer to:
  param1 = 3;
  // but this didn't change the value from whoever called me.
  // Doing "param2 = new ArrayList<>();" similarly wouldn't affect the caller.
  // The pointer to the list was simply copied.
  param2.add("Hello");
  // However, that ^ modified the list through the pointer.
  // Same is true for arrays:
  param3[0] = 0.0; // modified the original array
  param3 = new double[3]; // changed 'param3' to refer to a new array
}
 类似资料:
  • 问题内容: 我需要知道何时在中调用该方法。我创建了一个测试类,该法通过覆盖该方法来在调用该方法时将其写入文件。它不执行。谁能告诉我它为什么不执行的原因? 问题答案: 通常,最好不要依赖进行任何清理等工作。 根据Javadoc(值得阅读),它是: 当垃圾回收确定不再有对该对象的引用时,由垃圾回收器在对象上调用。 正如Joachim指出的那样,如果对象始终是可访问的,则在程序生命中可能永远不会发生这种

  • (1)重载是多态的集中体现,在类中,要以统一的方式处理不同类型数据的时候,可以用重载。 (2)重写的使用是建立在继承关系上的,子类在继承父类的基础上,增加新的功能,可以用重写。 (3)简单总结: 重载是多样性,重写是增强剂; 目的是提高程序的多样性和健壮性,以适配不同场景使用时,使用重载进行扩展; 目的是在不修改原方法及源代码的基础上对方法进行扩展或增强时,使用重写; 生活例子: 你想吃一碗面,我

  • 已弃用。这种方法本质上是不安全的。使用thread.Stop停止线程会导致它解锁它锁定的所有监视器(作为未检查的ThreadDeath异常向堆栈上传播的自然结果)。如果以前由这些监视器保护的任何对象处于不一致的状态,则损坏的对象将对其他线程可见,从而可能导致任意行为。stop的许多用法应该被简单修改某个变量以指示目标线程应该停止运行的代码所取代。目标线程应该定期检查这个变量,如果变量指示它要停止运

  • 问题内容: 当我创建自己的Android自定义类时,它就是本机类。然后,当我要重写基方法,我总是叫方法,就像我一直做的,等 我认为就是这样,因为从一开始,Android团队就建议我们始终调用每个方法重写。 但是,在 许多书籍中, 我可以看到比我自己更有经验的开发人员经常忽略调用,而且我真的怀疑他们是因为缺乏知识而这样做。例如,看看这个基本的SAX,其中解析器类中被省略,并且: 如果尝试通过Ecli

  • 问题内容: 我阅读的所有资料都提到了几个案例,并以“其他一些案例”作了总结。在视图/活动中调用onSaveInstanceState方法时,所有情况是什么? 问题答案: 该文档称 在活动被杀死之前将调用此方法,以便将来在将来返回某个时间时可以恢复其状态。