Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,如何在函数中分配空数组?_Java_Arrays - Fatal编程技术网

在Java中,如何在函数中分配空数组?

在Java中,如何在函数中分配空数组?,java,arrays,Java,Arrays,尝试获取一个函数以使用值填充多个数组。希望能够做到这一点: public class Demo { public static void getData(int[] array1, int[] array2) { array1 = new int[5]; array2 = new int[5]; } public static void main(String[] args) { int[] array1 = null; int[] array2

尝试获取一个函数以使用值填充多个数组。希望能够做到这一点:

public class Demo {
  public static void getData(int[] array1, int[] array2)  {
    array1 = new int[5];
    array2 = new int[5];
  }

  public static void main(String[] args)  {
    int[] array1 = null;
    int[] array2 = null;
    getData(array1, array2); 
    System.out.println(array1[0]); // line 11
  }
}
这会产生一个
NullPointerException
,但我不确定原因。我无法在
main()
中分配数组,因为无法预先知道它们的大小。可以使用
列表
,也可以使用2D数组,但有没有一种方法可以不使用任何一种

array1 = new int[5];
array2 = new int[5];//this will create variable in function body scope
这就是得到空指针的原因

尝试:


您试图实现它的方式在Java中是不可能的

您可以创建一个长度为0的数组:

public void getData(int[] array1, int[] array2)  {
   array1 = new int[5];
   array2 = new int[5];
}
public void main(String[] args)  {
   int[] array1 = new int[0];
   int[] array2 = new int[0];
getData(array1, array2); 
}
// fill array1 and array2 with data

Java总是将引用传递给main中声明的数组,因此不初始化它总是会得到一个NPE。我认为您应该使用List,因为您需要您的方法来定义大小。如果需要将最终输出转换为数组,只需将其转换为数组。

正如其他几位评论员所提到的,这里的问题是误解了按引用传递的概念。在不涉及细节的情况下,根据经验法则,无论何时说
a=…
,其中
a
对象(包括数组),您都会将名称
a
与以前的值断开,并将其指向新值。两者之间没有联系,也无法引用
a
的过去值。因此,在您的情况下,通过将
array1
array2
设置为新值,您不再引用传递到函数中的对象。在本例中,函数参数是
null
,不是实际的对象,但这不会改变这里的任何内容

然而,更重要的问题是如何应对?显然,目前的设计是行不通的,但我们究竟如何才能做到这一点呢?这是一个常见的问题,所以不出所料有很多可行的选择

使用静态变量 这里可以做的最简单的事情就是确保
main()
getData()
都使用相同的变量,通过使用静态类变量,这两种方法都可以引用。虽然对于简单的项目来说很容易,但随着项目的规模和范围越来越大,它很快就会崩溃,并开始引入比它解决的问题更多的问题。小心使用

public class Demo {
  public static void getData(int[] array1, int[] array2)  {
    array1 = new int[5];
    array2 = new int[5];
  }

  public static void main(String[] args)  {
    int[] array1 = null;
    int[] array2 = null;
    getData(array1, array2); 
    System.out.println(array1[0]); // line 11
  }
}
使用专用对象,并传递对该对象的引用 或者,我们可以通过构造单个holder对象并传递对它的引用来避免静态变量。然后,我们可以自由地更改持有者中的实例变量

public class Holder {
  // Should really be private, with constructors/getters/setters
  // but for brevity we'll access them directly here.  Don't
  // take this shortcut in production code
  public int[] array1;
  public int[] array2;
}

public class Demo {
  public static void getData(Holder holder) {
    holder.array1 = new int[5];
    holder.array2 = new int[5];
  }

  public static void main(String[] args)  {
    Holder holder = new Holder();
    getData(holder);
    System.out.println(holder.array1.length+" "+holder.array2.length);
  }
}
使用可调整大小的数据结构 您提到您担心的是您无法提前知道加载数据的大小,这使得它成为
列表
或其他数据结构的完美候选。您还提到您不想这样做,这很好,但请确实确保您确实需要阵列-它们与正确的集合类型相比没有什么好处,而且会带来更多麻烦。使用可调整大小的数据结构,我们可以分别构造和填充同一对象

import java.util.*;

public class Demo {
  public static void getData(List<Integer> ls1, List<Integer> ls2) {
    // bad formatting for brevity, don't do this either
    ls1.add(1); ls1.add(2); ls1.add(3); ls1.add(4); ls1.add(5); 
    ls2.add(1); ls2.add(2); ls2.add(3); ls2.add(4); ls2.add(5);
  }

  public static void main(String[] args)  {
    List<Integer> ls1 = new ArrayList<>();
    List<Integer> ls2 = new ArrayList<>();
    getData(ls1, ls2);
    System.out.println(ls1.size()+" "+ls2.size());
  }
}

通过使用专用类,我们对调用者隐藏了构建此数据的逻辑。相反,
main()
方法只需构造一个
Data()
对象,并且只需构造一个对象即可信任它现在拥有它所需的所有数据。无需担心引用、数组大小或其他任何问题;所有这些决策都在内部得到正确处理,并隐藏在调用方之外。

发布您看到的实际堆栈跟踪。粘贴的代码不应导致任何类型的
NullPointerException
(尽管它也不会编译,因为
getData()
方法不是
静态的
)@dimo414也不是
main
尽管:)我建议你学习类。@SotiriosDelimanolis touche:)这根本不是一个非常有用的代码片段……请解释这是什么变化。在海报的辩护中,最初的问题没有解释数组是如何使用的,广义地说,使用非空默认值有助于避免NPE。当然,您仍然必须正确使用数组,但这是一个更广泛的问题。精彩的描述,尤其是清晰地分解它。对于像这一个棘手的概念,它是有帮助的(我认为)听到和阅读它解释了几种不同的方式。当你从一个不同的角度攻击它时,你在一个“灯泡”时刻有另一个机会。你的解释(特别是顶部的
a=…
)让我得到了100%的支持。出于某种原因,这种方法奏效了。谢谢你过来。
public class Holder {
  // Should really be private, with constructors/getters/setters
  // but for brevity we'll access them directly here.  Don't
  // take this shortcut in production code
  public int[] array1;
  public int[] array2;
}

public class Demo {
  public static void getData(Holder holder) {
    holder.array1 = new int[5];
    holder.array2 = new int[5];
  }

  public static void main(String[] args)  {
    Holder holder = new Holder();
    getData(holder);
    System.out.println(holder.array1.length+" "+holder.array2.length);
  }
}
import java.util.*;

public class Demo {
  public static void getData(List<Integer> ls1, List<Integer> ls2) {
    // bad formatting for brevity, don't do this either
    ls1.add(1); ls1.add(2); ls1.add(3); ls1.add(4); ls1.add(5); 
    ls2.add(1); ls2.add(2); ls2.add(3); ls2.add(4); ls2.add(5);
  }

  public static void main(String[] args)  {
    List<Integer> ls1 = new ArrayList<>();
    List<Integer> ls2 = new ArrayList<>();
    getData(ls1, ls2);
    System.out.println(ls1.size()+" "+ls2.size());
  }
}
public class Data {
  // Again, getters/setters, but at least these are final, that's an improvement
  public final int[] array1;
  public final int[] array2;

  public Data() {
    array1 = new int[5];
    array2 = new int[5];
  }
}

public class Demo {
  public static void main(String[] args)  {
    Data data = new Data();
    System.out.println(data.array1.length+" "+data.array2.length);
  }
}