用Java创建对象数组


202

我是Java的新手,当时我用Java创建了一个对象数组。

例如,我有A类-

A[] arr = new A[4];

但这只是创建指向(引用)的指针,A而不是创建4个对象。它是否正确?我看到当我尝试访问创建的对象中的函数/变量时,出现空指针异常。为了能够操作/访问对象,我必须这样做:

A[] arr = new A[4];
for (int i = 0; i < 4; i++) {
    arr[i] = new A();
}

这是正确的还是我做错了什么?如果这是正确的,那真的很奇怪。

编辑:我觉得这很奇怪,因为在C ++中,您只是说new A[4],它会创建四个对象。


17
我只是想说这是一个非常有用的问题。感谢您的询问。
pandorym

Answers:


266

这是对的。

A[] a = new A[4];

...创建4个A引用,类似于这样做:

A a1;
A a2;
A a3;
A a4;

现在,您不能不这样a1.someMethod()分配a1

a1 = new A();

同样,对于数组,您需要执行以下操作:

a[0] = new A();

...使用之前。


10
这个答案为我省去了一堆混乱,感谢您的存在。
pandorym

1
我也有这种困惑,因为我来自C ++背景,所以我一直以为就像在C ++中一样,Java的new关键字也调用了构造函数并分配了I内存。我猜在Java中new,与C ++相比,它仅创建引用而不是实际对象。感谢您的回答。
克里希纳(Krishna Oza)2015年

1
@Krishna_Oza,这里与C ++没有什么区别。第一个new创建一个数组对象。这些是动态分配的对象(“堆”)。因此类似的C ++代码将是A **a = new A*[4]; for (int i = 0; i < 4; ++i) { a[i] = new A(); }
Vsevolod Golovanov

1
我得到了新的创建引用,但是为什么不像C ++那样还为数组的每个元素初始化构造函数。这可能很愚蠢,但是我想问,如果这样做,我们会遇到什么问题?@MeBigFatGuy
Jasser

3
@Jasser-您将为元素调用什么构造函数?如果唯一的元素构造函数接受一堆参数怎么办?您将如何创建这些对象?
MeBigFatGuy

80

这是对的。您也可以:

A[] a = new A[] { new A("args"), new A("other args"), .. };

此语法还可以用于在任何地方创建和初始化数组,例如在方法参数中:

someMethod( new A[] { new A("args"), new A("other args"), . . } )

35

是的,它仅创建引用,并将其设置为默认值null。这就是为什么要获取NullPointerException的原因,您需要单独创建对象并分配引用。使用Java创建数组需要执行3个步骤-

声明–在此步骤中,我们指定要创建的数组的数据类型和尺寸。但是请记住,我们还没有提到尺寸的大小。他们是空的。

实例化–在此步骤中,我们使用new关键字创建阵列或为阵列分配内存。正是在这一步中,我们提到了数组维度的大小。

初始化–数组总是初始化为数据类型的默认值。但是我们可以进行自己的初始化。

在Java中声明数组

这就是我们在Java中声明一维数组的方式–

int[] array;
int array[];

Oracle建议您使用以前的语法声明数组。这是法律声明的其他示例–

// One Dimensional Arrays
int[] intArray;             // Good
double[] doubleArray;

// One Dimensional Arrays
byte byteArray[];           // Ugly!
long longArray[];

// Two Dimensional Arrays
int[][] int2DArray;         // Good
double[][] double2DArray;

// Two Dimensional Arrays
byte[] byte2DArray[];       // Ugly
long[] long2DArray[];

这些是非法声明的一些例子–

int[5] intArray;       // Don't mention size!
double{} doubleArray;  // Square Brackets please!

实例化

这就是我们“实例化”或为数组分配内存的方式–

int[] array = new int[5];

当JVM遇到new关键字时,它知道必须为某些内容分配内存。通过指定int[5],我们的意思是我们想要一个int大小为5的s数组。因此,JVM创建内存并将新分配的内存的引用分配给类型为“引用”的数组int[]

初始化

使用循环–使用for循环初始化数组的元素是使数组运行的最常见方法。如果您要自己分配默认值,则无需运行for循环,因为JVM会为您完成。

一体..!–我们可以一次性声明,实例化和初始化数组。这是语法–

int[] arr = {1, 2, 3, 4, 5};

在这里,我们没有提及大小,因为JVM可以看到我们给出了5个值。

因此,直到我们实例化引用,该引用保持为空。希望我的回答对您有所帮助。:)

-Java中的数组


5

这是创建包含10个雇员对象的数组的清晰示例,该数组带有一个带参数的构造函数:

public class MainClass
{  
    public static void main(String args[])
    {
        System.out.println("Hello, World!");
        //step1 : first create array of 10 elements that holds object addresses.
        Emp[] employees = new Emp[10];
        //step2 : now create objects in a loop.
        for(int i=0; i<employees.length; i++){
            employees[i] = new Emp(i+1);//this will call constructor.
        }
    }
}

class Emp{
    int eno;
    public Emp(int no){
        eno = no;
        System.out.println("emp constructor called..eno is.."+eno);
    }
}

4

你是对的。除此之外,如果我们要创建特定大小的数组,并填充由某些“工厂”提供的元素,则自Java 8(引入了stream API)以来,我们可以使用以下一种格式:

A[] a = Stream.generate(() -> new A()).limit(4).toArray(A[]::new);
  • Stream.generate(() -> new A())就像以lambda所描述的方式创建的单独A元素的工厂一样,() -> new A()它是实现的Supplier<A>-描述如何创建每个新的A实例。
  • limit(4)设置流将生成的元素数量
  • toArray(A[]::new)(也可以重写为toArray(size -> new A[size]))-它使我们可以决定/描述应返回的数组类型。

对于一些基本类型,你可以使用DoubleStreamIntStreamLongStream其中还提供像发电机range rangeClosed和其他一些。


0

是的,在Java中是正确的,有几个步骤可以创建对象数组:

  1. 声明然后实例化(创建用于存储“ 4”对象的内存):

    A[ ] arr = new A[4];
    
  2. 初始化对象(在这种情况下,您可以初始化4个类A的对象)

    arr[0] = new A();
    arr[1] = new A();
    arr[2] = new A();
    arr[3] = new A();
    

    要么

    for( int i=0; i<4; i++ )
      arr[i] = new A();
    

现在,您可以从刚刚创建的对象等中开始调用现有方法。

例如:

  int x = arr[1].getNumber();

要么

  arr[1].setNumber(x);

0

对于通用类,有必要创建一个包装器类。例如:

Set<String>[] sets = new HashSet<>[10]

结果为:“无法创建通用数组”

改为使用:

        class SetOfS{public Set<String> set = new HashSet<>();}
        SetOfS[] sets = new SetOfS[10];  

这行表示您要创建一个Set数组,其中Set类型为String吗?
sofs1

0

在Java中声明新数组的一般形式如下:

type arrayName[] = new type[numberOfElements];

其中type是原始类型或Object。numberOfElements是要存储到数组中的元素数,并且该值不能更改,因为Java不支持动态数组(如果需要灵活且动态的结构来保存对象,则可能要使用某些Java集合)。

让我们初始化一个数组来存储一个5人的小公司中所有员工的薪水:

int salaries[] = new int[5];

数组的类型(在这种情况下 int)适用于数组中的所有值。您不能在一个数组中混合类型。

现在我们已经初始化了salals数组,我们想在其中添加一些值。我们可以在初始化期间执行以下操作:

int salaries[] = {50000, 75340, 110500, 98270, 39400};

或在以后这样进行:

salaries[0] = 50000;
salaries[1] = 75340;
salaries[2] = 110500;
salaries[3] = 98270;
salaries[4] = 39400;

数组创建的更多直观示例: 在此处输入图片说明

要了解有关数组的更多信息,请查看指南

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.