Typ generyczny (ang. generic type, także: typ parametryzowany) – typ zdefiniowany z użyciem jednego lub większej liczby parametrów typu (np. T), które są podstawiane konkretnymi typami w miejscu użycia[1][2][3]; pojęcie z zakresu teorii typów i praktyki projektowania języków programowania, używane w programowaniu generycznym: pozwala opisać jedną strukturę danych lub komponent (np. listę albo mapę) tak, by działał dla różnych rodzajów danych, a konkretny rodzaj wybiera się dopiero w miejscu użycia przez podstawienie parametru typu (np. T)[1][4]. W efekcie ta sama definicja może tworzyć wyspecjalizowane warianty (np. Lista<int> i Lista<string>), bez potrzeby tworzenia osobnych implementacji dla każdego typu elementów[4].
Charakterystyka
edytujTyp generyczny składa się z:
- definicji (np. klasy, interfejsu, typu algebraicznego),
- parametrów typu (np.
T,K,V), - ewentualnych ograniczeń parametrów (np. „
Tmusi implementować dane API” w C#).[5]
W praktyce typy generyczne są często używane do budowy struktur danych (kolekcji) i bibliotek algorytmów, ograniczając potrzebę rzutowań i podnosząc bezpieczeństwo typów.[6]
Związek z polimorfizmem parametrycznym
edytujW ujęciu teorii typów mechanizm typów generycznych jest praktyczną realizacją polimorfizmu parametrycznego (parametric polymorphism), czyli sytuacji, w której funkcja/typ działa jednolicie dla całej rodziny typów wyznaczonej przez parametry typu.[1]
Implementacje w językach programowania
edytujJava
edytujW Javie typy generyczne tworzą typy parametryzowane (np. C<T>)[2][7]. Specyfikacja opisuje m.in. zacieranie typów (ang. type erasure), czyli mapowanie typów parametryzowanych do typów bez parametrów na potrzeby kodu wykonywalnego, oraz rolę typów surowych (ang. raw types) dla zgodności wstecznej[7][6].
List<String> nazwy = new ArrayList<>();
C# i platforma .NET
edytujW C#/.NET typy generyczne są powszechnie stosowane m.in. w bibliotekach kolekcji; dokumentacja podkreśla ich wpływ na wielokrotne użycie kodu, bezpieczeństwo typów i wydajność[3][5][8]. Kompilacja generics do CIL zachowuje informację o parametrach typu w metadanych; zachowanie środowiska uruchomieniowego różni się m.in. dla typów wartościowych i referencyjnych (specjalizacja vs współdzielenie kodu)[9].
var liczby = new List<int> { 1, 2, 3 };
C++
edytujW C++ rolę mechanizmu generycznego pełnią szablony. Jednym z kluczowych przykładów praktycznego zastosowania jest Standard Template Library (STL), opisywana jako zestaw generycznych komponentów C++ przeznaczonych do współpracy w spójny sposób.[10]
template <class T>
struct Box { T value; };
TypeScript
edytujW TypeScript typy generyczne (parametry typu) służą do opisu funkcji, interfejsów i klas działających dla wielu typów danych przy zachowaniu kontroli statycznej (np. Array<T>, Promise<T>)[11]. Ponieważ TypeScript jest transpilowany do JavaScriptu, adnotacje typów (w tym parametry typu) są usuwane w kodzie wynikowym, więc mechanizm generyków działa wyłącznie na etapie kompilacji/sprawdzania typów[12].
function identity<T>(arg: T): T {
return arg;
}
const s = identity<string>("tekst");
Go
edytujW Go mechanizm generyczny (type parameters) wprowadzono w wersji 1.18; obejmuje on m.in. parametry typu dla funkcji i typów oraz ich instancjonowanie[13]. Składnia i reguły semantyczne parametrów typu są opisane w specyfikacji języka; ograniczenia (constraints) wyraża się za pomocą interfejsów (w tym tzw. type sets)[14].
package main
type Number interface {
~int | ~int64 | ~float64
}
func Sum[T Number](xs []T) T {
var s T
for _, v := range xs {
s += v
}
return s
}
Wariancja i (nie)zmienniczość
edytujRelacja podtypów dla typów generycznych zależy od języka i konstrukcji:
- w podejściu „niezmienniczym” (ang. invariance)
Lista<Kot>nie jest podtypemLista<Zwierzę>(nawet jeśliKotjest podtypemZwierzę), co w Javie uzasadniano m.in. zachowaniem bezpieczeństwa typów dla typów parametryzowanych;[6] - platforma .NET rozróżnia także wariancję (kowariancję i kontrawariancję) dla wybranych typów generycznych (np. interfejsów i delegatów), a dokumentacja definiuje pojęcia kowariancji, kontrawariancji i niezmienniczości w kontekście generics.[15]
Zobacz też
edytujPrzypisy
edytuj- ↑ a b c Luca Cardelli; Peter Wegner. On Understanding Types, Data Abstraction, and Polymorphism. „ACM Computing Surveys”. 17 (4), s. 475–478, 1985-12. DOI: 10.1145/6041.6042. [dostęp 2026-01-19]. (ang.).
- ↑ a b Marcin Pietraszek, Typy generyczne w języku Java [online], Samouczek Programisty, 26 marca 2016 [dostęp 2026-01-19].
- ↑ a b C# - typy generyczne - plukasiewicz.net [online], www.plukasiewicz.net [dostęp 2026-01-19].
- ↑ a b Generic classes and methods – C#. Microsoft Learn. [dostęp 2026-01-20]. (ang.).
- ↑ a b Generic classes and methods – C# [online] [dostęp 2026-01-19] (ang.).
- ↑ a b c Gilad Bracha; Martin Odersky; David Stoutamire; Philip Wadler. Making the Future Safe for the Past: Adding Genericity to the Java™ Programming Language. „OOPSLA ’98 (Conference Proceedings)”, s. 183–200, 1998-10. DOI: 10.1145/286942.286957. [dostęp 2026-01-19]. (ang.).
- ↑ a b The Java® Language Specification, Java SE 16 – §4.5 Parameterized Types; §4.6 Type Erasure [online], Oracle Documentation [dostęp 2026-01-19] (ang.).
- ↑ Generic types (generics) overview – .NET [online], Microsoft Learn [dostęp 2026-01-19] (ang.).
- ↑ Generics in the runtime (C# programming guide) [online], Microsoft Learn [dostęp 2026-01-19] (ang.).
- ↑ Alexander A. Stepanov; Meng Lee. The Standard Template Library. „Hewlett-Packard Laboratories Technical Report (HPL-94-34 (R.1))”, s. 4, 1994-04. [dostęp 2026-01-19]. (ang.).
- ↑ Documentation – Generics. TypeScript. [dostęp 2026-01-20]. (ang.).
- ↑ Documentation – The Basics. TypeScript. [dostęp 2026-01-20]. (ang.).
- ↑ Go 1.18 Release Notes. The Go Project. [dostęp 2026-01-20]. (ang.).
- ↑ The Go Programming Language Specification. The Go Project. [dostęp 2026-01-20]. (ang.).
- ↑ Covariance and contravariance in generics – .NET [online], Microsoft Learn [dostęp 2026-01-19] (ang.).