简体   繁体   English

在 Java 中创建对象数组

[英]Creating an array of objects in Java

I am new to Java and for the time created an array of objects in Java.我是 Java 新手,当时在 Java 中创建了一个对象数组。

I have a class A for example -例如,我有一个 A 类 -

A[] arr = new A[4];

But this is only creating pointers (references) to A and not 4 objects.但这只是创建指向A而不是 4 个对象的指针(引用)。 Is this correct?这样对吗? I see that when I try to access functions/variables in the objects created I get a null pointer exception.我看到当我尝试访问创建的对象中的函数/变量时,我得到了一个空指针异常。 To be able to manipulate/access the objects I had to do this:为了能够操作/访问对象,我必须这样做:

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

Is this correct or am I doing something wrong?这是正确的还是我做错了什么? If this is correct its really odd.如果这是正确的,那真的很奇怪。

EDIT: I find this odd because in C++ you just say new A[4] and it creates the four objects.编辑:我觉得这很奇怪,因为在 C++ 中你只说 new A[4]并且它创建了四个对象。

This is correct.这是对的。

A[] a = new A[4];

...creates 4 A references, similar to doing this: ...创建 4 个A引用,类似于这样做:

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

Now you couldn't do a1.someMethod() without allocating a1 like this:现在你不能在不分配a1情况下执行a1.someMethod() ,如下所示:

a1 = new A();

Similarly, with the array you need to do this:同样,对于数组,您需要这样做:

a[0] = new A();

...before using it. ...在使用之前。

This is correct.这是对的。 You can also do :你也可以这样做:

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

This syntax can also be used to create and initialize an array anywhere, such as in a method argument:此语法还可用于在任何地方创建和初始化数组,例如在方法参数中:

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

Yes, it creates only references, which are set to their default value null.是的,它只创建引用,这些引用被设置为它们的默认值 null。 That is why you get a NullPointerException You need to create objects separately and assign the reference.这就是为什么你得到一个 NullPointerException 你需要单独创建对象并分配引用。 There are 3 steps to create arrays in Java -在 Java 中创建数组有 3 个步骤 -

Declaration – In this step, we specify the data type and the dimensions of the array that we are going to create.声明- 在此步骤中,我们指定要创建的数组的数据类型和维度。 But remember, we don't mention the sizes of dimensions yet.但请记住,我们还没有提到维度的大小。 They are left empty.它们是空的。

Instantiation – In this step, we create the array, or allocate memory for the array, using the new keyword.实例化——在这一步中,我们使用 new 关键字创建数组或为数组分配内存。 It is in this step that we mention the sizes of the array dimensions.在这一步中,我们提到了数组维度的大小。

Initialization – The array is always initialized to the data type's default value.初始化– 数组始终初始化为数据类型的默认值。 But we can make our own initializations.但是我们可以进行自己的初始化。

Declaring Arrays In Java在 Java 中声明数组

This is how we declare a one-dimensional array in Java –这就是我们在 Java 中声明一维数组的方式——

 int[] array; int array[];

Oracle recommends that you use the former syntax for declaring arrays. Oracle 建议您使用前一种语法来声明数组。 Here are some other examples of legal declarations –以下是其他一些法律声明的例子——

 // 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[];

And these are some examples of illegal declarations –这些是一些非法声明的例子——

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

Instantiation实例化

This is how we “instantiate”, or allocate memory for an array –这就是我们“实例化”或为数组分配内存的方式——

 int[] array = new int[5];

When the JVM encounters the new keyword, it understands that it must allocate memory for something.当 JVM 遇到new关键字时,它明白它必须为某些东西分配内存。 And by specifying int[5] , we mean that we want an array of int s, of size 5. So, the JVM creates the memory and assigns the reference of the newly allocated memory to array which a “reference” of type int[]通过指定int[5] ,我们的意思是我们想要一个大小为 5 的int数组。因此,JVM 创建内存并将新分配的内存的引用分配给数组,该数组是int[]类型的“引用” int[]

Initialization初始化

Using a Loop – Using a for loop to initialize elements of an array is the most common way to get the array going.使用循环——使用 for 循环来初始化数组的元素是使数组运行的最常见方法。 There's no need to run a for loop if you are going to assign the default value itself, because JVM does it for you.如果您要自己分配默认值,则无需运行 for 循环,因为 JVM 会为您完成。

All in One..!一体..! – We can Declare, Instantiate and Initialize our array in one go. – 我们可以一次性声明、实例化和初始化我们的数组。 Here's the syntax –这是语法 -

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

Here, we don't mention the size, because JVM can see that we are giving 5 values.在这里,我们没有提到大小,因为JVM可以看到我们给出了5个值。

So, until we instantiate the references remain null.所以,在我们实例化之前,引用保持为空。 I hope my answer has helped you..!希望我的回答对你有帮助..! :) :)

Source - Arrays in Java Source - Java 中的数组

Here is the clear example of creating array of 10 employee objects, with a constructor that takes parameter:这是创建 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);
    }
}

You are correct.你是对的。 Aside from that if we want to create array of specific size filled with elements provided by some "factory", since Java 8 (which introduces stream API ) we can use this one-liner:除此之外,如果我们想创建由某个“工厂”提供的元素填充的特定大小的数组,因为 Java 8(引入了流 API )我们可以使用这个单行:

A[] a = Stream.generate(() -> new A()).limit(4).toArray(A[]::new);
  • Stream.generate(() -> new A()) is like factory for separate A elements created in a way described by lambda, () -> new A() which is implementation of Supplier<A> - it describe how each new A instances should be created. Stream.generate(() -> new A())就像以 lambda 描述的方式创建的单独 A 元素的工厂, () -> new A()这是Supplier<A>实现 - 它描述了每个新元素如何应该创建一个实例。
  • limit(4) sets amount of elements which stream will generate limit(4)设置流将生成的元素数量
  • toArray(A[]::new) (can also be rewritten as toArray(size -> new A[size]) ) - it lets us decide/describe type of array which should be returned. toArray(A[]::new) (也可以改写为toArray(size -> new A[size]) )——它让我们决定/描述应该返回的数组类型。

For some primitive types you can use DoubleStream , IntStream , LongStream which additionally provide generators like range rangeClosed and few others.对于某些原始类型,您可以使用DoubleStreamIntStreamLongStream ,它们还提供诸如range rangeClosed和其他一些生成器。

The genaral form to declare a new array in java is as follows:在java中声明一个新数组的一般形式如下:

type arrayName[] = new type[numberOfElements];

Where type is a primitive type or Object.其中 type 是原始类型或 Object。 numberOfElements is the number of elements you will store into the array and this value can't change because Java does not support dynamic arrays (if you need a flexible and dynamic structure for holding objects you may want to use some of the Java collections). numberOfElements是您将存储到数组中的元素数,该值不能更改,因为 Java 不支持动态数组(如果您需要一个灵活的动态结构来保存对象,您可能希望使用某些 Java 集合)。

Lets initialize an array to store the salaries of all employees in a small company of 5 people:让我们初始化一个数组来存储一家 5 人的小公司中所有员工的工资:

int salaries[] = new int[5];

The type of the array (in this case int ) applies to all values in the array.数组的类型(在本例中为int )适用于数组中的所有值。 You can not mix types in one array.您不能在一个数组中混合类型。

Now that we have our salaries array initialized we want to put some values into it.现在我们已经初始化了salary 数组,我们想将一些值放入其中。 We can do this either during the initialization like this:我们可以在初始化期间这样做:

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

Or to do it at a later point like this:或者稍后再这样做:

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

More visual example of array creation:数组创建的更直观示例: 在此处输入图片说明

To learn more about Arrays, check out the guide .要了解有关数组的更多信息,请查看指南

Yes it is correct in Java there are several steps to make an array of objects:是的,在 Java 中是正确的,有几个步骤可以创建对象数组:

  1. Declaring and then Instantiating (Create memory to store '4' objects):声明然后实例化(创建内存来存储“4”个对象):

     A[ ] arr = new A[4];
  2. Initializing the Objects (In this case you can Initialize 4 objects of class A)初始化对象(在这种情况下,您可以初始化 4 个 A 类对象)

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

    or要么

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

Now you can start calling existing methods from the objects you just made etc.现在您可以开始从您刚刚创建的对象等调用现有方法。

For example:例如:

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

or要么

  arr[1].setNumber(x);

For generic class it is necessary to create a wrapper class.对于泛型类,有必要创建一个包装类。 For Example:例如:

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

results in: "Cannot create a generic array"结果:“无法创建通用数组”

Use instead:改用:

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

Suppose the class A is such:假设A类是这样的:

class A{
int rollno;
int DOB;
}        

and you want to create an array of the objects for the class A. So you do like this,并且你想为 A 类创建一个对象数组。所以你这样做,

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

which is absolutely correct.这是绝对正确的。

Here A is the class and in Statement 1 Class A is a datatype of the array.这里 A 是类,在语句 1 中,A 类是数组的数据类型。 When this statement gets executed because of the new keyword an object is created and dynamically memory is allocated to it which will be equal to the space required for the 4 blocks of datatype A ie, ( for one block in the array space required is 8 bytes (4+4), I am assuming int takes 4 bytes of space. therefore total space allocated is 4*4 bytes for the array ).当由于 new 关键字而执行此语句时,将创建一个对象并为其动态分配内存,这将等于 4 个数据类型 A 块所需的空间,即(对于数组中的一个块,所需空间为 8 个字节(4+4),我假设 int 占用 4 个字节的空间。因此分配的总空间为数组 4*4 个字节)。 Then the reference of the object is given to the arr variable.然后将对象的引用赋予 arr 变量。 Here important point to note is that Statement 1 has nothing to do with creating an object for class A ,no object is created for this class it is only used as a datatype which gives the size of the class A required for the memory allocation of the array.这里需要注意的重要一点是,语句 1 与为 A 类创建对象无关,没有为此类创建对象,它仅用作数据类型,它给出了 A 类内存分配所需的大小大批。

Then when for loop is run and Statement 2 is executed JVM now allocates the memory for the Class A (ie creates an object) and gives its reference to the arr[i].然后,当 for 循环运行并执行语句 2 时,JVM 现在为 A 类分配内存(即创建一个对象)并将其引用提供给 arr[i]。 Every time the loop is called an object is created and the reference of it is given to arr[i].每次调用循环时都会创建一个对象,并将它的引用提供给 arr[i]。

Thus, arr[0] which holds a space of 8 bytes is given the reference of the object of the Class A and everytime loop is run new object is created and reference is given to that object so that it can now access the data in that object .因此,包含 8 个字节空间的 arr[0] 被赋予 A 类对象的引用,每次循环运行时都会创建新对象并赋予该对象引用,以便它现在可以访问该对象中的数据目的 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM