Jak utworzyć tablicę generyczną w Javie?

Ze względu na implementację Javy generics, nie można mieć takiego kodu:

public class GenSet<E> {
    private E a[];

    public GenSet() {
        a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array creation
    }
}

Jak mogę to zaimplementować przy zachowaniu bezpieczeństwa typu?

Widziałem na forach Java rozwiązanie, które wygląda tak:

import java.lang.reflect.Array;

class Stack<T> {
    public Stack(Class<T> clazz, int capacity) {
        array = (T[])Array.newInstance(clazz, capacity);
    }

    private final T[] array;
}
Ale naprawdę nie rozumiem, o co chodzi.
Author: Cœur, 2009-02-09

29 answers

Muszę zadać pytanie w zamian: czy Twój GenSet jest "sprawdzony " czy"niezaznaczony"? Co to znaczy?

  • Sprawdzone przez: mocne typowanie . {[3] } zna jawnie, jakiego typu obiekty zawiera (tzn. jego konstruktor został wywołany jawnie z argumentem Class<E>, a metody rzucą wyjątek, gdy zostaną przekazane argumenty, które nie są typu E. Zobacz też Collections.checkedCollection.

    - > W takim przypadku należy napisz:

    public class GenSet<E> {
    
        private E[] a;
    
        public GenSet(Class<E> c, int s) {
            // Use Array native method to create array
            // of a type only known at run time
            @SuppressWarnings("unchecked")
            final E[] a = (E[]) Array.newInstance(c, s);
            this.a = a;
        }
    
        E get(int i) {
            return a[i];
        }
    }
    
  • Unchecked: słabe typowanie . Żadne sprawdzanie typu nie jest wykonywane na żadnym z obiektów przekazywanych jako argument.

    - > W takim przypadku powinieneś napisać

    public class GenSet<E> {
    
        private Object[] a;
    
        public GenSet(int s) {
            a = new Object[s];
        }
    
        E get(int i) {
            @SuppressWarnings("unchecked")
            final E e = (E) a[i];
            return e;
        }
    }
    

    Zauważ, że typ składowej tablicy powinien być wymazywanie parametr typu:

    public class GenSet<E extends Foo> { // E has an upper bound of Foo
    
        private Foo[] a; // E erases to Foo, so use Foo[]
    
        public GenSet(int s) {
            a = new Foo[s];
        }
    
        ...
    }
    

Wszystko to wynika ze znanej i celowej słabości generyków w Javie: został zaimplementowany przy użyciu erasure, więc " generic" klasy nie wiedzą, z jakim argumentem typu zostały utworzone w czasie wykonywania i dlatego nie mogą zapewnić bezpieczeństwa typu, chyba że zaimplementowano jakiś jawny mechanizm (sprawdzanie typu).

 593
Author: Varkhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-06 04:19:53

Zawsze możesz to zrobić:

E[] arr = (E[])new Object[INITIAL_ARRAY_LENGTH];

Jest to jeden z sugerowanych sposobów implementacji zbioru generycznego w efektywnej Javie; pozycja 26 . Brak błędów typu, nie ma potrzeby wielokrotnego rzucania tablicy. jednakże to powoduje Ostrzeżenie, ponieważ jest potencjalnie niebezpieczne i powinno być używane z ostrożnością. Jak szczegółowo opisano w komentarzach, ten Object[] jest teraz maskowany jako nasz typ E[] i może powodować nieoczekiwane błędy lub ClassCastException s, jeśli zostanie użyty niewłaściwie.

Jako zasada, to zachowanie jest bezpieczne, o ile tablica cast jest używana wewnętrznie (np. do tworzenia kopii zapasowych struktury danych) i nie jest zwracana ani wystawiana na działanie kodu klienta. Jeśli musisz zwrócić tablicę typu generycznego do innego kodu, Klasa reflection Array, o której wspominasz, jest właściwą drogą.


Warto wspomnieć, że jeśli to możliwe, będziesz miał dużo szczęśliwszy czas pracy z Lists, a nie tablicami, jeśli używasz leków generycznych. Z pewnością czasami nie masz wyboru, ale korzystając z struktura kolekcji jest znacznie bardziej wytrzymała.

 167
Author: dimo414,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-31 00:12:32

Oto jak użyć generyków, aby uzyskać tablicę dokładnie tego typu, którego szukasz, zachowując bezpieczeństwo typów (w przeciwieństwie do innych odpowiedzi, które zwrócą tablicę Object lub spowodują ostrzeżenia podczas kompilacji):

import java.lang.reflect.Array;  

public class GenSet<E> {  
    private E[] a;  

    public GenSet(Class<E[]> clazz, int length) {  
        a = clazz.cast(Array.newInstance(clazz.getComponentType(), length));  
    }  

    public static void main(String[] args) {  
        GenSet<String> foo = new GenSet<String>(String[].class, 1);  
        String[] bar = foo.a;  
        foo.a[0] = "xyzzy";  
        String baz = foo.a[0];  
    }  
}

, który kompiluje się bez ostrzeżeń i jak widać w main, dla dowolnego typu zadeklarowanego jako instancja GenSet, możesz przypisać a do tablicy tego typu, A element z a do zmiennej tego typu, co oznacza, że tablica i wartości w tablicy są odpowiedniego typu.

Działa poprzez użycie liter klas jako tokenów typu runtime, jak opisano w samouczkach Java. Literały klas są traktowane przez kompilator jako instancje java.lang.Class. Aby go użyć, po prostu wykonaj nazwę klasy za pomocą .class. Tak więc String.class działa jako Class obiekt reprezentujący klasę String. Działa to również dla interfejsów, enum, tablic dowolnych wymiarów (np. String[].class), prymitywów (np. int.class) i słowo kluczowe void (tj. void.class).

Class jest to typ ogólny (deklarowany jako Class<T>, gdzie {[19] } oznacza typ, który reprezentuje obiekt Class), co oznacza, że typ String.class to Class<String>.

Tak więc, za każdym razem, gdy wywołujesz konstruktor dla GenSet, przekazujesz w klasie literał dla pierwszego argumentu reprezentującego tablicę zadeklarowanego typu instancji GenSet (np. String[].class dla GenSet<String>). Zauważ, że nie będziesz w stanie uzyskać tablicy prymitywów, ponieważ prymitywy nie mogą być używane dla zmiennych typu.

Wewnątrz konstruktora wywołanie metody cast zwraca przekazany argument Object oddany do klasy reprezentowanej przez obiekt Class, w którym metoda została wywołana. Wywołanie metody statycznej newInstance w java.lang.reflect.Array zwraca jako Object tablicę typu reprezentowanego przez obiekt Class przekazany jako pierwszy argument i o długości określonej przez int przekazany jako drugi argument. Wywołanie metody getComponentType zwraca obiekt Class reprezentujący komponent typ tablicy reprezentowanej przez obiekt Class, na którym została wywołana metoda (np. String.class dla String[].class, null jeśli obiekt Class nie reprezentuje tablicy).

To ostatnie zdanie nie jest do końca dokładne. Wywołanie String[].class.getComponentType() zwraca Class obiekt reprezentujący klasę String, ale jej typem jest Class<?>, a nie Class<String>, dlatego nie można wykonać czegoś takiego jak poniżej.
String foo = String[].class.getComponentType().cast("bar"); // won't compile

To samo dotyczy każdej metody w Class, która zwraca obiekt Class.

Odnośnie Komentarz Joachima Sauera do ta odpowiedź (Nie mam wystarczającej reputacji, aby sam ją skomentować), przykład użycia cast do T[] spowoduje Ostrzeżenie, ponieważ kompilator nie może zagwarantować bezpieczeństwa typu w tym przypadku.


Edytuj komentarze Ingo:

public static <T> T[] newArray(Class<T[]> type, int size) {
   return type.cast(Array.newInstance(type.getComponentType(), size));
}
 56
Author: gdejohn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:45

Jest to jedyna odpowiedź, która jest typu safe

E[] a;

a = newArray(size);

@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
    return Arrays.copyOf(array, length);
}
 34
Author: irreputable,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-06 04:11:51

Aby rozszerzyć na więcej wymiarów, wystarczy dodać [] ' s i parametry wymiarów do newInstance() (T jest parametrem typu, cls jest Class<T>, d1 przez d5 są liczbami całkowitymi):

T[] array = (T[])Array.newInstance(cls, d1);
T[][] array = (T[][])Array.newInstance(cls, d1, d2);
T[][][] array = (T[][][])Array.newInstance(cls, d1, d2, d3);
T[][][][] array = (T[][][][])Array.newInstance(cls, d1, d2, d3, d4);
T[][][][][] array = (T[][][][][])Array.newInstance(cls, d1, d2, d3, d4, d5);

Zobacz Array.newInstance() Po szczegóły.

 27
Author: Jason C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-12 18:55:29

W Javie 8, możemy wykonać rodzaj generycznego tworzenia tablic przy użyciu referencji lambda lub metody. Jest to podobne do podejścia refleksyjnego (które przechodzi Class), ale tutaj nie używamy refleksji.

@FunctionalInterface
interface ArraySupplier<E> {
    E[] get(int length);
}

class GenericSet<E> {
    private final ArraySupplier<E> supplier;
    private E[] array;

    GenericSet(ArraySupplier<E> supplier) {
        this.supplier = supplier;
        this.array    = supplier.get(10);
    }

    public static void main(String[] args) {
        GenericSet<String> ofString =
            new GenericSet<>(String[]::new);
        GenericSet<Double> ofDouble =
            new GenericSet<>(Double[]::new);
    }
}

Na przykład, jest to używane przez <A> A[] Stream.toArray(IntFunction<A[]>).

To może być również wykonane przed Java 8 przy użyciu anonimowych klas, ale jest to bardziej uciążliwe.

 11
Author: Radiodef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-05 01:17:05

Jest to omówione w rozdziale 5 (Generics) Effective Java, 2nd Edition , poz. 25...preferuj listy od tablic

Twój kod będzie działał, chociaż wygeneruje niezaznaczone Ostrzeżenie (które możesz stłumić za pomocą następującej adnotacji:

@SuppressWarnings({"unchecked"})

Jednak prawdopodobnie lepiej byłoby użyć listy zamiast tablicy.

Na stronie projektu OpenJDK jest ciekawa dyskusja na temat tego błędu/funkcji.

 10
Author: Jeff Olson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-29 16:56:59

Generyki Javy działają poprzez sprawdzanie typów w czasie kompilacji i wstawianie odpowiednich odlewów, ale wymazywanie typów w skompilowanych plikach. To sprawia, że biblioteki generyczne są użyteczne przez kod, który nie rozumie generycznych (co było celową decyzją projektową), ale co oznacza, że zwykle nie możesz dowiedzieć się, jaki jest typ w czasie uruchamiania.

Publiczny konstruktor Stack(Class<T> clazz,int capacity) wymaga przekazania obiektu klasy w czasie wykonywania, co oznacza, że informacja o klasie jest dostępna w czasie wykonywania do kod, który tego potrzebuje. A forma Class<T> oznacza, że kompilator sprawdzi, czy przekazany obiekt klasy jest dokładnie obiektem klasy dla typu T. nie jest podklasą T, nie superklasą T, ale dokładnie T.

Oznacza to, że można utworzyć obiekt array odpowiedniego typu w konstruktorze, co oznacza, że typ obiektów przechowywanych w kolekcji będzie sprawdzany w momencie ich dodania do kolekcji.

 7
Author: Bill Michell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-11 10:07:35

Cześć chociaż wątek jest martwy, chciałbym zwrócić na to uwagę:

Generics jest używany do sprawdzania typu podczas kompilacji:

  • dlatego celem jest sprawdzenie, czy to, co przychodzi, jest tym, czego potrzebujesz.
  • To, co zwracasz, jest tym, czego potrzebuje konsument.
  • Sprawdź to:

Tutaj wpisz opis obrazka

Nie martw się o Ostrzeżenia typu podczas pisania klasy generycznej. Martw się, gdy go używasz.

 6
Author: puneeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-08 10:56:23

Co z tym rozwiązaniem?

@SafeVarargs
public static <T> T[] toGenericArray(T ... elems) {
    return elems;
}
To działa i wygląda zbyt prosto, aby było prawdziwe. Czy jest jakaś wada?
 5
Author: Benjamin M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-21 01:28:56

Zobacz też:

public static <T> T[] toArray(final List<T> obj) {
    if (obj == null || obj.isEmpty()) {
        return null;
    }
    final T t = obj.get(0);
    final T[] res = (T[]) Array.newInstance(t.getClass(), obj.size());
    for (int i = 0; i < obj.size(); i++) {
        res[i] = obj.get(i);
    }
    return res;
}

Konwertuje listę dowolnego rodzaju obiektów na tablicę tego samego typu.

 4
Author: MatheusJardimB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-08 23:32:27

Znalazłem szybki i łatwy sposób, który działa dla mnie. Zauważ, że używałem tego tylko w Java JDK 8. Nie wiem czy będzie działać z poprzednimi wersjami.

Chociaż nie możemy utworzyć instancji tablicy generycznej określonego parametru typu, możemy przekazać już utworzoną tablicę do konstruktora klasy generycznej.

class GenArray <T> {
    private T theArray[]; // reference array

    // ...

    GenArray(T[] arr) {
        theArray = arr;
    }

    // Do whatever with the array...
}

Teraz w main możemy utworzyć tablicę TAK:

class GenArrayDemo {
    public static void main(String[] args) {
        int size = 10; // array size
        // Here we can instantiate the array of the type we want, say Character (no primitive types allowed in generics)
        Character[] ar = new Character[size];

        GenArray<Character> = new Character<>(ar); // create the generic Array

        // ...

    }
}

Aby uzyskać większą elastyczność z tablicami, możesz użyć listy połączonej np. ArrayList i inne metody znalezione na jawie.util.Klasy ArrayList.

 4
Author: Nik-Lz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-09 20:43:28

Przykładem jest użycie Java reflection do utworzenia tablicy. Robienie tego na ogół nie jest zalecane, ponieważ nie jest to bezpieczne. Zamiast tego powinieneś użyć wewnętrznej listy i w ogóle unikać tablicy.

 3
Author: Ola Bini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-09 17:33:58

Zrobiłem ten fragment kodu, aby odtworzyć instancję klasy, która jest przekazywana do prostego automatycznego narzędzia testowego.

Object attributeValue = null;
try {
    if(clazz.isArray()){
        Class<?> arrayType = clazz.getComponentType();
        attributeValue = Array.newInstance(arrayType, 0);
    }
    else if(!clazz.isInterface()){
        attributeValue = BeanUtils.instantiateClass(clazz);
    }
} catch (Exception e) {
    logger.debug("Cannot instanciate \"{}\"", new Object[]{clazz});
}

Zwróć uwagę na ten segment:

    if(clazz.isArray()){
        Class<?> arrayType = clazz.getComponentType();
        attributeValue = Array.newInstance(arrayType, 0);
    }

Dla tablicy inicjującej gdzie tablica.newInstance (class of array, size of array) . Klasa może być zarówno prymitywna (int.class) i object (Integer.klasy).

Fasola jest częścią Wiosny.
 3
Author: Bobster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-31 10:39:28

Nie musisz przekazywać argumentu klasy konstruktorowi. Spróbuj tego.

static class GenSet<T> {
    private final T[] array;
    @SuppressWarnings("unchecked")
    public GenSet(int capacity, T... dummy) {
        if (dummy.length > 0)
            throw new IllegalArgumentException(
              "Do not provide values for dummy argument.");
        Class<?> c = dummy.getClass().getComponentType();
        array = (T[])Array.newInstance(c, capacity);
    }
    @Override
    public String toString() {
        return "GenSet of " + array.getClass().getComponentType().getName()
            + "[" + array.length + "]";
    }
}

I

GenSet<Integer> intSet = new GenSet<>(3);
System.out.println(intSet);
System.out.println(new GenSet<String>(2));

Wynik:

GenSet of java.lang.Integer[3]
GenSet of java.lang.String[2]
 3
Author: saka1029,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 05:31:38

W rzeczywistości łatwiejszym sposobem na to jest utworzenie tablicy obiektów i oddanie jej do żądanego typu, jak w poniższym przykładzie:

T[] array = (T[])new Object[SIZE];

Gdzie SIZE jest stałą i {[2] } jest identyfikatorem typu

 2
Author: Pedram Esmaeeli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-12 09:53:54

Przekazywanie listy wartości...

public <T> T[] array(T... values) {
    return values;
}
 2
Author: Rodrigo Asensio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-15 10:19:41

Wymuszona Obsada sugerowana przez innych ludzi nie sprawdziła się dla mnie, rzucając wyjątek od nielegalnego castingu.

Jednak ta ukryta Obsada działała dobrze:

Item<K>[] array = new Item[SIZE];

Gdzie element jest klasą zdefiniowaną i zawierającą element:

private K value;

W ten sposób otrzymasz tablicę typu K (jeżeli element ma tylko wartość) lub dowolnego typu ogólnego, który chcesz zdefiniować w elemencie klasy.

 1
Author: vnportnoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-14 21:26:33

Nikt inny nie odpowiedział na pytanie, co się dzieje w zamieszczonym przez Ciebie przykładzie.

import java.lang.reflect.Array;

class Stack<T> {
    public Stack(Class<T> clazz, int capacity) {
        array = (T[])Array.newInstance(clazz, capacity);
    }

    private final T[] array;
}

Jak mówili inni, generyki są "kasowane" podczas kompilacji. Tak więc w czasie wykonywania instancja generyczna nie wie, jaki jest jej typ komponentu. Powód tego jest historyczny, Sun chciał dodać generyki bez naruszania istniejącego interfejsu (zarówno źródłowego, jak i binarnego).

Tablice natomiast znają swój typ komponentu w czasie wykonywania.

Ten przykład działa wokół problemu poprzez kod, który wywołuje konstruktor (który zna Typ) przekazuje parametr mówiący klasie wymagany typ.

Więc aplikacja skonstruowałaby klasę z czymś w rodzaju

Stack<foo> = new Stack<foo>(foo.class,50)

I konstruktor wie teraz (w czasie wykonywania), jaki jest typ komponentu i może użyć tych informacji do skonstruowania tablicy poprzez API reflection.

Array.newInstance(clazz, capacity);

Wreszcie mamy Typ cast, ponieważ kompilator nie ma możliwości dowiedzenia się, że tablica zwracany przez Array#newInstance() jest prawidłowym typem (chociaż wiemy).

Ten styl jest trochę brzydki, ale czasami może być najmniej złym rozwiązaniem dla tworzenia typów generycznych, które muszą znać swój typ komponentu w czasie wykonywania z jakiegokolwiek powodu (tworzenie tablic lub tworzenie instancji ich typu komponentu, itp.).

 1
Author: plugwash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-18 14:54:58

Znalazłem coś w rodzaju pracy wokół tego problemu.

Poniższy wiersz wyświetla błąd tworzenia ogólnej tablicy

List<Person>[] personLists=new ArrayList<Person>()[10];

Jeśli jednak zamknę List<Person> w oddzielnej klasie, to zadziała.

import java.util.ArrayList;
import java.util.List;


public class PersonList {

    List<Person> people;

    public PersonList()
    {
        people=new ArrayList<Person>();
    }
}

Możesz ujawnić ludzi z listy osób klasowych przez gettera. Poniższy wiersz da ci tablicę, która ma List<Person> w każdym elemencie. Innymi słowy tablica List<Person>.

PersonList[] personLists=new PersonList[10];

Potrzebowałem czegoś takiego w jakimś kodzie, nad którym pracowałem i właśnie to zrobiłem, aby go dostać praca. Jak na razie żadnych problemów.

 1
Author: developer747,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-19 12:57:33

Można utworzyć tablicę obiektów i wrzucić ją do e wszędzie. Tak, to nie jest zbyt czysty sposób, ale przynajmniej powinien zadziałać.

 0
Author: Esko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-09 17:46:55

Spróbuj tego.

private int m = 0;
private int n = 0;
private Element<T>[][] elements = null;

public MatrixData(int m, int n)
{
    this.m = m;
    this.n = n;

    this.elements = new Element[m][n];
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            this.elements[i][j] = new Element<T>();
        }
    }
}
 0
Author: David Bernard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-13 20:37:34

Łatwe, choć niechlujne obejście tego problemu polegałoby na zagnieżdżeniu drugiej klasy "posiadacza" wewnątrz głównej klasy i użyciu jej do przechowywania danych.

public class Whatever<Thing>{
    private class Holder<OtherThing>{
        OtherThing thing;
    }
    public Holder<Thing>[] arrayOfHolders = new Holder<Thing>[10]
}
 0
Author: StarMonkey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-05 00:10:45

Może niezwiązane z tym pytaniem, ale podczas gdy otrzymywałem błąd "generic array creation " za użycie

Tuple<Long,String>[] tupleArray = new Tuple<Long,String>[10];

Z@SuppressWarnings({"unchecked"}) poznaję następujące prace (i pracowały dla mnie):

 Tuple<Long, String>[] tupleArray = new Tuple[10];
 0
Author: Mohsen Afshin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-21 16:11:35

Zastanawiam się, czy ten kod stworzy efektywną tablicę generyczną?

public T [] createArray(int desiredSize){
    ArrayList<T> builder = new ArrayList<T>();
    for(int x=0;x<desiredSize;x++){
        builder.add(null);
    }
    return builder.toArray(zeroArray());
}

//zeroArray should, in theory, create a zero-sized array of T
//when it is not given any parameters.

private T [] zeroArray(T... i){
    return i;
}

Edit: być może alternatywnym sposobem utworzenia takiej tablicy, jeśli wymagany rozmiar byłby znany i mały, byłoby po prostu podanie wymaganej liczby "null" do polecenia zeroArray?

Choć oczywiście nie jest to tak wszechstronne jak użycie kodu createArray.

 0
Author: Cambot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-09 13:36:35

Przydałby się gips:

public class GenSet<Item> {
    private Item[] a;

    public GenSet(int s) {
        a = (Item[]) new Object[s];
    }
}
 0
Author: samir benzenine,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-15 17:23:32

Znalazłem dość unikalne rozwiązanie, aby ominąć niemożność zainicjowania tablicy generycznej. Co musisz zrobić, to utworzyć klasę, która przyjmuje zmienną ogólną T w następujący sposób:

class GenericInvoker <T> {
    T variable;
    public GenericInvoker(T variable){
        this.variable = variable;
    }
}

I wtedy w twojej klasie tablicy po prostu zacznij Tak:

GenericInvoker<T>[] array;
public MyArray(){
    array = new GenericInvoker[];
}

Uruchomienie new Generic Invoker[] spowoduje problem z niezaznaczonym, ale w rzeczywistości nie powinno być żadnych problemów.

Aby uzyskać z tablicy należy wywołać tablicę [i].zmienna Tak:

public T get(int index){
    return array[index].variable;
}

Reszta, jak zmiana rozmiaru tablicy może być wykonywana za pomocą tablic.copyOf () like so:

public void resize(int newSize){
    array = Arrays.copyOf(array, newSize);
}

I funkcję add można dodać Tak:

public boolean add(T element){
    // the variable size below is equal to how many times the add function has been called 
    // and is used to keep track of where to put the next variable in the array
    arrays[size] = new GenericInvoker(element);
    size++;
}
 0
Author: Crab Nebula,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-28 19:59:53
private E a[];
private int size;

public GenSet(int elem)
{
    size = elem;
    a = (E[]) new E[size];
}
 -1
Author: Zubair Ibrhaim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-03 06:16:21

Tworzenie generycznych tablic jest niedozwolone w Javie, ale można to zrobić tak:

class Stack<T> {
private final T[] array;
public Stack(int capacity) {
    array = (T[]) new Object[capacity];
 }
}
 -2
Author: Irfan Ul Haq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-19 13:45:59