Tworzenie tablicy obiektów w Javie

196

Jestem nowy w Javie i na razie stworzyłem tablicę obiektów w Javie.

Mam na przykład klasę A -

A[] arr = new A[4];

Ale to tylko tworzenie wskaźników (referencji), Aa nie 4 obiektów. Czy to jest poprawne? Widzę, że kiedy próbuję uzyskać dostęp do funkcji / zmiennych w utworzonych obiektach, otrzymuję wyjątek wskaźnika zerowego. Aby móc manipulować / uzyskiwać dostęp do obiektów, musiałem to zrobić:

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

Czy to prawda, czy robię coś złego? Jeśli to prawda, to naprawdę dziwne.

EDYCJA: Uważam to za dziwne, ponieważ w C ++ po prostu mówisz nowy A[4]i tworzy on cztery obiekty.

użytkownik220201
źródło
17
Chciałem tylko powiedzieć, że było to wyjątkowo pomocne pytanie; dzięki za pytanie.
pandorym

Odpowiedzi:

262

To jest poprawne.

A[] a = new A[4];

... tworzy 4 Areferencje, podobne do robienia tego:

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

Teraz nie można tego zrobić a1.someMethod()bez przydzielania w a1ten sposób:

a1 = new A();

Podobnie z tablicą musisz to zrobić:

a[0] = new A();

... przed użyciem.

MeBigFatGuy
źródło
10
Ta odpowiedź uratowała mnie od wielu zamieszania, dziękuję za jej istnienie.
pandorym
1
Miałem też to zamieszanie, ponieważ pochodzę z języka C ++, zawsze zakładałem, że podobnie jak w C ++ newsłowo kluczowe Java również wywołuje konstruktor i przydziela pamięć I. Sądzę, że w Javie newtworzy się referencje, a nie rzeczywisty obiekt w porównaniu do C ++. Dziękuję za odpowiedź.
Krishna Oza
1
@Krishna_Oza, tutaj nie ma różnicy od C ++. Pierwszy newtworzy obiekt tablicowy. Są to obiekty przydzielane dynamicznie („kupa”). Zatem analogiczny kod C ++ byłby A **a = new A*[4]; for (int i = 0; i < 4; ++i) { a[i] = new A(); }.
Vsevolod Golovanov
1
Rozumiem, że nowe tworzy odwołania, ale dlaczego nie zainicjować konstruktorów dla każdego elementu tablicy, jak w C ++. To może być głupie, ale chcę zapytać, czy mielibyśmy problemy, gdybyśmy to zrobili? @MeBigFatGuy
Jasser
2
@Jasser - jaki konstruktor elementów nazwałbyś? Co jeśli jedyny konstruktor elementów bierze wiele argumentów? Jak stworzyłbyś te obiekty?
MeBigFatGuy
77

To jest poprawne. Możesz także:

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

Tej składni można również użyć do utworzenia i zainicjowania tablicy w dowolnym miejscu, na przykład w argumencie metody:

someMethod( new A[] { new A("args"), new A("other args"), . . } )
Steve B.
źródło
34

Tak, tworzy tylko odwołania, dla których domyślna wartość to null. Dlatego otrzymujesz wyjątek NullPointerException Musisz utworzyć obiekty osobno i przypisać odwołanie. Istnieją 3 kroki, aby utworzyć tablice w Javie -

Deklaracja - W tym kroku określamy typ danych i wymiary tablicy, którą zamierzamy utworzyć. Pamiętaj jednak, że nie wspominamy jeszcze o rozmiarach. Zostają puste.

Tworzenie instancji - w tym kroku tworzymy tablicę lub przydzielamy pamięć dla tablicy, używając nowego słowa kluczowego. Na tym etapie wspominamy o rozmiarach wymiarów tablicy.

Inicjalizacja - tablica jest zawsze inicjowana do wartości domyślnej typu danych. Ale możemy tworzyć własne inicjalizacje.

Deklarowanie tablic w Javie

W ten sposób deklarujemy jednowymiarową tablicę w Javie -

int[] array;
int array[];

Oracle zaleca stosowanie poprzedniej składni do deklarowania tablic. Oto kilka innych przykładów deklaracji prawnych -

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

Oto niektóre przykłady nielegalnych deklaracji -

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

Instancja

W ten sposób „tworzymy” lub przydzielamy pamięć dla tablicy -

int[] array = new int[5];

Kiedy JVM napotka newsłowo kluczowe, zrozumie, że musi przydzielić pamięć na coś. Określając int[5], mamy na myśli, że chcemy tablicy ints, o rozmiarze 5. Zatem JVM tworzy pamięć i przypisuje odwołanie do nowo przydzielonej pamięci do tablicy, która jest „referencją” typuint[]

Inicjalizacja

Korzystanie z pętli - Użycie pętli for do inicjowania elementów tablicy jest najczęstszym sposobem uruchomienia tablicy. Nie ma potrzeby uruchamiania pętli for, jeśli zamierzasz przypisać samą wartość domyślną, ponieważ JVM robi to za Ciebie.

Wszystko w jednym..! - Możemy zadeklarować, utworzyć i zainicjować naszą tablicę za jednym razem. Oto składnia -

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

Tutaj nie wspominamy o rozmiarze, ponieważ JVM widzi, że podajemy 5 wartości.

Tak więc, dopóki nie utworzymy instancji, referencje pozostają zerowe. Mam nadzieję, że moja odpowiedź pomogła ci ...! :)

Źródło - tablice w Javie

Vamsi Sangam
źródło
5

Oto wyraźny przykład tworzenia tablicy 10 obiektów pracowniczych z konstruktorem, który przyjmuje parametr:

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);
    }
}
użytkownik1923551
źródło
3

Masz rację. Poza tym, jeśli chcemy stworzyć tablicę o określonym rozmiarze, wypełnioną elementami dostarczonymi przez jakąś „fabrykę”, ponieważ Java 8 (która wprowadza API streamu ) możemy użyć tego jednowierszowego:

A[] a = Stream.generate(() -> new A()).limit(4).toArray(A[]::new);
  • Stream.generate(() -> new A())jest jak fabryka dla oddzielnych elementów A utworzonych w sposób opisany przez lambda, () -> new A()czyli implementację Supplier<A>- opisuje, w jaki sposób należy tworzyć nowe instancje A.
  • limit(4)ustawia liczbę elementów, które wygeneruje strumień
  • toArray(A[]::new)(można również przepisać jako toArray(size -> new A[size])) - pozwala nam zdecydować / opisać typ tablicy, którą należy zwrócić.

Dla niektórych prymitywnych typów można użyć DoubleStream, IntStream, LongStreamktóre dodatkowo zapewniają generatorów jak range rangeClosedi kilka innych.

Pshemo
źródło
0

Tak, w Javie jest poprawne. Aby utworzyć tablicę obiektów, należy wykonać kilka kroków:

  1. Deklarowanie, a następnie tworzenie instancji (Utwórz pamięć do przechowywania obiektów „4”):

    A[ ] arr = new A[4];
  2. Inicjalizacja obiektów (w tym przypadku możesz zainicjować 4 obiekty klasy A)

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

    lub

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

Teraz możesz zacząć wywoływać istniejące metody z obiektów, które właśnie stworzyłeś itp.

Na przykład:

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

lub

  arr[1].setNumber(x);
Jeremy Levett
źródło
0

W przypadku klasy ogólnej konieczne jest utworzenie klasy opakowania. Na przykład:

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

skutkuje: „Nie można utworzyć tablicy ogólnej”

Zamiast tego użyj:

        class SetOfS{public Set<String> set = new HashSet<>();}
        SetOfS[] sets = new SetOfS[10];  
SzB
źródło
Czy ta linia oznacza, że ​​próbujesz utworzyć tablicę zestawów, gdzie typem zestawu jest ciąg?
sofs1,
0

Forma genarna do deklarowania nowej tablicy w Javie jest następująca:

type arrayName[] = new type[numberOfElements];

Gdzie typ jest pierwotnym typem lub obiektem. numberOfElementsto liczba elementów, które będziesz przechowywać w tablicy i ta wartość nie może się zmienić, ponieważ Java nie obsługuje tablic dynamicznych (jeśli potrzebujesz elastycznej i dynamicznej struktury do przechowywania obiektów, możesz chcieć użyć niektórych kolekcji Java).

Pozwala zainicjować tablicę do przechowywania wynagrodzeń wszystkich pracowników w małej firmie złożonej z 5 osób:

int salaries[] = new int[5];

Typ tablicy (w tym przypadku int) dotyczy wszystkich wartości w tablicy. Nie można mieszać typów w jednej tablicy.

Po zainicjowaniu tablicy wynagrodzeń chcemy wprowadzić do niej pewne wartości. Możemy to zrobić podczas inicjalizacji w następujący sposób:

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

Lub zrobić to później:

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

Bardziej wizualny przykład tworzenia tablicy: wprowadź opis zdjęcia tutaj

Aby dowiedzieć się więcej o tablicach, sprawdź przewodnik .

Jasio
źródło