Создание массива объектов в 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();
}

Это правильно или я что-то не так делаю? Если это правильно, это действительно странно.

РЕДАКТИРОВАТЬ: я нахожу это странным, потому что в C ++ вы просто говорите новый, A[4]и он создает четыре объекта.

user220201
источник
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();

... перед его использованием.

MeBigFatGuy
источник
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
Я получаю, что new создает ссылки, но почему бы не инициализировать конструктор для каждого элемента массива, как в C ++. Это может быть глупо, но я хочу спросить, есть ли у нас проблемы, если мы это сделаем? @MeBigFatGuy
Jasser
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. Вам нужно создавать объекты отдельно и назначать ссылку. Есть 3 шага для создания массивов в Java -

Объявление - на этом шаге мы указываем тип данных и размеры массива, который мы собираемся создать. Но помните, мы пока не упоминаем размеры размеров. Они оставлены пустыми.

Instantiation - на этом этапе мы создаем массив или выделяем память для массива, используя ключевое слово 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], мы имеем в виду, что нам нужен массив 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);
    }
}
user1923551
источник
3

Ты прав. Помимо этого, если мы хотим создать массив определенного размера, заполненный элементами, предоставленными некоторой «фабрикой», начиная с Java 8 (которая представляет потоковый API ), мы можем использовать эту однострочную строку:

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

Для некоторых примитивных типов , которые можно использовать DoubleStream, IntStream, LongStreamкоторые дополнительно обеспечивают генераторы , как range rangeClosedи некоторые другие.

Pshemo
источник
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];  
SZB
источник
Означает ли эта строка, что вы пытаетесь создать массив множеств, где тип набора - String?
sofs1
0

Общая форма объявления нового массива в Java выглядит следующим образом:

type arrayName[] = new type[numberOfElements];

Где тип - это примитивный тип или объект. numberOfElementsэто количество элементов, которые вы будете хранить в массиве, и это значение не может быть изменено, поскольку Java не поддерживает динамические массивы (если вам нужна гибкая и динамическая структура для хранения объектов, вы можете использовать некоторые из коллекций Java).

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

int salaries[] = new int[5];

Тип массива (в данном случае int) применяется ко всем значениям в массиве. Вы не можете смешивать типы в одном массиве.

Теперь, когда у нас инициализирован массив salaries, мы хотим добавить в него некоторые значения. Мы можем сделать это либо во время инициализации следующим образом:

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

Или сделать это позже, как это:

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

Более наглядный пример создания массива: введите описание изображения здесь

Чтобы узнать больше о массивах, ознакомьтесь с руководством .

Джонни
источник