Platforma Java, wersja standardowa

Platforma Java, wersja standardowa ( Java SE ) to platforma obliczeniowa do opracowywania i wdrażania przenośnego kodu dla środowisk komputerów stacjonarnych i serwerów . Java SE była wcześniej znana jako Java 2 Platform, Standard Edition ( J2SE ).

Platforma wykorzystuje język programowania Java i jest częścią rodziny platform oprogramowania Java . Java SE definiuje szereg interfejsów API ogólnego przeznaczenia — takich jak interfejsy API Java dla biblioteki klas Java — a także zawiera specyfikację języka Java i specyfikację maszyny wirtualnej Java . OpenJDK jest oficjalną implementacją referencyjną od wersji 7.

Nazewnictwo, normy i specyfikacje

Platforma była znana jako Java 2 Platform, Standard Edition lub J2SE od wersji 1.2, aż do zmiany nazwy na Java Platform, Standard Edition lub Java SE w wersji 1.5. „SE” służy do odróżnienia platformy podstawowej od platform Enterprise Edition ( Java EE ) i Micro Edition ( Java ME ). „2” pierwotnie miało na celu podkreślenie głównych zmian wprowadzonych w wersji 1.2, ale zostało usunięte w wersji 1.6. Konwencja nazewnictwa była zmieniana kilka razy w historii wersji Java . Począwszy od J2SE 1.4 (Merlin), Java SE była rozwijana w ramach Java Community Process , który tworzy opisy proponowanych i ostatecznych specyfikacji dla platformy Java o nazwie Java Specification Requests (JSR) . JSR 59 był specyfikacją parasolową dla J2SE 1.4, a JSR 176 określił J2SE 5.0 (Tiger). Java SE 6 (Mustang) została wydana pod JSR 270.

Java Platform, Enterprise Edition (Java EE) to pokrewna specyfikacja obejmująca wszystkie klasy Java SE oraz pewną liczbę klas, które są bardziej przydatne w programach działających na serwerach , a nie na stacjach roboczych .

Platforma Java, Micro Edition (Java ME) to powiązana specyfikacja, której celem jest zapewnienie certyfikowanej kolekcji interfejsów API języka Java do tworzenia oprogramowania dla małych urządzeń o ograniczonych zasobach, takich jak telefony komórkowe , urządzenia PDA i dekodery .

Środowisko Java Runtime Environment (JRE) i Java Development Kit (JDK) to rzeczywiste pliki pobierane i instalowane na komputerze w celu odpowiednio uruchamiania lub opracowywania programów Java.

Pakiety ogólnego przeznaczenia

java.lang

Pakiet Java java.lang zawiera podstawowe klasy i interfejsy ściśle powiązane z językiem i systemem wykonawczym . Obejmuje to klasy główne, które tworzą hierarchię klas , typy powiązane z definicją języka, podstawowe wyjątki , funkcje matematyczne, wątki , funkcje bezpieczeństwa, a także niektóre informacje na temat bazowego systemu natywnego. Ten pakiet zawiera 22 z 32 błędów dostępnych w JDK 6.

Główne klasy i interfejsy w java.lang to:

Klasy w java.lang są automatycznie importowane do każdego pliku źródłowego .

java.lang.ref

Pakiet java.lang.ref zapewnia bardziej elastyczne typy odniesień niż te, które są dostępne w inny sposób, umożliwiając ograniczoną interakcję między aplikacją a modułem wyrzucania elementów bezużytecznych Java Virtual Machine (JVM) . Jest to ważny pakiet, wystarczająco centralny dla języka, aby projektanci języków mogli nadać mu nazwę zaczynającą się od „java.lang”, ale ma on nieco specjalnego przeznaczenia i nie jest używany przez wielu programistów. Ten pakiet został dodany w J2SE 1.2.

Java ma ekspresyjny system odniesień i pozwala na specjalne zachowanie przy wyrzucaniu elementów bezużytecznych. Normalne odniesienie w Javie jest znane jako „silne odniesienie”. Pakiet java.lang.ref definiuje trzy inne typy referencji — miękkie, słabe i fantomowe. Każdy typ odniesienia jest przeznaczony do określonego zastosowania.

  • SoftReference może służyć do implementacji pamięci podręcznej . Obiekt, który nie jest osiągalny przez silne odniesienie (to znaczy nie jest silnie osiągalny), ale do którego odwołuje się miękkie odniesienie, nazywany jest „miękko osiągalnym”. Miękko osiągalny obiekt może być zbierany bezużytecznie według uznania modułu wyrzucania elementów bezużytecznych. Zasadniczo oznacza to, że obiekty miękko osiągalne są usuwane bezużytecznie tylko wtedy, gdy brakuje wolnej pamięci — ale znowu jest to w gestii wyrzucania elementów bezużytecznych. Semantycznie miękkie odniesienie oznacza: „Zachowaj ten obiekt, gdy nic innego się do niego nie odwołuje, chyba że potrzebna jest pamięć”.
  • WeakReference służy do implementacji słabych map . Obiekt, który nie jest silnie lub słabo osiągalny, ale do którego odwołuje się słabe odniesienie, nazywany jest „ słabo osiągalnym ”. Obiektem słabo osiągalnym są śmieci zbierane w następnym cyklu zbierania. To zachowanie jest używane w klasie java.util.WeakHashMap . Słaba mapa pozwala programiście umieścić pary klucz/wartość na mapie i nie martwić się o obiekty zajmujące pamięć, gdy klucz nie jest już osiągalny nigdzie indziej. Innym możliwym zastosowaniem słabych referencji jest pula ciągów stażystów . Semantycznie słabe odwołanie oznacza „pozbądź się tego obiektu, gdy nic innego nie odwołuje się do niego przy następnym wyrzucaniu elementów bezużytecznych”.
  • PhantomReference służy do odwoływania się do obiektów, które zostały oznaczone do wyrzucania elementów bezużytecznych i zostały sfinalizowane , ale nie zostały jeszcze odzyskane. Obiekt, który nie jest silnie, miękko lub słabo osiągalny, ale do którego odwołuje się fantomowe odniesienie, nazywany jest „osiągalnym fantomem”. Pozwala to na bardziej elastyczne czyszczenie niż w przypadku samego mechanizmu finalizacji. Semantycznie odniesienie fantomowe oznacza „ten obiekt nie jest już potrzebny i został sfinalizowany w ramach przygotowań do zebrania”.

Każdy z tych typów referencyjnych rozszerza klasę Reference , która zapewnia metodę get() zwracającą silne odwołanie do obiektu referencyjnego (lub wartość null , jeśli odwołanie zostało wyczyszczone lub jeśli typem referencyjnym jest fantom) oraz metodę clear () aby usunąć referencję.

Plik java.lang.ref definiuje również klasę ReferenceQueue , której można używać w każdej z omówionych powyżej aplikacji do śledzenia obiektów, które zmieniły typ odniesienia. Kiedy odwołanie, jest ono opcjonalnie rejestrowane w kolejce odwołań. Aplikacja sonduje kolejkę odwołań, aby uzyskać odwołania, które zmieniły stan osiągalności.

java.lang.reflect

Odzwierciedlenie jest składnikiem interfejsu API języka Java , który pozwala kodowi Java sprawdzać i „reflektować” komponenty Java w czasie wykonywania oraz używać odzwierciedlanych elementów. Klasy w java.lang.reflect wraz z java.lang.Class i java.lang.Package obsługują aplikacje, takie jak debugery , interpretery , inspektorzy obiektów, przeglądarki klas oraz usługi, takie jak serializacja obiektów i komponenty JavaBeans które potrzebują dostępu do publicznych członków obiektu docelowego (na podstawie jego klasy wykonawczej) lub członków zadeklarowanych przez daną klasę. Ten pakiet został dodany w JDK 1.1.

Odzwierciedlenie służy do tworzenia instancji klas i wywoływania metod przy użyciu ich nazw, co jest koncepcją umożliwiającą programowanie dynamiczne. Klasy, interfejsy, metody, pola i konstruktory mogą być odkrywane i używane w czasie wykonywania. Refleksja jest wspierana przez metadane , które JVM ma na temat programu.

Techniki

Istnieją podstawowe techniki związane z refleksją:

  • Discovery – obejmuje to wzięcie obiektu lub klasy i odkrycie członków, nadklas, zaimplementowanych interfejsów, a następnie ewentualnie wykorzystanie odkrytych elementów.
  • Użyj według nazwy – polega na rozpoczęciu od symbolicznej nazwy elementu i użyciu nazwanego elementu.
Odkrycie

Wykrywanie zwykle rozpoczyna się od obiektu i wywołania metody Object.getClass() w celu uzyskania klasy obiektu . Obiekt Class ma kilka metod odkrywania zawartości klasy, na przykład:

  • getMethods() – zwraca tablicę obiektów Method reprezentujących wszystkie publiczne metody klasy lub interfejsu
  • getConstructors() – zwraca tablicę obiektów Constructor reprezentujących wszystkie publiczne konstruktory klasy
  • getFields() – zwraca tablicę obiektów Field reprezentujących wszystkie pola publiczne klasy lub interfejsu
  • getClasses() – zwraca tablicę obiektów Class reprezentujących wszystkie publiczne klasy i interfejsy, które są członkami (np. klasy wewnętrzne ) klasy lub interfejsu
  • getSuperclass() – zwraca obiekt Class reprezentujący nadklasę klasy lub interfejsu ( dla interfejsów zwracana jest wartość null )
  • getInterfaces() – zwraca tablicę obiektów Class reprezentujących wszystkie interfejsy zaimplementowane przez klasę lub interfejs
Używaj według nazwy

Obiekt Class można uzyskać albo poprzez wykrywanie, używając literału klasy (np. MyClass.class ) albo używając nazwy klasy (np. Class.forName("mypackage.MyClass") ). Z Class , obiektami członkowskimi Method , Constructor lub Field można uzyskać przy użyciu symbolicznej nazwy elementu członkowskiego. Na przykład:

  • getMethod("methodName", Class...) – zwraca obiekt Method reprezentujący metodę publiczną o nazwie "methodName" klasy lub interfejsu, który akceptuje parametry określone przez parametry Class ....
  • getConstructor(Class...) – zwraca obiekt Constructor reprezentujący publiczny konstruktor klasy, który przyjmuje parametry określone przez parametry Class....
  • getField("fieldName") – zwraca obiekt Field reprezentujący pole publiczne o nazwie "fieldName" klasy lub interfejsu.

Method , Constructor i Field mogą służyć do dynamicznego uzyskiwania dostępu do reprezentowanego elementu członkowskiego klasy. Na przykład:

  • Field.get(Object) – zwraca obiekt zawierający wartość pola z instancji obiektu przekazanego do get() . (Jeśli Field reprezentuje pole statyczne, wówczas parametr Object jest ignorowany i może mieć wartość null .)
  • Method.invoke(Object, Object...) – zwraca obiekt zawierający wynik wywołania metody dla instancji pierwszego parametru Object przekazanego do invoke() . Pozostałe Object... są przekazywane do metody. (Jeśli Method reprezentuje metodę statyczną , wówczas pierwszy parametr Object jest ignorowany i może mieć wartość null .)
  • Constructor.newInstance(Object...) – zwraca nową instancję Object z wywołania konstruktora. Parametry Object ... są przekazywane do konstruktora. (Zauważ, że bezparametrowy konstruktor klasy można również wywołać, wywołując newInstance() .)
Tablice i proxy

Pakiet java.lang.reflect zawiera również klasę Array , która zawiera statyczne metody tworzenia obiektów tablicowych i manipulowania nimi, a od J2SE 1.3 klasę Proxy , która obsługuje dynamiczne tworzenie klas proxy, które implementują określone interfejsy.

Implementację klasy Proxy zapewnia dostarczony obiekt, który implementuje interfejs InvocationHandler . Metoda invoke(Object, Method, Object[]) obiektu InvocationHandler jest wywoływana dla każdej metody wywoływanej na obiekcie proxy — pierwszy parametr to obiekt proxy, a drugi to obiekt Method reprezentujący metodę z interfejsu zaimplementowanego przez proxy, a trzeci parametr to tablica parametrów przekazywanych do metody interfejsu. Metoda invoke () zwraca obiekt result, który zawiera wynik zwrócony do kodu, który wywołał metodę interfejsu proxy.

java.io

Pakiet java.io zawiera klasy obsługujące dane wejściowe i wyjściowe . Klasy w pakiecie są przede wszystkim zorientowane na strumień ; jednak dostępna jest również klasa dla plików o swobodnym dostępie . Centralne klasy w pakiecie to InputStream i OutputStream , które są abstrakcyjnymi klasami bazowymi odpowiednio do odczytu i zapisu strumieni bajtów . Powiązane klasy Reader i Writer są abstrakcyjnymi klasami bazowymi odpowiednio do odczytu i zapisu do strumieni znaków . Pakiet zawiera również kilka różnych klas wspierających interakcje z systemem plików hosta .

Strumienie

Klasy strumieni są zgodne ze wzorcem dekoratora , rozszerzając podstawową podklasę w celu dodania funkcji do klas strumieni. Podklasy klas strumieni podstawowych są zwykle nazywane na podstawie jednego z następujących atrybutów:

  • źródło/miejsce docelowe danych strumienia
  • typ danych zapisywanych do/odczytywanych ze strumienia
  • dodatkowe przetwarzanie lub filtrowanie danych strumienia

Podklasy strumieni są nazywane przy użyciu wzorca nazewnictwa XxxStreamType , gdzie Xxx to nazwa opisująca funkcję, a StreamType to jedna z wartości InputStream , OutputStream , Reader lub Writer .

W poniższej tabeli przedstawiono źródła/miejsca docelowe obsługiwane bezpośrednio przez pakiet java.io :

Źródło/Miejsce docelowe Nazwa Typy strumieni wejście/wyjście Klasy
tablica bajtów ( bajt[] ) ByteArray bajt w, na zewnątrz ByteArrayInputStream , ByteArrayOutputStream
znaków ( char[] ) CharArray zwęglać w, na zewnątrz CharArrayReader , CharArrayWriter
plik Plik bajt , znak w, na zewnątrz FileInputStream , FileOutputStream , FileReader , FileWriter
ciąg znaków ( StringBuffer ) Strunowy zwęglać w, na zewnątrz StringReader , StringWriter
wątek ( wątek ) Rurowy bajt , znak w, na zewnątrz PipedInputStream , PipedOutputStream , PipedReader , PipedWriter

Inne standardowe pakiety bibliotek udostępniają implementacje strumieni dla innych miejsc docelowych, takie jak InputStream zwracane przez metodę java.net.Socket.getInputStream() lub klasę Java EE javax.servlet.ServletOutputStream .

Obsługa typu danych i przetwarzanie lub filtrowanie danych strumienia odbywa się za pomocą filtrów strumienia . Wszystkie klasy filtrów akceptują inny zgodny obiekt strumienia jako parametr konstruktora i ozdabiają zamknięty strumień dodatkowymi funkcjami. Filtry są tworzone przez rozszerzenie jednej z podstawowych klas filtrów FilterInputStream , FilterOutputStream , FilterReader lub FilterWriter .

Klasy Reader i Writer to tak naprawdę tylko strumienie bajtów z dodatkowym przetwarzaniem wykonywanym na strumieniu danych w celu konwersji bajtów na znaki. Używają domyślnego kodowania znaków dla platformy, które od wersji J2SE 5.0 jest reprezentowane przez zestaw znaków zwracany przez statyczną metodę java.nio.charset.Charset.defaultCharset() . Klasa InputStreamReader konwertuje InputStream na Reader , a klasa OutputStreamWriter konwertuje OutputStream do Pisarza . Obie te klasy mają konstruktory, które obsługują określanie używanego kodowania znaków. Jeśli nie określono kodowania, program użyje domyślnego kodowania dla platformy.

W poniższej tabeli przedstawiono inne procesy i filtry obsługiwane bezpośrednio przez pakiet java.io. Wszystkie te klasy rozszerzają odpowiednią klasę Filter .

Operacja Nazwa Typy strumieni wejście/wyjście Klasy
buforowanie Buforowane bajt , znak w, na zewnątrz BufferedInputStream , BufferedOutputStream , BufferedReader , BufferedWriter
„odepchnij” ostatnią odczytaną wartość Odrzucenie bajt , znak W PushbackInputStream , PushbackReader
odczyt/zapis typów pierwotnych Dane bajt w, na zewnątrz DataInputStream , DataOutputStream
serializacja obiektów (obiekty odczytu/zapisu) Obiekt bajt w, na zewnątrz ObjectInputStream , ObjectOutputStream

Losowy dostęp

Klasa RandomAccessFile obsługuje dostęp swobodny do odczytu i zapisu plików. Klasa używa wskaźnika pliku , który reprezentuje przesunięcie bajtowe w pliku dla następnej operacji odczytu lub zapisu. Wskaźnik pliku jest przesuwany niejawnie przez odczyt lub zapis oraz jawnie przez wywołanie metody seek(long) lub skipBytes(int) . Bieżąca pozycja wskaźnika pliku jest zwracana przez metodę getFilePointer() .

System plików

Klasa File reprezentuje ścieżkę do pliku lub katalogu w systemie plików . Obiekty plików obsługują tworzenie, usuwanie i zmienianie nazw plików i katalogów oraz manipulowanie atrybutami plików , takimi jak tylko do odczytu i znacznik czasu ostatniej modyfikacji . Obiektów plików reprezentujących katalogi można użyć do uzyskania listy wszystkich zawartych w nich plików i katalogów.

FileDescriptor to deskryptor pliku reprezentujący źródło lub ujście (miejsce docelowe ) bajtów. Zazwyczaj jest to plik, ale może to być także konsola lub gniazdo sieciowe . Obiekty FileDescriptor służą do tworzenia strumieni plików . Uzyskuje się je ze plików oraz gniazd java.net i gniazd datagramowych.

java.nio

W J2SE 1.4 pakiet java.nio (NIO lub Non-blocking I/O) został dodany w celu obsługi operacji I/O mapowanych w pamięci , ułatwiając operacje I/O bliżej bazowego sprzętu, czasami znacznie poprawiając wydajność. Pakiet java.nio zapewnia obsługę wielu typów buforów. Podpakiet java.nio.charset zapewnia obsługę różnych kodowań znaków dla danych znakowych. Podpakiet java.nio.channels zapewnia obsługę kanałów, które reprezentują połączenia z jednostkami zdolnymi do wykonywania operacji we/wy, takimi jak pliki i gniazda. Pakiet java.nio.channels zapewnia również obsługę precyzyjnego blokowania plików.

java.math

Pakiet java.math obsługuje arytmetykę wieloprecyzyjną (w tym operacje arytmetyczne modułowe) i udostępnia generatory liczb pierwszych wieloprecyzyjnych używane do generowania kluczy kryptograficznych. Główne klasy pakietu to:

java.net

Pakiet java.net udostępnia specjalne procedury we/wy dla sieci, zezwalające na żądania HTTP , a także inne typowe transakcje.

java.tekst

Pakiet java.text implementuje procedury analizowania ciągów znaków i obsługuje różne języki czytelne dla człowieka oraz analizę składniową specyficzną dla ustawień regionalnych.

java.util

Głównym celem pakietu java.util są struktury danych , które agregują obiekty . W pakiecie znajduje się interfejs Collections API , zorganizowana hierarchia struktury danych, na którą duży wpływ mają wzorce projektowe .

Pakiety specjalnego przeznaczenia

aplet java

java.applet , stworzony w celu wspierania tworzenia apletów Java , umożliwia pobieranie aplikacji przez sieć i uruchamianie ich w strzeżonym obszarze izolowanym. Na piaskownicę można łatwo nałożyć ograniczenia bezpieczeństwa. Deweloper może na przykład zastosować podpis cyfrowy do apletu, oznaczając go tym samym jako bezpieczny. W ten sposób użytkownik może przyznać apletowi uprawnienia do wykonywania ograniczonych operacji (takich jak dostęp do lokalnego dysku twardego) i usuwa niektóre lub wszystkie ograniczenia piaskownicy. Certyfikaty cyfrowe są wydawane przez urzędy certyfikacji .

java.beans

W pakiecie java.beans znajdują się różne klasy do tworzenia i manipulowania komponentami bean, komponentami wielokrotnego użytku zdefiniowanymi przez architekturę JavaBeans . Architektura zapewnia mechanizmy manipulowania właściwościami komponentów i wyzwalania zdarzeń, gdy te właściwości się zmieniają.

Interfejsy API w java.beans są przeznaczone do użycia przez narzędzie do edycji komponentu bean, w którym komponenty bean mogą być łączone, dostosowywane i modyfikowane. Jednym z typów edytora fasoli jest GUI w zintegrowanym środowisku programistycznym .

java.awt

Pakiet java.awt lub Abstract Window Toolkit zapewnia dostęp do podstawowego zestawu widżetów GUI opartych na zestawie widżetów platformy natywnej, rdzeniu podsystemu zdarzeń GUI oraz interfejsie między natywnym systemem okienkowym a aplikacją Java. Zapewnia również kilka podstawowych menedżerów układu , pakiet transferu danych do użytku ze schowkiem oraz metodą przeciągania i upuszczania , interfejs do urządzeń wejściowych, takich jak myszy i klawiatury , a także dostęp do zasobnika systemowego na systemach wspomagających. Ten pakiet, wraz z javax.swing , zawiera największą liczbę wyliczeń (w sumie 7) w JDK 6.

java.rmi

Pakiet java.rmi umożliwia zdalne wywoływanie metod Java w celu obsługi zdalnych wywołań procedur między dwiema aplikacjami Java działającymi w różnych maszynach JVM .

java.bezpieczeństwo

Obsługa zabezpieczeń, w tym algorytmu skrótu wiadomości, jest zawarta w pakiecie java.security .

java.sql

Implementacja interfejsu API JDBC (używanego do uzyskiwania dostępu do baz danych SQL ) jest zgrupowana w pakiecie java.sql .

javax.rmi

Pakiet javax.rmi zapewniał obsługę zdalnej komunikacji między aplikacjami z wykorzystaniem protokołu RMI over IIOP. Protokół ten łączy w sobie funkcje RMI i CORBA.

Podstawowe technologie Java SE — CORBA / RMI-IIOP

javax.swing

Swing to zbiór procedur opartych na java.awt w celu zapewnienia niezależnego od platformy zestawu narzędzi widżetów . javax.swing wykorzystuje procedury rysowania 2D do renderowania komponentów interfejsu użytkownika, zamiast polegać na podstawowej obsłudze graficznego interfejsu użytkownika systemu operacyjnego .

Ten pakiet zawiera największą liczbę klas (w sumie 133) w JDK 6. Ten pakiet, wraz z java.awt , zawiera również największą liczbę wyliczeń (w sumie 7) w JDK 6. Obsługuje pluggable look and feel (PLAF) aby widżety w GUI mogły naśladować te z podstawowego systemu natywnego. Wzorce projektowe przenikają system, zwłaszcza modyfikacja wzorca model-widok-kontroler , która rozluźnia sprzężenie między funkcją a wyglądem. Jedną z niespójności jest to, że (od J2SE 1.3) czcionki są rysowane przez podstawowy system natywny, a nie przez Javę, co ogranicza przenośność tekstu. Istnieją obejścia, takie jak używanie czcionek bitmapowych. Ogólnie rzecz biorąc, używane są „układy”, które utrzymują elementy w spójnym estetycznie GUI na różnych platformach.

javax.swing.text.html.parser

Pakiet javax.swing.text.html.parser zawiera odporny na błędy parser HTML, który jest używany do pisania różnych przeglądarek internetowych i botów internetowych.

javax.xml.bind.adnotacja

Pakiet javax.xml.bind.annotation zawierał największą liczbę typów adnotacji (w sumie 30) w pakiecie JDK 6. Definiuje adnotacje do dostosowywania elementów programu Java do mapowania schematu XML.

Pakiety OMG

org.omg.CORBA

Pakiet org.omg.CORBA zapewnił obsługę zdalnej komunikacji między aplikacjami z wykorzystaniem protokołu General Inter-ORB oraz wspiera inne funkcje architektury brokera żądań wspólnego obiektu . Podobnie jak RMI i RMI-IIOP , ten pakiet służy do wywoływania zdalnych metod obiektów na innych maszynach wirtualnych (zwykle przez sieć).

Ten pakiet zawierał największą liczbę klas wyjątków (w sumie 45) w JDK 6. Ze wszystkich możliwości komunikacyjnych CORBA jest przenośna między różnymi językami; jednak wiąże się to z większą złożonością.

Te pakiety zostały uznane za przestarzałe w Javie 9 i usunięte z Javy 11.

org.omg.PortableInterceptor

Pakiet org.omg.PortableInterceptor zawierał największą liczbę interfejsów (w sumie 39) w JDK 6. Zapewnia mechanizm rejestrowania zaczepów ORB, przez które usługi ORB przechwytują normalny przepływ wykonywania ORB.

Bezpieczeństwo

Zgłoszono kilka krytycznych luk w zabezpieczeniach. Alerty bezpieczeństwa firmy Oracle informują o krytycznych poprawkach związanych z bezpieczeństwem dla Java SE.

Linki zewnętrzne