Tạo một mảng các đối tượng trong Java


196

Tôi chưa quen với Java và đã tạo ra một loạt các đối tượng trong Java.

Tôi có một lớp A chẳng hạn -

A[] arr = new A[4];

Nhưng đây chỉ là tạo con trỏ (tham chiếu) cho Achứ không phải 4 đối tượng. Điều này có đúng không? Tôi thấy rằng khi tôi cố gắng truy cập các hàm / biến trong các đối tượng được tạo, tôi nhận được một ngoại lệ con trỏ null. Để có thể thao tác / truy cập các đối tượng tôi phải làm điều này:

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

Điều này đúng hay tôi đang làm gì đó sai? Nếu điều này là chính xác, nó thực sự kỳ lạ.

EDIT: Tôi thấy điều này kỳ lạ bởi vì trong C ++, bạn chỉ cần nói mới A[4]và nó tạo ra bốn đối tượng.


17
Tôi chỉ muốn nói rằng đây là một câu hỏi đặc biệt hữu ích; cảm ơn đã hỏi nó
đại dịch

Câu trả lời:


262

Chính xác.

A[] a = new A[4];

... Tạo 4 Atài liệu tham khảo, tương tự như làm điều này:

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

Bây giờ bạn không thể làm a1.someMethod()mà không phân bổ a1như thế này:

a1 = new A();

Tương tự, với mảng bạn cần làm điều này:

a[0] = new A();

... Trước khi sử dụng nó.


10
Câu trả lời này đã cứu tôi cả đống nhầm lẫn, cảm ơn vì sự tồn tại của nó.
đại dịch

1
Tôi cũng có sự nhầm lẫn này, vì tôi đến từ nền C ++, tôi luôn cho rằng giống như trong newtừ khóa của C ++ Java cũng gọi hàm tạo và phân bổ bộ nhớ I. Tôi đoán trong Java newchỉ tạo các tham chiếu chứ không phải đối tượng thực tế so với C ++. Cảm ơn về câu trả lời.
Krishna Oza

1
@Krishna_Oza, không có sự khác biệt so với C ++ ở đây. Việc đầu tiên newtạo ra một đối tượng mảng. Đây là những đối tượng được phân bổ động ("heap"). Vì vậy, mã C ++ tương tự sẽ là A **a = new A*[4]; for (int i = 0; i < 4; ++i) { a[i] = new A(); }.
Vsevolod Golovanov

1
Tôi nhận được rằng các tham chiếu mới tạo ra, nhưng tại sao không khởi tạo các hàm tạo cho từng thành phần của mảng như trong C ++. Điều này có thể là ngớ ngẩn, nhưng tôi muốn hỏi, bất kỳ vấn đề nào chúng ta sẽ có, nếu chúng ta làm điều đó ?? @MeBigFatGuy
Jasser

2
@ Jasser - hàm tạo nào cho các phần tử bạn sẽ gọi? Điều gì xảy ra nếu hàm tạo phần tử duy nhất có một loạt các đối số? Làm thế nào bạn sẽ tạo ra những đối tượng?
MeBigFatGuy

77

Chính xác. Bạn cũng có thể làm:

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

Cú pháp này cũng có thể được sử dụng để tạo và khởi tạo một mảng ở bất cứ đâu, chẳng hạn như trong một đối số phương thức:

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

34

Có, nó chỉ tạo các tham chiếu, được đặt thành giá trị mặc định null. Đó là lý do tại sao bạn nhận được một NullPulumException Bạn cần tạo các đối tượng riêng biệt và gán tham chiếu. Có 3 bước để tạo mảng trong Java -

Khai báo - Trong bước này, chúng tôi chỉ định kiểu dữ liệu và kích thước của mảng mà chúng tôi sẽ tạo. Nhưng hãy nhớ rằng, chúng tôi chưa đề cập đến kích thước của kích thước nào. Họ bị bỏ trống.

Khởi tạo - Trong bước này, chúng tôi tạo mảng hoặc phân bổ bộ nhớ cho mảng, sử dụng từ khóa mới. Trong bước này, chúng tôi đề cập đến kích thước của kích thước mảng.

Khởi tạo - Mảng luôn được khởi tạo thành giá trị mặc định của kiểu dữ liệu. Nhưng chúng ta có thể tự khởi tạo.

Khai báo mảng trong Java

Đây là cách chúng tôi khai báo mảng một chiều trong Java -

int[] array;
int array[];

Oracle khuyên bạn nên sử dụng cú pháp cũ để khai báo mảng. Dưới đây là một số ví dụ khác về tuyên bố pháp lý -

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

Và đây là một số ví dụ về tuyên bố bất hợp pháp -

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

Khởi tạo

Đây là cách chúng tôi khởi tạo ngay lập tức, hoặc phân bổ bộ nhớ cho một mảng -

int[] array = new int[5];

Khi JVM gặp newtừ khóa, nó hiểu rằng nó phải phân bổ bộ nhớ cho một cái gì đó. Và bằng cách chỉ định int[5], chúng tôi có nghĩa là chúng tôi muốn có một mảng có intkích thước 5. Vì vậy, JVM tạo bộ nhớ và gán tham chiếu của bộ nhớ mới được phân bổ cho mảng mà một loại tham chiếu của kiểu Edwardint[]

Khởi tạo

Sử dụng vòng lặp - Sử dụng vòng lặp for để khởi tạo các phần tử của một mảng là cách phổ biến nhất để đưa mảng đi. Không cần chạy vòng lặp for nếu bạn định tự gán giá trị mặc định, vì JVM thực hiện điều đó cho bạn.

Tất cả hợp lại thành một..! - Chúng tôi có thể khai báo, khởi tạo và khởi tạo mảng của chúng tôi trong một lần. Đây là cú pháp -

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

Ở đây, chúng tôi không đề cập đến kích thước, vì JVM có thể thấy rằng chúng tôi đang đưa ra 5 giá trị.

Vì vậy, cho đến khi chúng tôi khởi tạo các tài liệu tham khảo vẫn còn trống. Tôi hy vọng câu trả lời của tôi đã giúp bạn ..! :)

Nguồn - Mảng trong Java


5

Dưới đây là ví dụ rõ ràng về việc tạo mảng 10 đối tượng nhân viên, với hàm tạo có tham số:

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);
    }
}

3

Bạn nói đúng. Ngoài ra, nếu chúng ta muốn tạo một mảng có kích thước cụ thể chứa đầy các phần tử được cung cấp bởi một số "nhà máy", vì Java 8 (giới thiệu API luồng ), chúng ta có thể sử dụng lớp lót này:

A[] a = Stream.generate(() -> new A()).limit(4).toArray(A[]::new);
  • Stream.generate(() -> new A())giống như nhà máy cho các phần tử A riêng biệt được tạo theo cách được mô tả bởi lambda, () -> new A()đây là phần thực hiện Supplier<A>- nó mô tả cách mỗi trường hợp A mới được tạo.
  • limit(4)thiết lập số lượng phần tử mà luồng sẽ tạo
  • toArray(A[]::new)(cũng có thể được viết lại dưới dạng toArray(size -> new A[size])) - nó cho phép chúng ta quyết định / mô tả loại mảng sẽ được trả về.

Đối với một số loại nguyên thủy, bạn có thể sử dụng DoubleStream, IntStream, LongStreamtrong đó cung cấp thêm máy phát điện như range rangeClosedvà vài người khác.


0

Đúng, trong Java có một số bước để tạo một mảng các đối tượng:

  1. Khai báo và sau đó khởi tạo (Tạo bộ nhớ để lưu trữ các đối tượng '4'):

    A[ ] arr = new A[4];
  2. Khởi tạo các đối tượng (Trong trường hợp này bạn có thể Khởi tạo 4 đối tượng của lớp A)

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

    hoặc là

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

Bây giờ bạn có thể bắt đầu gọi các phương thức hiện có từ các đối tượng bạn vừa thực hiện, v.v.

Ví dụ:

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

hoặc là

  arr[1].setNumber(x);

0

Đối với lớp chung, cần phải tạo một lớp bao bọc. Ví dụ:

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

kết quả trong: "Không thể tạo một mảng chung"

Sử dụng thay thế:

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

Dòng này có nghĩa là, bạn đang cố gắng tạo một mảng của Bộ, trong đó loại Set là Chuỗi?
sofs1

0

Hình thức genaral để khai báo một mảng mới trong java như sau:

type arrayName[] = new type[numberOfElements];

Trong đó loại là một loại nguyên thủy hoặc Đối tượng. numberOfElementslà số phần tử bạn sẽ lưu trữ trong mảng và giá trị này không thể thay đổi vì Java không hỗ trợ mảng động (nếu bạn cần cấu trúc linh hoạt và động để giữ các đối tượng bạn có thể muốn sử dụng một số bộ sưu tập Java).

Cho phép khởi tạo một mảng để lưu trữ tiền lương của tất cả nhân viên trong một công ty nhỏ gồm 5 người:

int salaries[] = new int[5];

Loại của mảng (trong trường hợp này int) áp dụng cho tất cả các giá trị trong mảng. Bạn không thể trộn các loại trong một mảng.

Bây giờ chúng tôi có mảng lương được khởi tạo, chúng tôi muốn đặt một số giá trị vào đó. Chúng ta có thể làm điều này trong quá trình khởi tạo như thế này:

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

Hoặc để làm điều đó vào một thời điểm sau như thế này:

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

Ví dụ trực quan hơn về tạo mảng: nhập mô tả hình ảnh ở đây

Để tìm hiểu thêm về Mảng, hãy xem hướng dẫn .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.