Co oznacza <T> (nawiasy ostre) w Javie?

139

Obecnie uczę się języka Java i ostatnio zaskoczyły mnie nawiasy ostre (<>). Co dokładnie mają na myśli?

public class Pool<T>{
    public interface PoolFactory<T>{
        public T createObject();
    }
    this.freeObjects = new ArrayList<T>(maxsize)
}

Co to <T>oznacza? Czy to znaczy, że mogę stworzyć obiekt typu T?

Śmiech
źródło
4
Trudno jest przeanalizować twój kod. Na początek nie ma wcięcia, a są dwa otwarte nawiasy klamrowe i tylko jeden zamykający. Czy T createObjectpowinien znajdować się w Pool lub PoolFactory? Gdzie this.freeObjects = ...ma być? Czy to osobny przykład? Posiadanie go tam jest nielegalne; musi znajdować się wewnątrz metody.
mgiuca
Jeśli ktoś szuka informacji o <>(operator diamentu), których można by użyć, List<Integer> list = new ArrayList<>();odwiedź docs.oracle.com/javase/7/docs/technotes/guides/language/… .
Pshemo

Odpowiedzi:

161

<T>jest typem ogólnym i zwykle można go czytać jako „typu T”. To zależy od typu po lewej stronie <>, co to właściwie oznacza.

Nie wiem, co to Poollub a PoolFactory, ale wspomniałeś również ArrayList<T>, że jest to standardowa klasa Java, więc powiem o tym.

Zwykle nie zobaczysz tam litery „T”, zobaczysz inny typ. Więc jeśli widzisz ArrayList<Integer>na przykład, oznacza to „An ArrayListz Integers”. Na przykład wiele klas używa typów ogólnych do ograniczania typu elementów w kontenerze. Innym przykładem jest HashMap<String, Integer>„mapa z Stringkluczami i Integerwartościami”.

Twój przykład puli jest nieco inny, ponieważ definiujesz klasę. W takim przypadku tworzysz klasę, której instancję mógłby ktoś inny utworzyć z określonym typem zamiast T. Na przykład mógłbym utworzyć obiekt typu Pool<String>przy użyciu definicji Twojej klasy. Oznaczałoby to dwie rzeczy:

  • Mój Pool<String>miałby interfejs PoolFactory<String>z createObjectmetodą, która zwraca Strings.
  • Wewnętrznie Pool<String>będzie zawierał ArrayListciąg ciągów znaków.

To świetna wiadomość, ponieważ innym razem mógłbym przyjść i stworzyć taki, Pool<Integer>który używałby tego samego kodu, ale miałbym go Integerwszędzie tam, gdzie widzisz Tw źródle.

mgiuca
źródło
3
Jedno z najlepszych wyjaśnień, jakie do tej pory widziałem :) Bardzo doceniane !.
Suhas Chikkanna
34

To naprawdę proste. To nowa funkcja wprowadzona w J2SE 5 . Określenie nawiasów kątowych po nazwie klasy oznacza, że ​​tworzysz tymczasowy typ danych, który może zawierać dane dowolnego typu.

Przykład:

class A<T>{
    T obj;
    void add(T obj){
        this.obj=obj;
    }
    T get(){
        return obj;
    }
}
public class generics {
    static<E> void print(E[] elements){
        for(E element:elements){
            System.out.println(element);
        }
    }

    public static void main(String[] args) {
        A<String> obj=new A<String>();
        A<Integer> obj1=new A<Integer>();
        obj.add("hello");
        obj1.add(6);
        System.out.println(obj.get());
        System.out.println(obj1.get());

        Integer[] arr={1,3,5,7};
        print(arr);
    }
}

Zamiast tego <T>możesz napisać wszystko i będzie działać w ten sam sposób. Spróbuj napisać <ABC>zamiast <T>.

To tylko dla wygody:

  • <T> jest określany jako dowolny typ
  • <E> jako typ elementu
  • <N> jako typ liczbowy
  • <V> jako wartość
  • <K> jako klucz

Ale możesz nazwać to, co chcesz, to nie ma znaczenia.

Ponadto Integer, String, Booleanetc są wrapper klasy Java, które pomagają w kontroli typów w czasie kompilacji. Na przykład w powyższym kodzie objjest typu String, więc nie możesz dodać do niego żadnego innego typu (spróbuj obj.add(1), wyrzuci błąd). Podobnie obj1jest tego Integertypu, nie możesz dodać do niego żadnego innego typu (spróbuj obj1.add("hello"), będzie błąd).

Ruturaj Mohanty
źródło
23

Jest to związane z rodzajami w java. Jeśli wspomniałem ArrayList<String>, oznacza to, że mogę dodać tylko obiekt typu String do tej ArrayList.

Dwie główne zalety leków generycznych w Javie to:

  1. Zmniejszenie liczby rzutów w programie, a tym samym zmniejszenie liczby potencjalnych błędów w programie.
  2. Poprawa przejrzystości kodu
Paul Bellora
źródło
11

nazywa się typem ogólnym. Możesz utworzyć instancję puli obiektów w następujący sposób:

PoolFactory<Integer> pool = new Pool<Integer>();

Parametr ogólny może być tylko typem referencyjnym. Nie możesz więc używać typów pierwotnych, takich jak int, double, char lub innych typów pierwotnych.

Rafiek
źródło
9

<>służy do wskazania typów ogólnych w Javie.

Tjest parametrem typu w tym przykładzie. I nie: tworzenie instancji jest jedną z niewielu rzeczy, których nie można zrobić T.

Oprócz samouczka, do którego link znajduje się powyżej, FAQ Angeliki Langers Generics jest świetnym źródłem informacji na ten temat.

Joachim Sauer
źródło
8

Klasy ogólne to typ klasy, który podczas tworzenia przyjmuje typ danych jako parametr. Ten parametr typu jest określany za pomocą nawiasów ostrych, a typ może się zmieniać za każdym razem, gdy tworzona jest instancja nowej instancji klasy. Na przykład, stwórzmy ArrayList dla obiektów Pracownika i drugą dla obiektów Firmy

ArrayList<Employee> employees = new ArrayList<Employee>();
ArrayList<Company> companies = new ArrayList<Company>();

Zauważysz, że używamy tej samej klasy ArrayList do tworzenia obu list i przekazujemy typ Pracownik lub Firma za pomocą nawiasów kątowych. Posiadanie jednej klasy ogólnej obsługującej wiele typów danych ogranicza liczbę klas wykonujących podobne zadania. Typy generyczne pomagają również zmniejszyć liczbę błędów, nadając wszystkiemu silny typ, który pomaga kompilatorowi wskazać błędy. Określając typ ArrayList, kompilator zgłosi błąd, jeśli spróbujesz dodać pracownika do listy firmy lub odwrotnie.

Adiii
źródło