Створення масиву об’єктів у Java


197

Я новачок у Java і на той час створив масив об’єктів на Java.

У мене, наприклад, клас А -

A[] arr = new A[4];

Але це лише створення покажчиків (посилань) на, Aа не на 4 об’єкти. Це правильно? Я бачу, що коли я намагаюся отримати доступ до функцій / змінних у створених об'єктах, я отримую нульове виключення вказівника. Щоб мати можливість маніпулювати / отримати доступ до об'єктів, я повинен був це зробити:

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

Це правильно чи я роблю щось не так? Якщо це правильно, це дійсно дивно.

EDIT: Я вважаю це дивним, оскільки в C ++ ви просто говорите нове, A[4]і це створює чотири об'єкти.


17
Я просто хотів сказати, що це було надзвичайно корисне питання; дякую за запитання.
пандорім

Відповіді:


262

Це вірно.

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
Ця відповідь врятувала мені цілу купу розгубленості, дякую за існування.
пандорім

1
У мене теж була ця плутанина, оскільки я з C ++, я завжди вважав, що, як і у C ++, newключове слово Java також викликає конструктор і виділяє I пам'ять. Я думаю, що в Java newстворюються лише посилання, а не фактичний об'єкт порівняно з C ++. Дякую за відповідь
Крішна Оза

1
@Krishna_Oza, різниці від C ++ тут ​​немає. Перший newстворює об’єкт масиву. Це динамічно виділені об'єкти ("купи"). Тож аналогічний код C ++ був би A **a = new A*[4]; for (int i = 0; i < 4; ++i) { a[i] = new A(); }.
Всеволод Голованов

1
Я розумію, що нові створюють посилання, але чому б не ініціалізувати конструктор для кожного елемента масиву, як у C ++. Це може бути нерозумно, але я хочу запитати, які б у нас проблеми були, якщо ми це зробимо ?? @MeBigFatGuy
Джассер

2
@Jasser - який конструктор для елементів ви б назвали? Що робити, якщо єдиний конструктор елементів бере купу аргументів? Як би ви створили ці об’єкти?
MeBigFatGuy

78

Це вірно. Ви також можете зробити:

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 кроки -

Декларація - на цьому кроці ми визначаємо тип даних та розміри масиву, який ми збираємося створити. Але пам’ятайте, ми ще не згадуємо розміри розмірів. Вони залишаються порожніми.

Моментальність - на цьому кроці ми створюємо масив або виділяємо пам'ять для масиву, використовуючи нове ключове слово. Саме на цьому кроці ми згадуємо розміри розмірів масиву.

Ініціалізація - масив завжди ініціалізується до типового значення даних. Але ми можемо зробити власні ініціалізації.

Оголошення масивів на 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], ми маємо на увазі, що ми хочемо масив ints, розміром 5. Таким чином, 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);
    }
}

3

Ви праві. Крім цього, якщо ми хочемо створити масив певного розміру, наповнений елементами, наданими деякими "фабриками", оскільки Java 8 (яка вводить API потоку ), ми можемо використовувати цей однолінійний:

A[] a = Stream.generate(() -> new A()).limit(4).toArray(A[]::new);
  • Stream.generate(() -> new A())це як фабрика для окремих елементів A, створена способом, описаним лямбда, () -> new A()що є реалізацією Supplier<A>- вона описує, як слід створювати всі нові екземпляри A
  • limit(4)встановлює кількість елементів, потік яких буде генеруватися
  • toArray(A[]::new)(можна також переписати як toArray(size -> new A[size])) - це дозволяє нам вирішити / описати тип масиву, який слід повернути.

Для деяких примітивних типів , які можна використовувати DoubleStream, IntStream, LongStreamякі додатково забезпечують генератори , як 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];  

Чи означає цей рядок, що ви намагаєтеся створити масив Sets, де тип Set є String?
sofs1

0

Генаральна форма для оголошення нового масиву в java така:

type arrayName[] = new type[numberOfElements];

Де тип - примітивний тип або Об'єкт. numberOfElements- це кількість елементів, які ви будете зберігати в масиві, і це значення не може змінитися, оскільки Java не підтримує динамічні масиви (якщо вам потрібна гнучка та динамічна структура для розміщення об'єктів, можливо, ви хочете використовувати деякі колекції Java).

Дозволяємо ініціалізувати масив для зберігання зарплат усіх працівників у невеликій компанії з 5 чоловік:

int salaries[] = new int[5];

Тип масиву (у цьому випадку int) застосовується до всіх значень масиву. Не можна змішувати типи в одному масиві.

Тепер, коли у нас ініціалізований масив зарплат, ми хочемо внести в нього деякі значення. Ми можемо це зробити або під час ініціалізації так:

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

Або зробити це в більш пізній момент, як це:

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

Більш наочний приклад створення масиву: введіть тут опис зображення

Щоб дізнатися більше про масиви, перегляньте посібник .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.