Wykład Java ver3.0 1

Wielkość: px
Rozpocząć pokaz od strony:

Download "Wykład Java 07-01-31 ver3.0 1"

Transkrypt

1 Wykład Java ver3.0 1 Java jest językiem stosowanym w Internecie. Aby zrozumieć jego ważność, można przyjąć, że ma on tak samo duże znaczenie dla programowania w Internecie, jak C++ dla programowania systemowego.. Bez Javy nie istniałby Internet w obecnym kształcie. Język Java został opracowany w 1991 roku przez Jamesa Goslinga, Patricka Naughtona, Chrisa Wartha, Eda Franka i Mike'a Sheridana z firmy Sun Microsystems, Inc. Utworzenie pierwszej działającej wersji zajęło dalszych 18 miesięcy. Język ten początkowo nazywał się Oak (dąb), ale w 1995 roku jego nazwę zmieniono na Javę. W okresie dzielącym pojawienie się pierwszej implementacji języka Oak na jesieni 1992 roku i oficjalnego ogłoszenia powstania Javy na wiosnę 1995 roku wiele osób przyczyniło się do ulepszenia rozwiązań i rozwoju tego języka. Głównymi sprawcami udoskonalania początkowej wersji byli: Bill Joy, Arthur van Hoff, Jonathan Payne, Frank Yellin i Tim Lindholm. Może się to wydawać dziwne, ale początkowo język Java nie był przeznaczony dla, Internetu. U podstaw jego utworzenia była potrzeba istnienia języka niezależnego od mikroprocesora i systemu operacyjnego, którego można by używać do tworzenia oprogramowania instalowanego w różnych elektronicznych urządzeniach, takich jak kuchenki mikrofalowe i urządzenia zdalnego sterowania. Java została początkowo zaprojektowana jako narzędzie do tworzenia przenośnego kodu, który dawałby się uruchamiać w różnego rodzaju urządzeniach sterujących. W czasie opracowywania szczegółów Javy pojawiał się stopniowo drugi i o wiele ważniejszy czynnik, który odegrał kluczową rolę w dalszym rozwoju tego języka. Czynnikiem tym była oczywiście sieć WWW. W tej dziedzinie był także potrzebny środek tworzenia przenośnego kodu. Gdyby strony WWW nie nabrały tak ogromnego znaczenia w czasie projektowania Javy, to prawdopodobnie pozostałaby ona użytecznym wprawdzie, ale mało znanym językiem programowania, używanym przy projektowaniu konsumenckich urządzeń elektronicznych. Jednak w miarę rozrastania się sieci WWW Java wysuwała się na pierwsze miejsce w dziedzinie projektowania języków komputerowych. Java jest spokrewniona z C++ z dwóch ważnych powodów. Po pierwsze, używa tej samej składni: taką samą postać mają takie instrukcje, jak for, while czy do. Po drugie, w obu językach stosowane są bardzo podobne zasady projektowania zorientowanego obiektowo. Z powodu powierzchownych podobieństw występujących między językami C++ i Java można przypuszczać, że Java jest wersją Internetową języka C++. Stwierdzenie to nie jest jednak w pełni prawdziwe, ponieważ między obu językami istnieją również różnice, zmieniające w istotny sposób ich charakter. Mimo to programiści C++ nie mają powodów do zmartwienia: nauka programowania w Javie nie przysporzy im z pewnością problemów.

2 Wykład Java ver3.0 2 Podsumowując, można stwierdzić, że przewaga Javy nad C++ wynika nie z tego, co ten nowy język zawiera, ale raczej, czego nie zawiera. 1 Najważniejsze zalety Javy: Ponieważ języki C i C++ są wszechstronnymi, dobrze zdefiniowanymi, profesjonalnymi językami programowania, można by się zastanawiać nad sensownością wprowadzenia jeszcze jednego języka. Jednak utworzenie Javy było konieczne z dwóch ważnych powodów, które dają się streścić za pomocą dwóch słów: bezpieczeństwo i przenośność. Bezpieczeństwo Z pewnością wszyscy programiści wiedzą, że załadowanie każdego "zwykłego" programu wiąże się z ryzykiem zarażenia komputera wirusem. Przed wprowadzeniem Javy większość użytkowników sieci nie pobierało zbyt często wykonywalnych programów, a jeżeli to robili, to przed ich uruchomieniem testowali je programami antywirusowymi. Jednak nawet wówczas nie znikało w pełni ryzyko zarażenia systemu lub uruchomienia "złośliwego" programu (program taki mógł zbierać informacje poufne, takie jak numery kart kredytowych, stany kont bankowych czy hasła, przeszukując zawartość lokalnego systemu plików). Odpowiedzią Javy na te zagrożenia było wprowadzenie "zapory ogniowej" (ang. firewall, istniejącej między aplikacją sieciową a komputerem lokalnym. Korzystając z przeglądarki WWW kompatybilnej z Javą, można bezpiecznie wczytywać aplety Javy bez obawy o zarażenie komputera wirusem. Twórcy Javy uzyskali to przez ograniczenie zakresu instrukcji tego języka do środowiska wykonywania danego programu i uniemożliwienie dostępu do innych elementów komputera (wkrótce zostanie objaśniony sposób zrealizowania tego celu). Mówiąc krótko, najważniejszą cechą charakterystyczną Javy jest możliwość ładowania apletów, mając pewność, że nie wyrządzą one żadnej szkody komputerowi użytkownika sieci. Przenośność Istnieje wiele różnych typów komputerów i systemów operacyjnych - wiele z nich jest podłączonych do Internetu. Aby programy można było dynamicznie ładować i uruchamiać we wszystkich systemach komputerowych połączonych z siecią WWW, trzeba dysponować narzędziem pozwalającym generować przenośny kod wykonywalny. Jak będzie się można wkrótce przekonać, sposób, w jaki Java pozwala uzyskać przenośność, jest zarówno elegancki, jak i efektywny 1 Partrick Naughton

3 Wykład Java ver3.0 3 Istota kodu bajtowego Wiele problemów można rozwiązać dzięki temu, że kompilator Javy nie tworzy kodu wykonywalnego programów, lecz tak zwany kod bajtowy (ang. bytecode). Kod bajtowy jest wysoko zoptymalizowanym zestawem instrukcji przeznaczonym do wykonywania przez maszynę wirtualną, którą emuluje system czasu przebiegu Javy. Można więc powiedzieć, system czasu przebiegu Javy (ang. Java run-time system) jest interpreterem kodu bajtowego. Może się to wydawać dziwne, gdyż -jak wiadomo - programy C++ są kompilowane do postaci kodu wykonywalnego. Zresztą większość współczesnych języków programowania jest przeznaczonych do kompilowania, a nie interpretowania, głównie ze względu na szybkość wykonywania programów. Jednak fakt, że programy Javy są interpretowane, pozwala rozwiązać główne problemy związane z ładowaniem programów z Internetu. Jest tak dlatego, że interpretowanie kodu bajtowego Javy ułatwia uruchamianie programów Javy w wielu różnych środowiskach. Przyczyna tego jest oczywista: dla każdej platformy trzeba zaimplementować jedynie system czasu przebiegu Javy. Kiedy już pakiet ten istnieje w danym systemie komputerowym, można go używać do uruchamiania wszystkich programów Javy. Należy pamiętać, że szczegóły systemu czasu przebiegu Javy zależą od danej platformy, to jednak wszystkie potrafią interpretować ten sam kod bajtowy tego języka. Gdyby programy Javy były kompilowane, to należałoby tworzyć różne wersje wykonywalne tego samego programu, przeznaczone dla poszczególnych rodzajów komputerów połączonych z Internetem. Nie byłoby to oczywiście rozwiązaniem dającym się zrealizować w praktyce. Jak więc widać, interpretacja jest najłatwiejszym sposobem tworzenia w pełni przenośnych programów. Fakt, że programy Javy są interpretowane, pomaga także uczynić je bezpiecznymi. Ponieważ wykonywaniem każdego programu steruje w pełni system czasu przebiegu Javy, może on ograniczać wykonywane przez niego operacje i uniemożliwić mu wywoływanie efektów ubocznych. Jak będzie się można przekonać, bezpieczeństwo dodatkowo się zwiększa przez wprowadzenie niektórych ograniczeń dotyczących Javy. Jak zapewne niektórzy czytelnicy wiedzą, programy, które są interpretowane, działają znacznie wolniej, niż ich odpowiedniki kompilowane do postaci kodu wykonywalnego. Jednak w przypadku Javy wydłużenie czasu wykonywania programów nie jest duże. Stosowanie kodu bajtowego umożliwia bowiem systemowi czasu przebiegu Javy wykonywanie programów dużo szybciej niż można by tego oczekiwać. Nie oznacza to rezygnacji z bezpieczeństwa i przenośności programów, gdyż również w takiej sytuacji ich wykonywaniem zarządza system czasu przebiegu Javy

4 Wykład Java ver3.0 4 Podobieństwo do języka C/C++ Java została zaprojektowana w taki sposób, aby zawodowi programiści mogli się jej szybko nauczyć i efektywnie stosować. Dotyczy to szczególnie programistów C++, gdyż rozpoczęcie programowania w Javie wymaga od nich minimalnego wysiłku. Ponieważ w Javie jest stosowana składnia języków C/C++ i wiele elementów programowania zorientowanego obiektowo, większość programistów jest w stanie poznać ten język w bardzo krótkim czasie. Jest tak również dlatego, że najgorsze rozwiązania stosowane w C/C++ zostały w Javie poprawione lub nie zostały do niej przeniesione. Zorientowanie obiektowe Projektanci Javy ulepszyli koncepcje programowania zorientowanego obiektowo istniejących języków programowania, takich jak C++. Nie musieli jednak kopiować ich wad, gdyż mieli możliwość utworzenia od początku takiego modelu obiektów, który byłby przejrzysty i łatwy w stosowaniu. Mimo iż Java jest językiem ze ścisłą kontrolą obiektów, to jednak umożliwia pisanie szybko działających programów. Przyczynia się do tego między innymi fakt, że podstawowe typy, takie jak liczby całkowite czy znaki, są typami elementarnymi, a nie obiektami. Wygoda Kilka cech charakterystycznych Javy pozwala pisać w prosty sposób poprawnie działające i funkcjonalne programy. Po pierwsze, jest to język ze ścisłą kontrolą typów. Ponieważ dla każdej zmiennej i wyrażenia trzeba określić typ, pozwala to wykrywać ewentualne błędy już w czasie kompilowania programu. Wszelkiego rodzaju niezgodności typów są sygnalizowane w postaci komunikatów kompilatora. Po drugie, w Javie jest dużo łatwiej zarządzać pamięcią, niż w C++, gdyż nie trzeba pisać instrukcji zwalniających przydzieloną pamięć (nieużywane fragmenty pamięci są zwalniane automatycznie). Po trzecie, zorientowana obiektowo obsługa wyjątków umożliwia utworzenie przejrzystej struktury tekstu źródłowego, ułatwiającej wykrywanie sytuacji nietypowych pojawiających się podczas działania programu i odpowiednie reagowanie. Wielowątkowość Projektanci Javy uwzględnili potrzebę istnienia języka umożliwiającego tworzenie praktycznie wykorzystywanych, interaktywnych programów sieciowych. Dlatego Java pozwala pisać programy wielowątkowe, a więc wykonujące jednocześnie wiele operacji. W systemach czasu przebiegu Javy zastosowano eleganckie, choć skomplikowane rozwiązanie synchronizacji procesów, umożliwiające konstruowanie sprawnie działających programów interaktywnych.

5 Wykład Java ver3.0 5 Łatwość stosowania wielowątkowości w Javie pozwala myśleć kategoriami działania programu, a nie realizacji wielozadaniowości. Niezależność od sprzętu Jednym z głównych osiągnięć zespołu pracującego nad Javą jest umożliwienie tworzenia. pojedynczych wersji programów, które można uruchamiać w wielu różnych systemach komputerowych. Wymaga to oczywiście instalowania maszyny wirtualnej Javy w nowo powstającym sprzęcie i oprogramowaniu. Dzięki temu kod bajtowy generowany na podstawie tekstu źródłowego Javy może pozostawać cały czas niezmienny. Interpretacja Wadą języków interpretowanych jest często niezadowalająca szybkość działania programów. Jest to szczególnie dotkliwe podczas korzystania z wolno działających procesorów. Istnieje jednak możliwość bieżącej (ang. just-in-time) kompilacji programów. Oznacza to, że kod bajtowy wygenerowany przez kompilator Javy jest tłumaczony na kod wykonywalny, właściwy dla danego procesora, tuż przed jego pierwszym wykonaniem. Instrukcje kodu bajtowego zostały zaprojektowane w taki sposób, aby to tłumaczenie przebiegało jak najsprawniej. Poza tym kod bajtowy jest optymalizowany ze względu na jego interpretację, tak więc problemy towarzyszące zwykle korzystaniu z języków interpretowanych nie są w przypadku Javy znaczące. Środowisko rozproszone Java została zaprojektowana dla środowiska rozproszonego Internetu, ponieważ umożliwia ona korzystanie z protokołów TCP/IP. Uzyskanie dostępu do zasobu przez podanie adresu URL (skrót od ang. Uniform Resource Locator = ujednolicony adres zasobu) jest niewiele trudniejsze niż uzyskanie dostępu do pliku. Dynamika Programy Javy zawierają znaczne ilości informacji czasu przebiegu dotyczących typów i wykorzystywanych w celu weryfikowania i realizowania żądań dostępu do obiektów. Umożliwia to dynamiczne dołączanie kodu w łatwy i wygodny sposób. Jest to bardzo ważne dla sprawnego funkcjonowania środowiska apletów, gdzie małe fragmenty kodu bajtowego mogą być dynamicznie uaktualniane w działających programach.

6 Wykład Java ver3.0 6 Różnice między Javą i C++ Mimo iż pierwowzorem Javy jest C++, to jednak między tymi językami istnieje kilka podstawowych różnic. Niektóre z nich polegają tylko na wprowadzeniu drobnych zmian, inne są związane z głównymi założeniami projektu, mającymi istotny wpływ na sposób pisania programów. W dalszej części wykładu zostaną omówione najważniejsze różnice. Wcześniej jednak musimy sobie zdać sprawę z pewnego, bardzo ważnego faktu: Java została zaprojektowana w celu umożliwienia bezpiecznego ładowania przenośnych aplikacji za pomocą sieci i w swoim obecnym kształcie nie można nią zastąpić języków C/C++ jako narzędzi do tworzenia programów systemowych. Pamiętając o tym, przyjrzyjmy się kilku różnicom występującym między językami Java oraz C++. Elementy usunięte z C/C++ Kilka elementów charakterystycznych języka C++ nie zostało przeniesionych do Javy. Część z nich po prostu nie odnosiła się do środowiska programów Javy. Projektanci Javy usuwali także te elementy języka C++, które były w nim powielane. W jeszcze innych przypadkach nie zostały uwzględnione elementy programowania, które byłyby zbyt niebezpieczne w apletach Javy. Prawdopodobnie największą różnicą występującą między językami C/C++ i Java jest brak wskaźników w tym ostatnim. Jako programiści C/C++, wszyscy czytelnicy wiedzą, że wskaźniki są najważniejszymi i najbardziej wszechstronnymi elementami języków programowania. Jednak w przypadku ich niewłaściwego użycia stają się one bardzo niebezpieczne. Wskaźniki nie istnieją w Javie z dwóch powodów. Przede wszystkim właśnie dlatego, że ich stosowanie wiąże się z dużym niebezpieczeństwem. Na przykład korzystając ze wskaźników C++ można uzyskać dostęp do komórek pamięci znajdujących się poza miejscem zajmowanym przez kod wynikowy i dane programu. "Złośliwy" program mógłby wykorzystać ten fakt w celu zniszczenia systemu, uzyskanie niedozwolonego dostępu do jego zasobów (na przykład odczytania haseł) lub wykonania innego działania niezgodnego z zasadami bezpieczeństwa. Po drugie, nawet jeśli zakres wskaźników byłby ograniczony przez system czasu przebiegu Javy (co byłoby teoretycznie możliwe, gdy programy Javy są interpretowane), to i tak twórcy tego języka uznali, że są one częstym źródłem występowania błędów w programach. Z faktu, że Java nie zawiera wskaźników, wynika, że nie istnieje w niej także operator ->. Java nie zawiera struktur i unii. Zostały one uznane jako zbędne, gdyż można je zastąpić klasami.

7 Wykład Java ver3.0 7 W Javie nie jest możliwe przeładowywanie operatorów. Ponieważ działanie to jest często źródłem wieloznaczności w programach C++, projektanci Javy stwierdzili, iż przynosi ono więcej kłopotów niż korzyści. Java nie zawiera preprocesora i nie umożliwia stosowania jego dyrektyw, twórcy Javy postanowili w ogóle z nich zrezygnować. W Javie nie są wykonywane automatyczne konwersje typów powodujące zmniejszenie dokładności. Na przykład przekształcenie typu long int w int musi być dokonane jawnie. Cały tekst źródłowy programu Javy należy do jednej lub większej liczby klas. W związku z tym w Javie nie istnieje pojęcie funkcji i zmiennych globalnych. Java nie pozwala na stosowanie argumentów domyślnych. W C++ można określić wartość, która jest automatycznie przypisywana parametrowi w przypadku pominięcia odpowiadającego mu argumentu w wywołaniu funkcji. W Javie nie jest to dozwolone. Java nie pozwala na dziedziczenie wielu klas przez pojedynczą klasę pochodną. W Javie istnieją konstruktory, ale nie ma destruktorów. Zamiast nich została wprowadzona funkcja finalize(). Java nie zawiera instrukcji typedef. Nie można deklarować liczb całkowitych bez znaku (unsigned int). W Javie nie istnieje instrukcja goto. Nie ma operatora delete. Operatory <<i >> nie zostały przeładowane do celów operacji wejścia/wyjścia. W Javie obiekty można przekazywać wyłącznie przez odwołanie (w C++ obiekty mogą być przekazywane zarówno przez odwołanie, jak i przez wartość). Nowe elementy dodane do Javy Niektóre elementy Javy nie mają swoich odpowiedników w C++. Do najważniejszych z nich z pewnością należą pakiety, interfejsy i wielowątkowość. Oprócz nich istnieje kilka innych, wzbogacających środowisko programowania Javy. Pakiet (ang. package) definiuje w Javie obszar nazw i umożliwia grupowanie spokrewnionych ze sobą klas. Nie ma elementów C++, które by bezpośrednio odpowiadały pakietom Javy. Najbliższe podobieństwo do nich wykazuje zestaw funkcji bibliotecznych korzystających ze wspólnego pliku nagłówkowego. Jednak konstruowanie i korzystanie z biblioteki C++ przebiega zupełnie inaczej niż konstruowanie i korzystanie z pakietów Javy. Interfejs (ang. interface) Javy przypomina w pewnym stopniu klasę abstrakcyjną C++ (klasa abstrakcyjna C++ jest klasą zawierającą przynajmniej jedną funkcję wirtualną). Na przykład oba elementy językowe służą do określania wspólnego interfejsu implementowanego przez klasy pochodne, stąd też nie jest dozwolone tworzenie ich obiektów. Główna różnica między

8 Wykład Java ver3.0 8 klasami abstrakcyjnymi a interfejsami Javy polega na tym, że te ostatnie lepiej służą idei tworzenia dziedziczonych klas wzorcowych. Wielowątkowość umożliwia jednoczesne wykonywanie dwóch lub większej liczby fragmentów tego samego programu. Rozwiązanie zastosowane w Javie pozwala na uzyskiwanie wielowątkowości za pomocą wbudowanych mechanizmów. Nie istnieje odpowiednik tego elementu w języku C++. Jeżeli program C++ ma składać się z wielu wątków, to można ten cel osiągnąć jedynie "ręcznie", za pomocą funkcji systemu operacyjnego. Mimo iż obie metody umożliwiają jednoczesne wykonywanie wielu wątków, to jednak rozwiązanie zastosowane w Javie jest bardziej przejrzyste i łatwiejsze w stosowaniu. innym elementem różniącym Javę od C++ jest sposób przydziału pamięci. Podobnie jak w C++, w Javie istnieje słowo kluczowe new, ale nie ma słowa delete. Jest to spowodowane tym, że zniszczenie ostatniego odwołania do danego obiektu powoduje jego automatyczne usunięcie podczas wykonywania następnej operacji porządkowania pamięci (ang. garbage collection). W Javie została usunięta biblioteka standardowa C/C++, a zastąpił ją specjalny zestaw klas API. Między obu rodzajami funkcji istnieje znaczne podobieństwo, ale występują też istotne różnice w nazewnictwie parametrów. Poza tym, ponieważ cała biblioteka API Javy jest zorientowana obiektowo, w przeciwieństwie do biblioteki C++, która jest zorientowana obiektowo tylko w części, w odmienny sposób wywołuje się oba rodzaje funkcji bibliotecznych. Rozszerzono zakres stosowania instrukcji break i continue, umożliwiając stosowanie etykiet jako wartości docelowych. Typ char oznacza 16-bitowe znaki zapisywane w ujednoliconym kodzie Unicode. Stosowanie ujednoliconego kodu jest gwarantem uzyskania przenośności. Java posiada operator >>>, wykonujący przesunięcie w prawo liczby bez znaku. Oprócz komentarzy jednowierszowych (//) i wielowierszowych (/* */) w Javie można stosować również komentarze dokumentacyjne, które rozpoczynają się od znaków /** i kończą znakami */. Java zawiera wbudowany typ łańcuchowy o nazwie String. Jest on nieco podobny do standardowej klasy string języka C++. Oczywiście klasa string nie jest typem wbudowanym, dlatego można z niej korzystać dopiero po dołączeniu do programu odpowiedniego pliku nagłówkowego. Zmienione elementy

9 Wykład Java ver3.0 9 Istnieją elementy, które istnieją zarówno w C++, jak i Javie, ale w każdym z tych języków funkcjonują nieco inaczej. W obu językach istnieje typ danych logicznych, ale różna jest implementacja wartości true i false. W C++ true jest dowolną wartością różną od zera, a false zerem, natomiast w Javie true i false są predefiniowanymi literałami, określającymi jedyne dopuszczalne wartości wyrażeń typu boolean. Wprawdzie także w C++ są zdefiniowane wartości true i false, które można przypisywać zmiennym typu boolean, ale wszystkie wartości niezerowe są w razie potrzeby automatycznie przekształcane w true, a wartości zerowe w false. W Javie operacja taka nie jest wykonywana. Specyfikatory dostępu zamieszczone w definicji klasy C++ dotyczą grup instrukcji, natomiast w Javie wyłącznie deklaracji, które bezpośrednio poprzedzają. W programach C++ można obsługiwać wyjątki podobnie, jak w programach Javy. Jednak w C++ nie ma obowiązku przechwytywania wszystkich generowanych wyjątków, podczas gdy w Javie większość wyjątków musi być przechwytywana. Z Javą wiążą się dwa ważne terminy, nie używane w językach programowania C/C++: aplety i metody. Aplety Javy Za pomocą Javy można tworzyć dwa rodzaje programów: aplikacje i aplety. Aplikacja jest programem działającym na komputerze użytkownika i zarządzanym przez jego system operacyjny. Tak więc Java jest (w większym lub mniejszym stopniu) podobna do aplikacji utworzonej przez kompilator C lub C++. Jeżeli Javy używa się do przygotowywania aplikacji, to nie różni się ona wiele od innych języków programowania. Cechą Javy, która nadaje jej znaczenia, jest możliwość tworzenia apletów. Aplet (ang. applet) jest małą aplikacją przeznaczoną do przesłania jej za pomocą Internetu i wykonywaną za pomocą kompatybilnej z Javą przeglądarki sieci WWW. Dzięki stosowaniu apletów zawartość strony WWW może aktywnie decydować o sposobie jej wyświetlenia. Możliwość tworzenia przenośnych, dynamicznie ładowalnych apletów jest najważniejszą przyczyną ogromnej popularności Javy. Metody Zanim przejdziemy do pisania pierwszej aplikacji Javy, musi zostać wyjaśniony jeszcze jeden ważny termin używany przez programistów Javy. W języku tym bardzo rzadko pojawia się

10 Wykład Java ver termin funkcja. Fragment programu, który programista C++ nazwałby funkcją składową, jego kolega programujący w Javie nazywa metodą (ang. method). Wynika to stąd, że w Javie nie istnieją funkcje globalne. Wszystkie funkcje (metody) należą do klas.

11 Wykład Java ver Termin API AFC AWT BDK Enterprise APIs HotJava IFC Internacjonalizacja Wybrane terminy związane z Javą Znaczenie Application Programming Interfaces; standard programowania (taki jak stdlib lub Win32) Application Foundation Classes: biblioteka klas wypromowana przez Microsoft. Zobacz także IFC, JFC Abstract Window Toolkit: biblioteka GUI Javy Beans Development Kits. Zobacz także JDK, Java Beans "Enterprise APIs" firmy Sun dla Javy z JDBC, RMI i Security Kompletna przeglądarka WWW napisana w całości w Javie Internet Foundation Classes: biblioteka klas promowana przez Netscape. Zobacz także AFC, JFC Program do obsługi różnych języków (na przykład francuskiego lub angielskiego) i różnych miejsc (na przykład Wielka Brytania a symbole walut i pisownia amerykańska) bez ponownej kompilacji. Java 1.1 wprowadza nowe właściwości, które upraszczają internacjonalizację. Zobacz także Unikod, ResourceBundles Introspekcja Oznacza, według którego klienta można "otrzymać" funkcjonalność wyeksportowaną przez Java Bean. Zobacz także Java Beans, Refleksja JAR Java Beans JavaOS JDK JFC JIT JNI JDBC JVM Właściwości Plik Java Archive: wygodne środki do wczytywania apletu i innych związanych plików (pliki dźwiękowe, obrazy, pomoc itd.) za jednym "zamachem", zamiast przez kilka osobnych zapytań HTTPD "Software component model"; podobne do COM i ActiveX Microsoftu System operacyjny rozwinięty przez Sun, nadający się szczególnie do uruchamiania aplikacji Javy Java Development Kit: kompletny kompilator Javy, biblioteki itd.jdk można otrzymać za darmo ze strony początkowej firmy Sun Java Foundation Classes: biblioteka klas Javy firmy Sun. Zobacz także AFC, IFC Just In Time Compiler. JIT przekształca ("od ręki") kody bajtowe Javy na wykonywalne. Użycie JIT w przeglądarkach WWW drastycznie zwiększyło wydajność programów Javy Native Method Interface: umożliwia programom C używanie klas i metod Javy Java Data Base Connectivity: część Enterprise API. JDBC umożliwia programom Javy komunikowanie się z bazami danych; podobne do ODBC Microsoftu Java vrtualmachine: interpretuje kod bajtowy Javy i wykonuje program Javy (na przykład w przeglądarce z aktywną Javą) Java Beans eksportuje swoje właściwości do programów klienta jako zestaw wlaściwości (atrybuty obiektu) i metody (zachowanie)

12 Wykład Java ver Termin Refleksja ResourceBundle RMI Servlet Sygnowany aplet Unikod Wybrane terminy związane z Javą Znaczenie To nowy pakiet JDK 1.1 umożliwiający uzyskanie informacji o właściwościach i metodach dostępnych w elemencie Java Bean "Refleksja" jest podobna do "Bibiotek typu" używanych w MS- Windows Związane z internacjonalizacją. Zwykle polega na zdefiniowaniu unikatowej "wiązki" Remote Method Invocation: część Enterprise API; umożliwia apletom Javy wywołanie zdalnych zasobów (na przykład innych aplętów) w różnych procesach lub nawet na różnych maszynachw Internecie Program Javy przeznaczony do uruchamiania na serwerze WW W; przeciwieństwo apletu, który jest wczytywany i uruchamiany na kliencie Dołączenie "podpisu cyfrowego" do pliku JAR Javy gwarantuje,że aplet pochodzi z dobrego źródła Format łańcucha w Javie; przeznaczony do obsługi dowolnego znaku w dowolnym języku Słowa kluczowe Zarezerwowane słowa kluczowe są specjalnymi identyfikatorami umożliwiającymi zapisywanie programów. Służą one wyłącznie do identyfikowania wbudowanych typów, modyfikatorów i instrukcji sterujących, nie można więc ich używać na przykład jako nazw zmiennych czy metod. W połączeniu z operatorami i separatorami, słowa kluczowe umożliwiają zdefiniowanie pełnej składni Javy. W sumie język ten (w wersji 1.0) zawiera 59 słów kluczowych, zamieszczonych w tabeli Zarezerwowane słowa kluczowe abstract break byte byvalue case cast catch char class const continue default do double else extends false final finally float for future generic goto if implements import inner instanceof int interface long native new null boolean operator outer package private protected public rest return short static super switch synchronized this throw throws transient true try var void volatile while Identyfikatory

13 Wykład Java ver Identyfikatorów używa się jako nazw klas, metod i zmiennych. Mogą one składać się z liter, cyfr, znaku podkreślenia i znaku dolara. Pierwszy znak nie może być cyfrą, gdyż w przeciwnym razie można by je było pomylić z omówionymi niżej literałami numerycznymi. W Javie są rozróżniane małe i duże litery, na przykład identyfikatory DOM i Dom są różne. Do poprawnie zbudowanych identyfikatorów należą między innymi: timeofday, temp_val, a4 i $_. Natomiast niepoprawne identyfikatory to na przykład 1more, 3$, #abc Twórcy Javy proponują, aby wszystkim metodom i zmiennym publicznym przydzielać identyfikatory rozpoczynające się od małych liter i zawierające duże litery na początku każdego nowego słowa, na przykład nextltem, currentvalue czy gettimeofday. Natomiast identyfikatory metod prywatnych oraz zmiennych prywatnych i lokalnych powinny zawierać wyłącznie małe litery oraz znaki podkreślenia oddzielające kolejne wyrazy, na przykład next_val czy temp_val. Zmienne finalne, czyli zmienne o stałych wartościach, najlepiej jest wyróżniać za pomocą dużych liter, na przykład TOK_BRACE, DAY_FRIDAY czy GREEN. Literały Stałe wartości zapisuje się w programach Javy w postaci literałów. Z każdym literałem jest związany określony typ, czyli sposób zapisywania go i wykonywania na nim operacji - może to być liczba całkowita, liczba zmiennoprzecinkowa (rzeczywista), wartość logiczna (boolowska), znak lub łańcuch (tekst). Literały całkowite Literały całkowite są najczęściej występującymi literałami w większości programów. Umożliwiają one zapisywanie liczb całkowitych w trzech systemach liczenia: dziesiętnym, ósemkowym i szesnastkowym. Literały ósemkowe (oktalne), używane przez niektórych doświadczonych programistów, umożliwiają zapisywanie cyfr odpowiadających trójkom bitów, ale korzyści wynikające z ich stosowania są niewielkie. Mogą one zawierać wyłącznie cyfry od 0 do 7 i muszą zaczynać się od 0. Wynika stąd, że pozornie prawidłowo zapisana liczba 09 nie jest poprawnie zbudowanym literałem Javy, gdyż cyfra 9 nie należy do systemu ósemkowego. Dużo większe znaczenie mają w informatyce liczby szesnastkowe (heksadecymalne), gdyż składają się z cyfr odpowiadających kolejnym czwórkom bitów, a jak wiadomo, długość słowa maszynowego wszystkich procesorów jest podzielna przez 4. Ponieważ dziesiętny system liczenia zawiera tylko cyfry od 0 do 9, pozostałych sześć cyfr systemu

14 Wykład Java ver szesnastkowego, od 10 do 15, zapisuje się za pomocą liter od A do F (ich wielkość nie ma znaczenia). Przed każdym literałem szesnastkowym muszą występować znaki Ox lub OX. Jak więc z tego wynika. Literały całkowite Javy są typu int, w związku z czym zajmują 32 bity, a więc umożliwiają zapisywanie liczb należących do przedziału od około -2 do +2 miliardów. Jeżeli jest on niewystarczający, to trzeba utworzyć wartość typu Iong, dopisując na końcu literału literę L lub l, na przykład Ox7FFFFFFFFFFFL. Ponieważ typ Iong zajmuje 64 bity, to można dzięki niemu tworzyć literały o maksymalnej wartości wynoszącej aż około 9 trylionów (9*10 18 ). Literały zmiennoprzecinkowe Literały zmiennoprzecinkowe reprezentują liczby dziesiętne z częścią ułamkową. Można je zapisywać na dwa sposoby: w postaci standardowej i wykładniczej. Zapis standardowy składa się z cyfr oznaczających część całkowitą (początkowe zero można pominąć), kropki dziesiętnej (odpowiednika przecinka dziesiętnego w krajach anglosaskich) i cyfr oznaczających część ułamkową, na przykład 2.0, i Zapis wykładniczy zawiera dodatkowo literę E lub e oraz liczbę oznaczającą wykładnik potęgi (dodatni lub ujemny), do której należy podnieść liczbę 10, na przykład 6.022E23 (= 6,022 * ), E-5 (= *10-5 lub 2e+100 (= 2 * ). Literały Logiczne Istnieją tylko dwa literały logiczne (boolowskie), czyli wartości, jakie mogą przyjmować wyrażenia typu boolean: true i false. Inaczej niż w językach C/C++, nie mają one odpowiedników w postaci wartości całkowitych: true nie jest równe 1, a false to nie 0. Wynika stąd, że zmiennym typu boolean nie wolno przypisywać wartości numerycznych, a jedynie wymienione dwa literały logiczne Literały znakowe W Javie można zapisywać wszystkie znaki należące do zestawu Unicóde. Są one reprezentowane przez liczby 16-bitowe, które można przekształcać do typu int i wykonywać na nich działania za pomocą operatorów całkowitych. Literały znakowe umieszcza się między apostrofami. Wszystkie drukowalne (dające się wyświetlić i wydrukować) znaki ASCI I można zapisywać bezpośrednio, na przykład 'a', 'z' czy '@'. Natomiast znaki, które nie mają odpowiadających im klawiszy, zapisuje się w postaci tak zwanych sekwencji escape; na przykład '\" to apostrof, a '\n' znak nowego wiersza. Istnieje również możliwość bezpośredniego określania wartości liczbowej zapisywanego znaku.

15 Wykład Java ver Zapis ósemkowy składa się ze znaku \ i trzech cyfr, na przykład '\141' oznacza literę a. Natomiast użycie liczby szesnastkowej wymaga wpisania znaków \u, a następnie 4 cyfr szesnastkowych. Na przykład '\u0061' oznacza literę a (pierwsze dwa zera charakteryzują zestaw znaków ISO-Latin-1), natomiast '\ua432'-jeden ze znaków alfabetu japońskiego Katakana. Wszystkie sekwencje escape zostały zestawione w Tabela 1. Sekwencje Escape są podobne do stałych znakowych języka C/C++ z ukośnikiem wstecznym. Tabela 1 Sekwencja Escape Sekwencja Escape \ddd Znak ósemkowy (ddd) \uxxxx Znak heksadecymalny UNICODE (xxxx) \' Apostrof \" Cudzysłów \\ Ukośnik tylny (ang. Backslash) \r Znak powrotu karetki, CR (ang. Carriage return) \n Znak nowego wiersza, LF (ang. Line feed) \f Znak nowej strony, FF (ang. Form feead) \t Znak tabulacji poziomej, HT (ang. Horizontal tab) \b Znak cofania, BS (ang. Backspace) Standard kodowania - Unikod (Unicode) Unikod (Unicode) jest sposobem kodowania obejmującym praktycznie wszystkie znaki używane na całym świecie. W skład Unikodu wchodzą również symbole np. techniczne, muzyczne i itp. Ogólem w wersji 3.0 Unikodu jest prawie 50 tyś. znaków. Unikod jednoznacznie identyfikuje symbol. Pozwala to swobodne umieszczać znaki różnych krajów razem, bez obaw o pomyłki. Zestaw polskich znaków UNICODE. Znak heksadecymalny: UNICODE: \u... dziesiętny: ą ć ę ł ń ó F

16 Wykład Java ver ś ź ż Ą Ć Ę Ł Ń Ó Ś Ż Ź 015B 017A 017C D3 015A B Jak używać UNICODE Użycie UNICODE w programach Java jest bardzo proste. Jeżeli chcemy, aby np. tekst w polu typu Label zawierał polski znak, znak ten zamieniamy na odpowiednią wartość UNICODE. Label lb1 = new Label(); lb1.settext("nowo\u015bci"); Znak "ś" w słowie "Nowości" został zamieniony Sposoby kodowania Ze względu na to iż nie wszystkie dostępne systemy i programy zdolne są do wspierania Unikodu w pełnym zakresie oraz dla zapewnienia bezproblemowego transferu danych przy użyciu takich systemów określono kilka sposobów kodowania: UTF-7 - format 7-bitowy UTF-8 - format 8-bitowy UTF-16 - format 16-bitowy występujący w dwóch odmianach różniących się kolejnością ułożenia bajtów w słowie:

17 Wykład Java ver Literały Łańcuchowe Literały łańcuchowe Javy wyglądają tak samo jak we wszystkich innych językach programowania, czyli znajdują się w cudzysłowie. Fakt, że dla każdego z nich jest tworzony oddzielny obiekt, pozostaje dla programisty niewidoczny. Można korzystać ze wszystkich sekwencji escape zdefiniowanych dla pojedynczych znaków. Do przykładów poprawnie zbudowanych literałów łańcuchowych należą między innymi: Witamy wszystkich, "dwa\nwiersze" i "\ "Ten tekst jest w cudzysłowie \ "". Każdy literał musi znajdować się w całości w jednym wierszu; nie istnieje znak kontynuacji wiersza, spotykany w niektórych innych językach programowania. Operatory Operatory są elementami leksykalnymi języków programowania, które pobierają jeden lub więcej argumentów (operandów) i generują określony wynik. Umieszcza się je obok identyfikatorów i literałów, zwykle między nimi. Operatory to specjalne znaki instruujące kompilator, aby wykonał określoną operację na operandach, będących zmiennymi, wyrażeniami lub literałami. W Javie istnieją operatory jedno- i dwuargumentowe oraz jeden trójargumentowy. Niektóre operatory jednoargumentowe umieszcza się przed operandem, a inne za nim; pierwsze z nich nazywa się operatorami przedrostkowymi (ang. prefix), drugie - przyrostkowymi (ang. postfix). Operatory dwu- i trójargumentowe znajdują się zawsze między operandami, dlatego są one określane mianem operatorów wrostkowych (ang. infix). Operatory dwuargumentowe umożliwiają wykonywanie działań znanych powszechnie z arytmetyki, takich jak dodawanie czy mnożenie. W Javie istnieją łącznie 44 operatory. Można je podzielić na cztery następujące grupy: operatory arytmetyczne, bitowe, relacyjne i logiczne. Dla każdego operatora jest określony typ operandów i rodzaj wykonywanej operacji. Nieraz działanie operatora zależy od typu jego operandów. Tabela 2 Operatory Javy Priorytet Operator Priorytet Operator 1. [] () 9 ^ ! ~ instanceof 10 3 * / % 11 && << >> >>> 13?:

18 Wykład Java ver < > <= >= 14 = op= 7 ==!= 15, 8 &

19 Wykład Java ver Tabela 3 Operatory Bitowe Javy. Operator & Działanie Koniunkcja, AND Alternatywa,OR Różnica symetryczna, XOR ^ ~ Uzupełnienie do 1, NOT >> Przesunięcie w prawo << Przesunięcie w lewo >>> Przesunięcie w prawo bez znaku <<< Przesunięcie w lewo bez znaku Operator Działanie - odejmowanie, również minus jednoargumentowy, + dodawanie, * mnożenie, / dzielenie, % dzielenie modulo, oblicz resztę z dzielenia. W przeciwieństwie do C/C++, można go stosować nie tylko z typami całkowitymi, ale także z typami zmiennoprzecinkowymi -- dekrementacja (zmniejszenie o 1), ++ inkrementacja (zwiększanie o 1). Rysunek 1Operatory arytmetyczne Javy.

20 Wykład Java ver Operatory relacyjne Operator Działanie > większy, >= większy lub równy, < mniejszy, <= i mniejszy lub równy, == równy,!= różny, Operatory logiczne Operator Działanie && koniunkcja, AND alternatywa, OR! negacja, NOT?: trójargumentowy operator if then-else Rysunek 2 Operatory relacyjne i logiczne Javy.

21 Wykład Java ver Separatory Poza wymienionymi, istnieje jeszcze tylko kilka innych sekwencji znaków, które mogą występować w poprawnie zbudowanym programie Javy. Są to tak zwane separatory, umożliwiające oddzielenie od siebie poszczególnych elementów leksykalnych języka. Ich postać i przeznaczenie zostały przedstawione w Tabela 4. Tabela 4 Sepatatory Javy. Symbol Nazwa Przeznaczenie () Nawiasy Okrągłe 1. Zapisywanie parametrów w definicjach metod i przekazywanie metodom argumentów. 2. Zmiana kolejności wykonywania działań w wyrażeniach. 3. Zapisywanie wyrażeń w instrukcjach sterujących. 4.Rzutowanie typów. { Nawiasy klamrowe 1. Definiowanie bloków instrukcji, na przykład klas, metod i instrukcji złożonych 2. Zapisywanie wartości automatycznie inicjalizowanych tablic [] Nawiasy kwadratowe Deklarowanie typów tablicowych i odwoływanie się do elementów tablic ; Średnik Część składowa instrukcji, Przecinek l. Oddzielanie identyfikatorów w deklaracji zmiennych tego samego typu. 2.Oddzielanie instrukcji znajdujących się wewnątrz instrukcji for.. Kropka Oddzielanie nazw klas od nazw podklas i metod oraz nazw obiektów od nazw metod i zmiennych egzemplarzowych.

22 Wykład Java ver Zmienne Zmienne można określić jako podstawowe jednostki pamięci wykorzystywanej przez program. Każdą zmienną Javy deklaruje się przez określenie jej nazwy (identyfikatora), typu i dostępu. Ten ostatni atrybut zależy zarówno od położenia deklaracji zmiennej, jak i od użytych modyfikatorów. Istnieją na przykład zmienne dostępne tylko wewnątrz określonej instrukcji złożonej, takiej jak for, zmienne dostępne w pojedynczej metodzie lub klasie, zmienne dostępne w całym programie itp. Deklarowanie zmiennych Ogólna postać deklaracji jednej lub większej liczby zmiennych wygląda następująco: typ identyfikator [=wartość][,identyfikator [=wartość]...]; Za słowo typ można podstawić jeden z ośmiu podstawowych typów danych podanych w Tabela 5 lub nazwę określonej klasy lub interfejsu. Tabela 5 Osiem podstawowych typów danych (typy proste) Typ danych Znaczenie Zakres Rozmiar (w bitach) boolean wartości true/false 8 byte liczba całkowita mała char znak 16 short Liczba całkowita krótka ( int liczba całkowita ( ) 32 long liczba całkowita długa float liczba zmiennoprzecinkowa pojedynczej precyzji 3,4* ,4* void - - double liczba zmiennoprzecinkowa podwójnej precyzji 1,7* ,7* Najczęściej używanymi typami są typy całkowite. Większość programistów zwykle nie zastanawia się nawet, czy ich dopuszczalny zakres jest wystarczający, ponieważ służą one najczęściej do zapisywania niewielkich wartości. Zresztą w większości języków programowania dopuszczalny zakres poszczególnych typów nie jest dokładnie określony. Inaczej wygląda sytuacja w Javie - tutaj szerokość poszczególnych typów (liczba bitów) jest dokładnie określona; na przykład liczby typu int zajmują zawsze 32 bity.

23 Wykład Java ver Bezpieczeństwo i niezawodność programów Javy wynika między innymi ze ścisłej kontroli typów. Kompilator sprawdza, czy wartości przypisywane zmiennym i wyrażeniom są zgodne z ich typami; sprawdzenia takie są dokonywane zarówno w instrukcjach przypisania, jak i w wywołaniach metod. W przeciwieństwie do niektórych innych języków programowania, nigdy nie zachodzi automatyczna konwersja niezgodnych typów. Użycie niewłaściwego typu nie powoduje wygenerowania ostrzeżenia, lecz komunikatu o błędzie, co uniemożliwia skompilowanie danej klasy. Z każdym typem jest związany określony zbiór wartości, które może on reprezentować, oraz zestaw operacji, które można wykonywać na jego zmiennych. Na przykład dozwolone jest dodawanie liczb typu int czy float, ale nie wartości typu boolean. Typy numeryczne służą do zapisywania liczb. Są one potrzebne podczas wykonywania każdego działania arytmetycznego, zarówno do przechowania jego argumentów, jak i wyniku. Istnieją dwa rodzaje typów numerycznych: całkowite i zmiennoprzecinkowe. Pierwsze z nich umożliwiają, zgodnie z nazwą, zapisywanie liczb całkowitych, a drugie rzeczywistych, czyli posiadających część ułamkową. Dla każdego typu numerycznego jest dopuszczalny zakres wartości, a dla typów zmiennoprzecinkowych dodatkowo największa dokładność, czyli maksymalna liczba cyfr po przecinku. To, z którego typu należy skorzystać, zależy od danej aplikacji. W Javie istnieją wszystkie typy numeryczne standardu ANSI C. Jedyna różnica, jaka istnieje między tymi językami, polega na tym, że w Javie wszystkie typy numeryczne mają ściśle określoną szerokość (zakres i dokładność). Natomiast w C liczba bitów przydzielanych poszczególnym typom zależy od danej implementacji kompilatora. Zmienna szerokość typu int, dostosowywana do długości słowa maszynowego, stanowi główną przyczynę braku przenośności programów C. Pod pojęciem słowa maszynowego rozumiemy liczbę bitów rejestrów wewnętrznych procesora, stosowanych do zapamiętywania liczb i wykonywania na nich operacji arytmetycznych. W latach siedemdziesiątych długość słowa maszynowego większości komputerów osobistych wynosiła 8 bitów. Lata osiemdziesiąte przyniosły zaprojektowanie procesorów 16 bitowych rodziny Wraz z pojawieniem się procesorów 486 i Pentium, standardem stały się 32-bitowe słowa maszynowe. Wreszcie, rozpoczęcie produkcji układów Pentium Pro i UItraSPARC rozpoczęło erę komputerów 64-bitowych. Tak więc, w zależności od użytego kompilatora, typ int języka C jest zdefiniowany jako 16, 32 lub 64 bity. Deklarując zmienną typu int, programista C zdaje się mówić kompilatorowi: przydziel mi liczbę bitów odpowiadającą długości słowa

24 Wykład Java ver maszynowego. Rozwiązanie to ma tę zaletę, że gwarantuje największą efektywność programów. Zupełnie inaczej funkcjonuje Java - tutaj typ int zajmuje zawsze 32 bity, niezależnie od tego, na jakim komputerze są uruchamiane programy. Oczywiście prawdą jest, że aplikacja napisana dla komputera 64-bitowego działałaby szybciej, gdyby kompilator przydzielał zmiennym typu int po 64 bity. Wówczas jednak stracilibyśmy jej niezależność od sprzętu, gdyż w inny sposób mogłaby ona działać na komputerach 32-bitowych, a w inny na komputerach 64-bitowych. Na przykład mogłoby się okazać, że zbyt mała liczba bitów spowodowałaby wystąpienie nadmiaru lub niedomiaru. Ściśle określona szerokość typów jest więc jedną z tych właściwości Javy, gdzie niezależność od sprzętu zwyciężyła nad efektywnością. Zmienne globalne W czasach panowania FORTRAN-u, kiedy "prawdziwi mężczyźni" programowali w asemblerach, a tekst programów zapisywano na kartach perforowanych, zmienne globalne były na porządku dziennym. Dlatego możliwość stosowania ich przewidziano także w języku C, choć wprowadzono dodatkowe ograniczenie, polegające na konieczności deklarowania ich typu. Problem towarzyszący używaniu zmiennych globalnych polega oczywiście na tym, że można do nich uzyskać dostęp z każdego miejsca programu. W ten sposób powstaje wiele błędów, czasami o katastrofalnych skutkach, polegających na przykład na przypadkowej zmianie stanu programu. Istnienie zmiennych globalnych w programie C++ świadczy o tym, że nie wykorzystano w nim w pełni możliwości programowania zorientowanego obiektowo, a dokładniej - że nie dokonano w wystarczającym stopniu enkapsulacji danych. W Javie jedynymi nazwami globalnymi są nazwy klas. Zdefiniowanie zmiennej poza klasą jest po prostu niemożliwe. Co prawda, istnieje możliwość deklarowania statycznych zmiennych publicznych, które w praktyce zachowują się tak samo, jak zmienne globalne, ale używanie ich nie jest zalecane. Zresztą, nawet, jeśli zmienne takie istnieją, to są one zawsze przydzielone do określonej klasy. Typy całkowite Ponieważ programiści C/C++ używają często zmiennych całkowitych do zapisywania masek bitowych, wartości kolorów i innych liczb przyjmujących wyłącznie wartości dodatnie, wprowadzono modyfikator typu unsigned.. W Javie modyfikator taki nie istnieje, a wszystkie zmienne całkowite mogą przyjmować zarówno wartości dodatnie, jak i ujemne. O znaku liczby decyduje zawsze pierwszy bit z lewej strony (dla liczb dodatnich jest równy ), a dla ujemnych 1). Tak więc )x80 to w Javie -1.

25 Wykład Java ver Typ byte Typ byte zajmuje 8 bitów, umożliwia więc zapisywanie liczb z zakresu od -128 do 127. Najbardziej nadaje się do wczytywania danych z plików lub sieci, gdyż umożliwia rozpoznawanie protokołów sieciowych i formatów plików. Oprócz tego używa się go do wykonywania operacji bitowych. Poza tymi przypadkami, a więc na przykład podczas wykonywania typowych obliczeń, należy unikać stosowania typu byte, a zamiast niego korzystać z omówionego niżej typu int. Podane niżej dwie instrukcje przykładowe deklarują zmienne b i c typu byte oraz przypisują drugiej z nich wartość szesnastkową 0x55. byte b; byte c = 0x55; Typ short Typ short jmuje 16 bitów, w związku z czym umożliwiają zapisywanie liczb z zakresu od do Jest najrzadziej używanym typem Javy, ponieważ charakteryzuje się zapisywaniem bajtów w innej kolejności, niż na komputerach z procesami Intela (najpierw bardziej znaczącego bajtu, a potem mniej znaczącego). Oto dwa przykłady deklaracji zmiennych typu short: short s; short t=0x55aa; Istnieją dwa sposoby zapisywania w pamięci liczb zajmujących więcej niż jeden bajt, czyli takich, jak short, int czy long. Różnią się one kolejnością zapisywania bajtów tworzących daną liczbę. Jeden z nich, stosowany między innymi w komputerach SPARC i PowerPC, polega na tym, że jako pierwszy zapisywany jest najbardziej znaczący bajt, a jako ostatni najmniej znaczący. Inne rozwiązanie przyjęto w komputerach z procesorem Intela; charakteryzuje się ono tym, że bajty zapisywane są w kolejności od najmniej do najbardziej znaczącego. Istnieją dwa sposoby zapisywania w pamięci liczb zajmujących więcej niż jeden bajt, czyli takich, jak short, int czy long. Różnią się one kolejnością zapisywania bajtów tworzących daną liczbę. Jeden z nich, stosowany między innymi w komputerach SPARC i PowerPC, polega na tym, że jako pierwszy zapisywany jest najbardziej znaczący bajt, a jako ostatni najmniej znaczący. Typ int

26 Wykład Java ver Typ int zajmuje 32 bity, w związku z czym umożliwia zapisywanie liczb należących do zakresu od do Jest najczęściej używanym typem całkowitym. Ponieważ pozwala zapisywać bardzo duże liczby, aż do ponad 2 miliardów, to nadaje się świetnie do stosowania w pętlach i indeksowania tablic. Jego dodatkową zaletę stanowi fakt, że zapewnia on efektywne działanie programów na używanych dzisiaj najczęściej komputerach 32-bitowych oraz tych komputerach 64-bitowych, które mogą działać w szybkim trybie 32-bitowym. Każde wyrażenie, w którym występują zmienne i literały typu byte, short i int, jest automatycznie przekształcane do typu int przed rozpoczęciem wykonywania obliczeń. int i; int j = 0x55aa0000; Typ int jest najbardziej wszechstronny i efektywny ze wszystkich typów całkowitych, dlatego należy go zawsze stosować podczas wykonywania operacji arytmetycznych i indeksowania tablic. Wydawać by się mogło, że używając typu byte lub short można zaoszczędzić pamięć, ale i tak nie ma gwarancji, że Java nie przekształci ich automatycznie do typu int. W zasadzie typ określony w deklaracji zmiennej decyduje jedynie o jej zachowaniu się, a nie o liczbie bajtów, jakie będzie zajmować w pamięci. Jedynym wyjątkiem od tej reguły są tablice, których elementom jest zawsze przydzielana liczba bajtów odpowiadająca podanemu w tekście źródłowym typowi. Typ long zajmuje 64 bity, umożliwia więc zapisywanie tak olbrzymich liczb, że ich podawanie nie ma nawet sensu. Przypadki, kiedy typ int okazuje się niewystarczający i zachodzi potrzeba użycia typu long, są bardzo rzadkie. Należy do nich na przykład zliczanie milisekund w okresie roku lub dłuższym czy mnożenie bardzo dużych liczb. Oto dwa przykłady deklaracji zmiennych typu long: long m; long n=0x55aa000055bb0101; Jak już wspomniałem wcześniej, rodzaj typu całkowitego nie należy rozumieć jako liczbę przydzielanych mu bajtów pamięci, lecz jako sposób wykonywania działań na jego zmiennych i wyrażeniach. Kompilator Javy ma prawo przydzielać poszczególnym typom dowolną liczbę bajtów, dążąc do zapewnienia możliwie jak największej efektywności programów. Na przykład jego aktualna wersja implementuje typu bajt i short jako słowa 32- bitowe, gdyż taka jest właśnie długość słów maszynowych zdecydowanej większości używanych obecnie komputerów. Oczywiście nie oznacza to, że wszystkie 32 bity są wykorzystywane.

27 Wykład Java ver Przypisując zmiennej wartość przekraczającą dopuszczalny zakres jej typu, powoduje się obcięcie nadmiernej liczby bitów, czyli wykonanie odpowiedniej operacji modulo (operacji dającej w wyniku resztę z dzielenia). Na przykład, jeżeli zmienna x jest typu byte, to instrukcja x = 257 powoduje zapisanie w niej liczby 1. (gdyż = ). Zakresy poszczególnych typów całkowitych różnią się w znacznie większym stopniu, niż wynikałoby to z porównania ich szerokości. Aby to sobie lepiej wyobrazić, załóżmy, że liczymy mijające sekundy. Typ byte umożliwia zapisanie kilku minut, short całego dnia, int przeciętnej długości życia człowieka, a long- więcej niż istnienie wszechświata! Typy zmiennoprzecinkowe Liczb zmiennoprzecinkowych, zwanych w matematyce oraz w niektórych językach programowania liczbami rzeczywistymi, używa się na przykład podczas obliczania pierwiastka kwadratowego liczby lub wykonywania funkcji trygonometrycznych, takich jak sinus czy cosinus. W Javie jest zaimplementowany zestaw typów i operatorów zmiennoprzecinkowych zgodny ze standardem IEEE-754. Istnieją dwa typy zmiennoprzecinkowe: float i double; ich szerokość i typ zostały podane w Tabela 5. Rzutowanie typów Rzutowanie typów z C zostało przeniesione do Javy. Zdarzają się bowiem sytuacje, w których wartość określonego typu trzeba zapisać w zmiennej innego typu. Jeżeli zakres i dokładność zmiennej docelowej są na tyle duże, że można w niej zapisać wartość źródłową bez utraty informacji, to kompilator dokonuje automatycznej konwersji typów. Dzieje się tak na przykład' podczas zapisywania wartości typu byte w zmiennej typu int. Tego typu konwersja nazywa się poszerzaniem (ang. widening lub promotion) typów, gdyż węższy typ jest przekształcany w szerszy. W przypadku przeciwnym, czyli podczas zapisywania wartości typu szerszego w zmiennej typu węższego konieczne jest jawne rzutowanie typu. Na przykład, aby zapi- sać liczbę typu int w zmiennej typu byte, trzeba rzutować typ int do typu byte. Operację taką nazywa się nieraz zawężaniem (ang. narrowing) typów, gdyż polega ona na świadomym zmniejszaniu liczby bitów danej wartości, aby zmieścić ją w zmiennej węższego typu. Typ docelowy rzutowania umieszcza się w nawiasach przed wartością źródłową, na przykład (byte) value. Podane niżej instrukcje pokazują rzutowanie typu int do typu byte

28 Wykład Java ver int a = 100: byte b = (byte) a: Automatyczna konwersja typów w wyrażeniach Typy wyników częściowych obliczeń muszą często zapewniać większy zakres i dokładność niż typ wyniku końcowego. Przyjrzyjmy się na przykład podanemu niżej przykładowi, w którym wszystkie argumenty są deklarowane jako zmienne typu byte: byte a = 40; byte b = 50; byte c = 100; int d = a * b / c; Ponieważ jest bardzo prawdopodobne, że wynik mnożenia a * b przekroczy dopuszczalny zakres typu byte, kompilator Javy automatycznie przekształca go do typu wyniku (zmiennej d), czyli do typu int. Konwersja taka przydaje się między innymi w podanym przykładzie, w którym a * b = 2000, gdy tymczasem typ byte pozwala jedynie na zapisywanie liczb z zakresu od -128 do 127. Czasem jednak automatyczna konwersja typów powoduje niespodziewane błędy. Dzieje się tak wtedy, gdy w wyrażeniach występują nie tylko zmienne, ale także literały. Przypomnijmy, że wszystkie literały całkowite, za którymi nie występuje litera L, są traktowane jako liczby typu int, a literały zmiennoprzecinkowe bez końcowej litery F - jako liczby typu double; litera L oznacza typ long, a F - float. Zwróćmy na przykład uwagę na pozornie poprawne, następujące instrukcje: byte b = 50; b = b * 2; ^ Incompatible type for =.. Explicit cast needed to convert int to byte. Błąd zasygnalizowany przez kompilator wynika z faktu, że liczba 2 jest traktowana jako wartość typu int, w związku z czym do tego typu jest również przekształcane wyrażenie b * 2. Powoduje to próbę zapisania wartości typu int w zmiennej typu byte, czego nie wolno wykonywać bez jawnej konwersji ze względu na możliwość utraty informacji. Co prawda, w tym przypadku wynik mnożenia, 100, jest mniejszy od maksymalnej wartości typu bajt, ale oczywiście nie można tego traktować jako reguły. Dlatego podane instrukcje należy zapisać w następujący sposób: byte b = 50; b = (byte) (b * 2) ;

29 Wykład Java ver Typ każdego wyrażenia jest zawsze automatycznie przekształcany do najszerszego typu występujących w nim zmiennych i literałów. Na przykład, jeśli w wyrażeniu występują zmienne typu byte, short i int, to całe wyrażenie uzyskuje typ int; jeśli obecna jest przynajmniej jedna zmienna typu long, to i całe wyrażenie jest tego typu. W przypadku, gdy wyrażenie zawiera wartości całkowite i zmiennoprzecinkowe, typem wynikowym jest typ szerszy zmiennoprzecinkowy. Oznacza to na przykład, że wynik operacji wykonanej na zmiennych typu int i float jest typu float. Podana niżej definicja klasy jest przykładem wielokrotnej automatycznej konwersji typów: class poszerzanie {public static void main(string args[]) { byte b=42; char c='a'; short s=1024; int i=50000; float f=5.67f; double d=.1234; double wynik =(f*b)+(i/c)-(d*s); System.out.println((f*b)+"+"+(i/c)+"-"+(d*s)); System.out.println("Wynik="+wynik); b=(byte)(b*2); System.out.println(b/2+"*2="+b); Zakres zmiennych Instrukcje złożone, czyli sekwencje instrukcji prostych, rozpoczynają się i kończą nawiasami klamrowymi. Każda zmienna jest widoczna (dostępna) od miejsca jej deklaracji do końca zawierającej ją instrukcji złożonej. Instrukcje złożone mogą być zagnieżdżone, czyli w jednej instrukcji złożonej może występować inna, i każda z nich może zawierać własne zmienne lokalne; niedozwolone jest jednak stosowanie w odniesieniu do nich takich samych identyfikatorów. Podana niżej definicja klasy jest nieprawidłowa, gdyż występują w niej deklaracje dwóch zmiennych o takiej samej nazwie. Instrukcje takie można by natomiast umieścić w programie C lub C++, ponieważ obie zmienne bar mają różne zakresy. class zakres {public static void main(string args[]) {int bar=1;

30 Wykład Java ver {int bar=2; //Utworzenie nowego zakresu //bład komplacji Tablice Na pierwszy rzut oka wydaje się, że tablice Javy funkcjonują w taki sam sposób jak tablice C++. Należy jednak być ostrożnym, gdyż między tablicami występującymi w obu tych językach istnieją mało zauważalne, choć ważne różnice. Tablice jednowymiarowe Aby utworzyć tablicę, należy najpierw utworzyć zmienną tablicową odpowiedniego typu. Ogólna postać deklaracji jednowymiarowej tablicy wygląda następująco: typ nazwa zmiennej[]; Słowo typ oznacza tu typ bazowy tablicy. Zauważmy, że między nawiasami kwadratowymi nie ma wymiaru; jest to spowodowane tym, że podaje się go w późniejszej instrukcji. Typ bazowy tablicy określa typ każdego jej elementu, czyli - innymi słowy - typ danych, które będą w tej tablicy zapisywane. Na przykład podana niżej instrukcja deklaruje tablicę liczb całkowitych (typu bazowego int), o nazwie numbers: int numbers[]; Mimo iż deklaracja ta tworzy zmienną tablicową numbers, to jednak po jej wykonaniu nie istnieje jeszcze żadna tablica. Zmiennej numbers jest bowiem przypisywana wartość początkowa null, reprezentująca tablicę nie zawierającą żadnego elementu. Aby powiązać zmienną numbers z rzeczywistą tablicą liczb całkowitych, należy przydzielić jej pamięć za pomocą operatora new. Ogólna postać operatora new zastosowanego do tablicy jednowymiarowej wygląda następująco: zmienna tablicowa = new typ[rozmiar]; Tutaj słowa typ i rozmiar określają typ i liczbę elementów tablicy, a zmienna_tablicowa jest zmienną tablicową, która ma zostać powiązana z tworzoną tablicą. Jak więc widać, użycie operatora new w celu utworzenia tablicy wymaga podania typu i liczby jej elementów. Wszystkie elementy tablicy tworzonej za pomocą operatora new uzyskują wartości początkowe równe zeru. Podana niżej instrukcja tworzy tablicę liczb całkowitych i wiąże ją ze zmienną numbers: numbers = new int[100];

31 Wykład Java ver Po wykonaniu tej instrukcji zmienna numbers będzie odwoływać się do tablicy 100 elementów całkowitych, przy czym na początku będą one wszystkie równe zeru. Streśćmy podane wyżej informacje. Tworzenie tablicy jest procesem dwuetapowym: najpierw trzeba zadeklarować zmienną odpowiedniego typu tablicowego, a następnie przydzielić tablicy pamięć za pomocą operatora new i przypisać ją zadeklarowanej wcześniej zmiennej. Tak więc, w Javie wszystkie tablice - podobnie jak obiekty - są tworzone dynamicznie. Po utworzeniu tablicy można z niej korzystać tak samo, jak z tablic C++. Do elementów wspólnych obu języków należy między innymi fakt, że indeksy tablicy rozpoczynają się od zera i że w celu uzyskania dostępu do określonego elementu tablicy należy umieścić jego indeks w nawiasach kwadratowych. Na przykład pierwsza z podanych niżej instrukcji przypisuje wartość 28 drugiemu elementowi tablicy numbers, a druga wyświetla wartość czwartego elementu: numbers[1]=28; System.out.println(numbers[3]); Poniższy przykład pokazuje sposób tworzenia tablic jednowymiarowych class tablica {public static void main(string args[]) { int numbers[]; numbers=new int[100]; int i; for(i=0;i<100;i++) numbers[i]=i*i; for(i=0;i<100;i++) System.out.println("Kwadrat liczby "+i+" wynosi:"+numbers[i]); druga wersja tego programu class tablica1 { public static void main(string args[]) { int numbers[]=new int[100]; // istnieje możliwość połączenia deklaracji zmiennej tablicowej z przydzielaniem pamięci //samej tablicy int i;

32 Wykład Java ver for(i=0;i<100;i++) numbers[i]=i*i; for(i=0;i<100;i++) System.out.println("Kwadrat liczby "+i+" wynosi:"+numbers[i]); Deklarowane tablice można jednocześnie inicjalizować, przy czym proces ten przebiega niemal tak samo, jak w C++. Kompilator Javy tworzy na tyle dużą tablicę, aby można w niej było pomieścić wszystkie wyszczególnione wartości. W tym przypadku nie ma potrzeby stosowania operatora new. Na przykład podany niżej program inicjalizuje tablicę 10 liczb całkowitych: class tablica2 {public static void main(string args[]) { int numbers[]={0,1,2,3,4,5,6,7,8,9; //przy takiej deklaracji tablicy operator new jest zbędny int i; for(i=0;i<10;i++) System.out.println("Kwadrat liczby "+i+" wynosi:"+numbers[i]); Java nie dopuszcza do przekroczenia granic tablic. Mówiąc inaczej, podczas wykonywania programu sprawdzana jest poprawność operacji wykonywanych na tablicach w celu wykrycia ewentualnych błędów polegających na zastosowaniu nieodpowiednich wartości indeksów (pod tym względem Java zdecydowanie różni się od języków C/C++, które charakteryzują się brakiem wykrywania błędów przekroczenia zakresu tablicy). Na przykład w podanym wyżej programie nie jest możliwe uzyskanie dostępu do elementu tablicy numbers o indeksie nie należącym do zakresu od 0 do 9. Próba wykonania takiego działania spowodowałaby zasygnalizowanie błędu.

33 Wykład Java ver Tablice wielowymiarowe W Javie wielowymiarowe tablice są właściwie tablicami tablic. Mimo iż wykazują one duże podobieństwo do tablic C++, to jednak pod pewnymi względami różnią się od nich. Aby zadeklarować zmienną oznaczającą tablicę wielowymiarową, należy określić każdy indeks przez podanie osobnej pary nawiasów kwadratowych. Na przykład podana niżej instrukcja deklaruje dwuwymiarową tablicę o nazwie tablica2d: int tablica2d[][]=new int[4][5]; Instrukcja ta przydziela pamięć tablicy o wymiarach 4x5 i przyporządkowuje ją zmiennej tablica2d. Wewnętrznie tablica ta jest realizowana jako tablica tablic liczb całkowitych. Podczas przydzielania pamięci tablicy wielowymiarowej wystarczy podać tylko pierwszy (położony najbardziej na lewo) wymiar. Pozostałe wymiary można określić później. Na przykład pierwsza z podanych niżej instrukcji przydziela pamięć jedynie pierwszemu wymiarowi tablicy tablica2d, natomiast pamięć dla pozostałych wymiarów jest przydzielana osobno: int tablica2d[][]=new int[4][]; tablica2d[0]=new int[1]; tablica2d[1]=new int[2]; tablica2d[2]=new int[3]; tablica2d[3]=new int[4]; W tej sytuacji indywidualne przydzielanie pamięci tablicom drugiego wymiaru nie przynosi żadnych korzyści, ale w innych sytuacjach działanie takie może być pożądane. Na przykład "ręczny" przydział pamięci poszczególnym tablicom pozwala określić różną liczbę elementów tablic tego samego wymiaru. To, że długość każdej tablicy może zostać ustalona

34 Wykład Java ver oddzielnie, wynika z faktu, iż -jak wiadomo - tablice wielowymiarowe Javy są w rzeczywistości tablicami tablic: Podany niżej program tworzy dwuwymiarową tablicę, dla której wartości drugiego wymiaru są różne: class tablica2dw {public static void main(string args[]) { int tablica2d[][]=new int[4][]; tablica2d[0]=new int[1]; tablica2d[1]=new int[2]; tablica2d[2]=new int[3]; tablica2d[3]=new int[4]; int i,j,k; for(i=0,k=0;i<4;i++) for(j=0;j<i+1;j++) tablica2d[i][j]=k++; for(i=0;i<4;i++){ for(j=0;j<i+1;j++) System.out.print(tablica2d[i][j]+" "); System.out.println(); Program ten wyświetla następujące dane: Czyszczenie pamięci Ponieważ tablice i obiekty są tworzone dynamicznie za pomocą operatora new, pojawia się pytanie: w jaki sposób elementy te są niszczone w celu zwolnienia zajmowanej przez nie pamięci? W niektórych językach, na przykład w C++, pamięć przydzielona obiektom dynamicznie musi być zwolniona ręcznie (w C++ za pomocą operatora delete). W Javie zastosowano inne rozwiązanie: w języku tym operacje związane ze zwalnianiem pamięci są wykonywane automatycznie, z wykorzystaniem techniki zwanej czyszczeniem pamięci lub zbieraniem odpadków (ang. garbage collection). Opiera się ona na założeniu, że jeżeli nie istnieje odwołanie do danego obiektu, to obiekt ten nie jest już potrzebny i można zwolnić przydzieloną mu pamięć.

35 Wykład Java ver W programach Javy nie trzeba więc niszczyć obiektów w taki sposób, jak w C++. Trzeba jednak pamiętać o tym, że podczas działania programu czyszczenie pamięci odbywa się sporadycznie - może się nawet zdarzyć, że ani razu. Fakt, że jeden lub więcej obiektów nie jest już wykorzystywanych, nie wystarcza do tego, by pamięć została natychmiast wyczyszczona. Zresztą, poszczególne systemy czasu przebiegu Javy stosują różne podejście do czyszczenia pamięci. Pomimo tych zastrzeżeń w większości przypadków programista Javy nie musi (i nie powinien) zajmować się niszczeniem tworzonych dynamicznie obiektów. Metoda finalize() Niektóre obiekty muszą wykonać przed zniszczeniem określone działania. Na przykład, jeżeli obiekt korzysta z zasobu nie należącego do Javy, takiego jak plik czy czcionka (font), to może być konieczne zwolnienie tego zasobu przed zniszczeniem samego obiektu. Aby umożliwić odpowiednie napisanie programu w tego typu sytuacjach, projektanci Javy wprowadzili mechanizm zwany finalizacją (ang. finalization). Pozwala on określić działania, które mają być wykonane tuż przed zniszczeniem go przez program odzyskujący odpadki (program czyszczący pamięć, ang. garbage collector). Aby skorzystać z mechanizmu finalizacji, należy zdefiniować w odpowiedniej klasie metodę finalize(). System czasu przebiegu Javy wywołuję tę metodę przed zwolnieniem pamięci przydzielonej dowolnemu obiektowi jej klasy. W metodzie finalize() należy więc umieścić instrukcje, które powinny być wykonane przed zniszczeniem obiektu. Ogólna postać metody finalize() wygląda następująco: protected void finalize() { // istukcje finalizacji Należy koniecznie pamiętać o tym, że metoda finalize() jest wywoływana tylko przed czyszczeniem pamięci. Nie jest natomiast wywoływana wtedy, gdy obiekt przestaje być dostępny dla aktualnie wykonywanego fragmentu programu. Wynika stąd, że nie można określić chwili, w której metoda ta zostanie wywołana; może się nawet zdarzyć, że nie nastąpi to ani razu. Dlatego zasoby wykorzystywane przez obiekt powinny być zwalniane przez program w inny sposób. Normalnego funkcjonowania programu nie można opierać na działaniu metody finalize().

36 Wykład Java ver if (wyrażenie) { sekwencja instrukcji1; else { sekwencja instrukcji2; if (wyrażenie) instrukcja1; else instrukcja2; wyrażenie Fałsz Prawda sekw. instrukcji 1 Stopniowanie if-else-if if (wyrażenie1) instrukcja1; else if (wyrażenie2) instrukcja2; else if (wyrażenie3) instrukcja3;... else instrukcja4; sekw. instrukcji 2 Stop Stop switch (wyrażenie){ case stała1: sekw. instrukcji1; braeak; case stała2: sekw. instrukcji2; braeak; case stała3: sekw. instrukcji3; braeak; default: sekw.instrukcji4; Prawda stała1 Fałsz Prawda stała2 Fałsz sekw. instrukcji 1 sekw. instrukcji 2 sekw. instrukcji 4 stała3 Fałsz Prawda sekw. instrukcji 3 Instrukcja Break Język Java nie zawiera instrukcji goto, która w innych językach programowania pozwala na wykonanie skoku (przejście) do dowolnego miejsca programu. Stosowanie jej zmniejsza czytelność tekstu źródłowego i uniemożliwia wykonanie pełnej optymalizacji kodu wynikowego przez kompilator. Istnieją jednak takie sytuacje, w których użycie instrukcji sterującej goto lub jej odpowiednika jest uzasadnione, a nawet potrzebne. W Javie we wszystkich tych przypadkach stosuje się instrukcję break. Nakazuje ona kompilatorowi przejście do pierwszej instrukcji znajdującej się za instrukcją złożoną o podanej nazwie. Nazwy instrukcji definiuje się za pomocą etykiet (ang. labels). Etykieta musi być poprawnie zbudowanym identyfikatorem i znajdować się przed daną instrukcją. Bezpośrednio za definiowaną etykietą umieszcza się dwukropek; znaku tego nie podaje się jednak podczas odwoływania się do etykiety w instrukcji break.

37 Wykład Java ver class break1{public static void main(string args[]) { int i=1; int k=10; Etykieta: { while(i++<100) { if (k--==0) break Etykieta; System.out.println("i="+i+";k="+k+": i*k="+i*k); // wyświetlenie na ekranie wyniku mnożenia //Tu zostałoby przekazane sterowanie gdyby instrukcja //break nie miała etykiety Etykieta. System.out.println(" Koniec"); //koniec bloku instrukcji //Tu zostaje przekazane sterowanie programem po wykonaniu //instrukcji break Etykieta java break1 Wynik zadziałania programu: i=2;k=9: i*k=18 i=3;k=8: i*k=24 i=4;k=7: i*k=28 i=5;k=6: i*k=30 i=6;k=5: i*k=30 i=7;k=4: i*k=28 i=8;k=3: i*k=24 i=9;k=2: i*k=18 i=10;k=1: i*k=10 i=11;k=0: i*k=0 Instrukcja for for (inicjalizacja ; warunek ; inkrementacja) { sekwencja instrukcji1; for (inicjalizacja ; warunek ; inkrementacja) instrukcja1; for (x=0, y=0 ; x+y <10; ++x) { sekwencja instrukcji1; Fałsz inicjalizacja Stop warunek Prawda for (x=0, y=0 ; x+y <10; ++x) ; /* pętla pusta */ sek. instrukcji 1 inkrementacja

38 Wykład Java ver Instrukcja while i do-while do { sekwencja instrukcji1; while (warunek) sek. instrukcji 1 Fałsz warunek Prawda while (warunek) { sekwencja instrukcji 1 ; Fałsz warunek sek. instrukcji 1 Prawda Instrukcja return Instrukcja return umożliwia natychmiastowe zakończenie wykonywania bieżącej metody i powrót do procesu, który ją wywołał. Instrukcja continue Czasami zdarza się, że w danej iteracji trzeba pominąć wszystkie pozostałe instrukcje pętli, ale nadal w niej pozostać. Wykonanie tego działania umożliwia instrukcja continue. Jeżeli występuje ona w pętli while lub do-while, to powoduje przejście do instrukcji sprawdzającej warunek, natomiast jeśli jest obecna w instrukcji for, to przekazuje sterowanie do bloku inkrementacji ( wyrażenia po drugim średniku ). Podobnie jak w przypadku instrukcji break, tak i w continue można podać etykietę określającą pętlę, której wykonywanie ma być kontynuowane. Z właściwości tej korzysta podany niżej program, który wyświetla tabliczkę mnożenia w zakresie od 0 do 9. class continue1 {public static void main(string args[]) { dalej:for(int i=0;i<10;i++) for(int j=0;j<10;j++)

39 Wykład Java ver {if (j>i) {System.out.println(""); continue dalej; System.out.print(" "+(i*j)); Instrukcja continue powoduje tu zakończenie wykonywania pętli z licznikiem j i rozpoczęcie następnej iteracji pętli z licznikiem i, czyli przejście do instrukcji i++. Informacje wyświetlane przez ten program są następujące: Wynik zadziałania programu: Klasy Między C a Javą istnieje wiele podobieństw dotyczących klas; niemniej jednak występują także pewne różnice. Rozpoczynamy od wspólnych elementów klas definiowanych w programach C++ i Javy. Klasy Javy mogą zawierać zarówno zmienne składowe, jak i funkcje składowe, zwane metodami. Dostęp do poszczególnych elementów obiektów klas uzyskuje się za pomocą operatora w postaci kropki. Klasy Javy mogą zawierać konstruktory, które można przeładowywać. Dozwolone jest zresztą przeładowywanie wszystkich metod klas (przeładowywanie funkcjonuje w Javie mniej więcej tak samo jak w C++). Klasa Javy to szablon umożliwiający tworzenie obiektów i deklarowany za pomocą słowa kluczowego class. klasa stanowi narzędzie do tworzenia nowych typów danych, których elementy noszą nazwę obiektów (dla których definicja klasy stanowi wzorzec) i mogą być przypisywane zmiennym obiektowym. Definicja klasy przyjmuje następującą formę: [modyfikatory] class NazwaKlasy [extends NazwaNadklasy] [implements NazwyInterfejsów]

40 Wykład Java ver { // Ciało klasy: specyfikator dostępu typ zmienna_egzemplarzowal ; specyfikator dostępu typ zmienna_egzemplarzowa2 ; //... specyfikator dostępu typ zmienna_egzemplarzowan ; specyfikator dostępu typ nazwa_metody1(lista_parametrów){ //część główna metdoy specyfikator dostępu typ nazwa_metody2(lista_parametrów){ //część główna metdoy Elementy deklaracji pomiędzy nawiasami [ i ] są opcjonalne. Deklaracja klasy definiuje następujące jej właściwości: modyfikatory deklarują rodzaj klasy (np.: public, abstract lub final static); NazwaKlasy określa nazwę deklarowanej klasy(poprawnie zbudowany identyfikator); NazwaNadklasy jest nazwą nadklasy ("prefiksu") deklarowanej przez nas klasy; NazwyInterfejsów jest to lista, rozdzielona przecinkami, nazw interfejsów implementowanych przez naszą klasę. Dane (zmienne) zdefiniowane w klasie nazywają się zmiennymi egzemplarzowymi (ang. instance variabdes), a funkcje -jak wiemy - metodami (ang. methods). Każdy element składowy klasy można poprzedzić specyfikatorem dostępu (ang. access specifier), określającym jego zakres. Dostęp do elementu klasy, który został zmodyfikowany za pomocą słowa public, może uzyskać dostęp każda instrukcja programu. Natomiast elementy zadeklarowane jako private są dostępne jedynie dla pozostałych elementów tej samej klasy. Właśnie dlatego metoda main() musi być zawsze poprzedzona specyfikatorem public (jest ona wywoływana spoza programu - przez system czasu przebiegu Javy). Elementy klas, których dostęp nie został określony jawnie, są traktowane domyślnie jako elementy publiczne w obrębie tego samego pakietu, ale nie mogą do nich uzyskać dostępu instrukcje znajdujące się poza tym pakietem. Specyfikator dostępu musi znajdować się przed pozostałą częścią specyfikacji typu elementu składowego klasy, czyli musi występować na początku instrukcji deklaracji, tak jak w podanych niżej dwóch przykładach:

41 Wykład Java ver public int i; private double j; private int mymethod(int a, char b) { //... Mimo iż klasy Javy są bardzo podobne do klas C++, to nie sposób nie wspomnieć o trzech ważnych, dzielących je różnicach. Są one następujące: 1. W C++ można pisać funkcje nie należące do klas; w Javie nie ma takiej możliwości. 2. Każda metoda Javy musi być zdefiniowana w obrębie swojej klasy; niedozwolone jest zdefiniowanie metody na zewnątrz definicji klasy. 3. Specyfikator dostępu dotyczy tylko tego elementu klasy, przed którym występuje. Inaczej jest w C++, gdzie specyfikatory dostępu są traktowane jako nagłówki, odnoszące się do wszystkich leżących niżej deklaracji, aż do wystąpienia następnego specyfikatora w ramach ciała klasy. 4. Nazwa każdego pliku źródłowego Javy musi być taka sama, jak nazwa zdefiniowanej w nim klasy. Tak więc podaną wyżej definicję klasy Punkt trzeba umieścić w pliku Punkt.java. Zarówno w tekście źródłowym, jak i w nazwach plików rozróżniane są duże i małe litery. Definiowanie metod Metody, czyli podprogramy związane z poszczególnymi klasami, tworzą ich interfejsy. Implementacje wszystkich metod danej klasy muszą znajdować się w obrębie jej definicji, na tym samym poziomie co zmienne egzemplarzowe. Metody mogą korzystać ze zmiennych egzemplarzowych swojej klasy w taki sposób, jakby były one ich zmiennymi lokalnymi. Deklaracja metody musi określać typ zwracanej przez nią wartości, a ponadto może zawierać listę parametrów formalnych. Jej ogólna postać wygląda następująco: typ nazwa_metody(lista parametrów_formalnych) { //

42 Wykład Java ver Nie istnieją ograniczenia dotyczące typów powrotnych metod; jeżeli dana metoda nie zwraca żadnej wartości, to jej typ określa się słowem kluczowym void. Nazwa metody może być dowolnym, poprawnie zbudowanym identyfikatorem, z tym zastrzeżeniem, że żadne dwie metody lub zmienne egzemplarzowe należące do wspólnej klasy nie mogą mieć takich samych nazw. Lista parametrów formalnych składa się z oddzielonych przecinkami par identyfikatorów, z których pierwszy jest nazwą typu, a drugi nazwą parametru. Jeżeli dana metoda nie pobiera żadnych parametrów, to za jej nazwą umieszcza się w deklaracji same nawiasy. Zgodnie ze standardem ANSI C funkcje, które nie pobierają żadnych parametrów, deklaruje się przy użyci słowa void. W Javie taki zapis jest niepoprawny. Warto wspomnieć, że żadna inna metoda nie może mieć takiej samej nazwy co jej klasa. Deklaracje konstruktorów wyglądają trochę dziwnie, ponieważ nie określają typu powrotnego. Jest to spowodowane tym, że typem każdego konstruktora jest typ jego klasy. Poza tym definicje konstruktorów niczym nie różnią się od definicji wszystkich pozostałych metod. Dobrze napisany konstruktor powinien w taki sposób zainicjalizować zmienne egzemplarzowe swojej klasy, aby bez wykonywania dodatkowych działań można było od razu przystąpić do korzystania z jej metod. Przeładowywanie metod Deklaracje konstruktorów nie określają typu powrotnego. Jest to spowodowane tym, że typem każdego konstruktora jest typ jego klasy. Poza tym definicje konstruktorów niczym nie różnią się od definicji wszystkich pozostałych metod. Dobrze napisany konstruktor powinien w taki sposób zainicjalizować zmienne egzemplarzowe swojej klasy, aby bez wykonywania dodatkowych działań można było od razu przystąpić do korzystania z jej metod. Która z metod zostanie wywołana, zależy od rodzaju przekazanych jej argumentów. Liczba i typy parametrów formalnych metody nazywa się jej sygnaturą typów (ang. type signature). Argumenty przekazywane w wywołaniu przeładowanej metody muszą być zgodne z sygnaturą typów jednej z jej wersji. Zdefiniowanie dwóch metod o takiej samej nazwie i takich samych sygnaturach typów jest niedozwolone. Na rodzaj wywoływanej metody ma wpływ wyłącznie sygnatura typów. Nie mają natomiast znaczenia nazwy parametrów formalnych ani typ powrotny metody. Dlatego błędem jest zdefiniowanie dwóch metod, które różnią się tylko typem zwracanych wartości lub nazwami parametrów. Operator new

43 Wykład Java ver Podobnie jak w przypadku tablic, zadeklarowanie zmiennej typu klasy powoduje przypisanie jej wartości null. Wartość ta, zdefiniowana jako odwołanie do obiektu typu Object, jest kompatybilna z wszystkimi innymi odwołaniami do klas. Różni się jednak, podobnie jak wartość false, od zera. Podana niżej przykładowa instrukcja deklaruje zmienną p typu Punkt i powoduje przypisanie jej wartości null. Punkt p; Operator new tworzy pojedynczy egzemplarz danej klasy i zwraca wartość odwołania do niego. Innymi słowy, operator ten rezerwuje pamięć wymaganą przez obiekt i zwraca adres, za pomocą którego można do tego obiektu uzyskiwać dostęp. Na przykład podana niżej instrukcja tworzy obiekt klasy Punkt i zapisuje wartość odwołania do niego w zmiennej p. Punkt p = new Punkt(); Jak wynika z podanych informacji, w Javie w inny sposób korzysta się z typów prostych i z typów klas. Mimo iż zmienna p z poprzedniego przykładu została zadeklarowana jako zmienna typu klasy, to nie jest obiektem, lecz jedynie odwołaniem do niego. Istnieje możliwość tworzenia wielu odwołań do tego samego obiektu. Na przykład podane niżej instrukcje tworzą jeden obiekt typu Punkt oraz dwa odwołania do niego. Punkt p = new Punkt(); Punkt p2 = p; Zapisanie wartości zmiennej p w zmiennej p2 nie powoduje zarezerwowania dodatkowej pamięci lub przekopiowania jakiejkolwiek części obiektu wskazywanego przez p. Przez przypisanie zmiennej p2 innej wartości, tak jak w podanym niżej przykładzie, można ją "odłączyć" od tego obiektu, nie wprowadzając do niego żadnej zmiany. Punkt p = new Punkt(); Punkt.p2 = p; p = null; Po wykonaniu ostatniej instrukcji zmienna p ma wartość null, ale zmienna p nadal wskazuje na obiekt utworzony za pomocą operatora new. Jeżeli obiekt nie jest wskazywany przez żadną zmienną, to Java automatycznie usuwa go, zwalniając całą zajmowaną przez niego pamięć. Działanie to nazywa się czyszczeniem pamięci (ang. garbage collection).

44 Wykład Java ver Dostęp do zmiennych i metod obiektów uzyskuje się za pomocą operatora oznaczanego kropką. Ogólna postać wyrażenia uzyskującego dostęp do zmiennej egzemplarzowej wygląda następująco: odwołanie_do_obiektu.nazwa_zmiennej; Zmienna znajdująca się z lewej strony operatora kropka musi być odwołaniem do obiektu utworzonego za pomocą operatora new, a identyfikator z prawej strony - nazwą jednej z jego zmiennych egzemplarzowych. Podany niżej fragment programu pokazuje przykład przypisywania zmiennym egzemplarzowym nowych wartości. p.x = 10; p.y = 20; W kolejnej przykładowej instrukcji operator kropka umożliwia odczytanie wartości zmiennych obiektu p i wyświetlenie ich na ekranie. System.out.println("x = " + p.x + ", y = " + p.y); Operator kropka umożliwia nie tylko uzyskiwanie dostępu do zmiennych egzemplarzowych klas, ale także wywoływanie ich metod. W poprzednim przykładzie utworzyliśmy pojedynczy obiekt, do którego odwoływały się dwie zmienne. Jednak języki zorientowane obiektowo, w tym Java, pozwalają tworzyć wiele obiektów tej samej klasy, z których każdy otrzymuje własny zestaw zmiennych egzemplarzowych. Dlatego zmiany wprowadzone do zmiennych jednego obiektu nie wpływają na postać pozostałych. Na przykład podany niżej program tworzy trzy obiekty klasy Punkt, umożliwiając reprezentowanie trzech różnych punktów. plik:dwapunkty.java class dwapunkty {public static void main(string args[]) {Punkt p1=new Punkt(10,55); Punkt p2=new Punkt(); Punkt p3=new Punkt(); Punkt3D h1=new Punkt3D(111,222); p3.a=11; p3.b=22; System.out.println("P1.a="+p1.a+", P1.b= "+ p1.b); System.out.println("P2.a="+p2.a+", P2.b= "+ p2.b); System.out.println("P3.a="+p3.a+", P3.b= "+ p3.b); int suma(int x,int y) { return x+y; dwapunkty()

45 Wykład Java ver {System.out.println("Dwa punkty konstruktor"); plik:punkt.java class Punkt { int a,b; Punkt(int x, int y) {a=x; b=y; Punkt() { this(99,-1); plik: Punkt3D.java class Punkt3D extends dwapunkty // podlasa klasy dwapunkty {Punkt3D(int l, int u) {super(); // wywołanie konstruktora nadklasy System.out.println("metoda suma ="+suma(l,u)); System.out.println("metoda super.suma ="+super.suma(l,u)); plik:go.bat javac -deprecation dwapunkty.java javac -deprecation Punkt.java javac -deprecation Punkt3D.java java dwapunkty Wynik zadziałania programu Dwa punkty konstruktor metoda suma =333 metoda super.suma =333 P1.a=10, P1.b= 55 P2.a=99, P2.b= -1 P3.a=11, P3.b= 22 Klasa dwapunkty zawiera metodę main(), potrzebną do jej uruchomienia. Trzeba pamiętać jednak o tym, że metoda main() musi występować tylko w jednej klasie programu - tej, od której rozpoczyna się jego działanie i której nazwę podaje się w wywołaniu interpretera Javy. W Javie nie istnieje mechanizm pozwalający na przekazywanie argumentów metod przez adres (ang. by reference). W językach C/C++ można przekazać funkcji na przykład wskaźnik do zmiennej typu int, która następnie może zostać przez tę funkcję zmodyfikowana. W Javie

46 Wykład Java ver wszystkie argumenty są przekazywane przez wartość (ang. by value), w konsekwencji czego metody nie mają dostępu do zmiennych, których wartości zostały przypisane ich parametrom. Również odwołania do obiektów są przekazywane przez wartość, co oznacza, że wywołane metody nie mogą zmieniać wartości zmiennych, które wskazują na obiekty. Dozwolona jest jednak modyfikacja zawartości obiektów, właśnie dzięki temu, że przekazywane są odwołania do nich. Dziedziczenie klas Drugim podstawowym mechanizmem programowania zorientowanego obiektowo jest dziedziczenie (ang. inheritance), umożliwiające tworzenie struktury drzewiastej wszystkich klas. Klasa potomna danej klasy dziedziczy wszystkie jej zmienne egzemplarzowe i metody, a oprócz tego definiuje własne, dodatkowe elementy. Można więc powiedzieć, że jest jej bardziej specjalistyczną wersją. Bezpośrednia klasa podrzędna danej klasy nazywa się jej podklasą (ang. subclass), a bezpośrednia klasa nadrzędna - nadklasą (ang. superclass). Tworzenie podklas jest bardzo prostą czynnością, podobną do tworzenia klas nie dziedziczących żadnej innej klasy. Jedyna różnica polega na tym, że za identyfikatorem podklasy umieszcza się słowo kluczowe extends oraz nazwę nadklasy. Jeśli jesteś programistą C/C++, to być może spodziewałeś się, że w tym miejscu nastąpi omówienie wielokrotnego dziedziczenia (ang. multiple inheritance), czyli jednoczesnego dziedziczenia większej liczby klas przez pojedynczą klasę. Wielokrotne dziedziczenie pozwala programiście łączyć atrybuty różnych klas, ale jednocześnie zmniejsza czytelność tekstu źródłowego i efektywność programu. Dlatego mechanizm ten nie został włączony do Javy. W większości przypadków, w których wskazane lub konieczne jest jego stosowanie, można go zastąpić użyciem interfejsów. Słowo kluczowe super umożliwia nie tylko wywoływanie konstruktora nadklasy, ale także każdej innej jej metody, można je więc traktować jako pełny odpowiednik słowa this. Słowo kluczowe this Java zawiera specjalne słowo kluczowe this, umożliwiające uzyskiwanie dostępu do zmiennych egzemplarzowych i metod bieżącej klasy, czyli klasy, w której słowo to występuje. Z technicznego punktu widzenia słowo this jest odwołaniem do bieżącej klasy i może być użyte w każdym miejscu, w którym dozwolone jest użycie dowolnego innego odwołania. Istnienie słowa kluczowego this może wydawać się w pierwszej chwili niepotrzebne, gdyż, jak stwierdziliśmy wcześniej, metody mogą uzyskiwać dostęp do zmiennych

47 Wykład Java ver egzemplarzowych swojej klasy bezpośrednio lub za pmocą słowa kluczowego super, tak jakby były one ich zmiennymi lokalnymi. W taki sam sposób można wywoływać wszystkie metody zadeklarowane w tej samej klasie. Jednak słowo this pozwala użyć tych samych nazw w odniesieniu do parametrów formalnych oraz do zmiennych egzemplarzowych, co nieraz upraszcza tekst źródłowy. Wówczas dostęp do parametrów uzyskuje się bezpośrednio, a dostęp do zmiennych egzemplarzowych za pomocą odwołania this.. Między słowem this a identyfikatorem zmiennej umieszcza się operator zapisywany za pomocą kropki. Słowa kluczowego this można także używać do wywoływania metod. Jedyna sytuacja, w której korzystanie z tej właściwości Javy ma sens, występuje wtedy, gdy dana klasa zawiera kilka konstruktorów (są one przeładowane) i jeden z nich wywołuje inny. Często zastosowanie takiego rozwiązania ulepsza wygląd tekstu źródłowego. Słowo kluczowe this traktuje się w tym kontekście tak samo, jak nazwę metody. Oznacza to, że umieszcza się za nim w nawiasach listę jego parametrów. plik :BaseClass.java class BaseClass{ int i=100; public static void main(string args[]){ int i; BaseClass baza= new BaseClass(); Pochodna pochodna=new Pochodna(); i=400; System.out.println(""); System.out.println(" main for BaseClass"); System.out.println("i = "+i); System.out.println("baza.i = "+ baza.i); System.out.println("pochodna.i = "+ pochodna.i); System.out.println("((BaseClass)pochodna).i = "+ ((BaseClass)pochodna).i); plik:pochodna.java class Pochodna extends BaseClass{ int i=200; Pochodna() { int i; i=300; System.out.println(" konstruktor dla Pochodnej"); System.out.println("i ="+ i); System.out.println("this.i = "+this.i); System.out.println("super.i = "+super.i);

48 Wykład Java ver Przykrywanie i dynamiczne rozdzielanie metod W języku C++ funkcje klasy bazowej zadeklarowane jako wirtualne mogą zostać przykryte (ang. overridden) przez funkcje klas pochodnych. W Javie istnieje podobny mechanizm, ale nie wymaga on stosowania słowa kluczowego virtual; słowo to nie jest nawet w tym języku zdefiniowane. Każda metoda podklasy Javy, która ma taką samą nazwę i taką samą listę parametrów, co odpowiadająca jej metoda nadklasy, automatycznie przykrywa ją. Tak więc wszystkie metody Javy są z założenia wirtualne, chyba że w sposób jawny zostało w programie określone inaczej. Przykrycie metody przez podklasę powoduje, że odpowiadająca jej metoda z nadklasy przestaje być dostępna. Oznacza to, że każde wywołanie przykrytej metody przez obiekt podklasy powoduje wykonanie jej wersji zdefiniowanej w tej podklasie. Przyjrzyjmy się na przykład następującemu programowi plik: AA.java class AA {int i,j; AA(int a, int b) {i=a; j=b;

49 Wykład Java ver void Widok() {System.out.println("Zmienne i,j: "+i+" "+j); plik: BB.java class BB extends AA {int k; BB(int a, int b, int c) {super(a,b); k=c; /* Wyświetlanie wartości zmiennej k - metoda przykrywająca metodę Widok() z klasy AA*/ void Widok() {System.out.println("Zmienna k: "+k); plik: Przykrywanie.java class Przykrywanie {public static void main(string args[]) {BB ob=new BB(1,2,3); ob.widok(); // wywołanie metody Widok() z klasy BB go.bat javac -deprecation AA.java javac -deprecation BB.java javac -deprecation Przykrywanie.java java Przykrywanie Wynik zadziałania programu Zmienna k: 3 Zapobieganie przykrywania metod Mimo iż możliwość przykrywania metod jest jedną z najważniejszych cech Javy, to jednak zdarza się, że wykonywanie tego działania jest niepożądane. Aby uniemożliwić przykrycie

50 Wykład Java ver metody, na początku jej deklaracji należy umieścić słowo kluczowe final, czyli zadeklarować ją jako metodę finalną. Niżej zostało to zilustrowane na przykładzie: class A { final void lala() { System.out.println("To jest metoda finalna."); class B extends A { void lala() { // Błąd! Tej funkcji nie wolno przykrywać! System.out.println("Instrukcja niedozwolona!"); Ponieważ metoda lala() została zadeklarowana w klasie A ze słowem kluczowym final, nie można jej przykryć w klasie B. Próba wykonania takiego działania powoduje wygenerowanie błędu kompilacji. Warto również wiedzieć, że metody finalne mogą zawierać instrukcje wewnętrzne (ang. inline code), pozwalające uniknąć wydłużenia czasu działania programu spowodowanego koniecznością zastosowania typowego mechanizmu wywołania funkcji i pobrania jej wartości (pod tym względem metody final Javy są podobne do funkcji inline C++). Zapobieganie dziedziczeniu Niektóre z tworzonych klas nie powinny być dziedziczone. Aby temu zapobiec, należy zadeklarować klasę jako finalną, czyli poprzedzić jej deklarację słowem kluczowym final. Wszystkie metody klasy finalnej są również finalne. Jak można się domyślić, niedozwolone jest jednoczesne użycie słów kluczowych abstract i final w deklaracji klasy, gdyż każda klasa abstrakcyjna jest niepełna, a jej metody są implementowane w podklasach. Niżej został pokazany schematyczny przykład definicji klasy finalnej: final class A{ //... class B extends A{ // Błąd! Klasy A nie wolno dziedziczyć!

51 Wykład Java ver Jak wynika z komentarzy, klasa B nie może dziedziczyć klasy A, ponieważ ta ostatnia została zadeklarowana jako klasa finalna. Tworzenie stałych symbolicznych Trzecie zastosowanie słowa kluczowego final polega na definiowaniu zmiennych będących odpowiednikami stalych symbolicznych, czyli oznaczanych za pomocą nazwy (ang. named constants). Zmienne, których deklaracja zawiera słowo kluczowe final, nie mogą być w programie modyfikowane. Wynika stąd, że deklaracje zmiennych finalnych powinny zawierać ich inicjalizację (w tym zastosowaniu słowo final jest podobne do słowa const języków C/C++). Na przykład instrukcja final int LICZNIK=1000; tworzy stałą Licznik o wartości Metody i klasy abstrakcyjne Programiści C++ wiedzą, że niektóre funkcje wirtualne definiowane w klasach bazowych nie są w żaden sensowny sposób zaimplementowane. Funkcje takie są zwykle deklarowane z użyciem słów kluczowych virtual, co oznacza, że muszą być przykrywane w klasach pochodnych. Innymi słowy, klasy bazowe określają jedynie interfejs czystych funkcji wirtualnych, natomiast ich implementacja jest definiowana osobno przez każdą klasę pochodną. Podobne funkcje można również tworzyć w Javie, ale tutaj nazywają się one metodami abstrakcyjnymi (ang. abstract methods). Metody abstrakcyjne deklaruje się z użyciem specyfikatora abstract i nie określa się dla nich implementacji. Jeżeli więc nadklasa zawiera metodę abstrakcyjną, to każda podklasa musi ją przykryć - korzystanie z wersji zdefiniowanej w nadklasie nie jest możliwe, gdyż taka wersja nie istnieje. Ogólna postać deklaracji metody abstrakcyjnej wygląda następująco: abstract typ nazwa(lista_parametrów); Jak widać, metoda abstrakcyjna nie zawiera głównej części (poza deklaracją nie ma żadnych instrukcji). Każda klasa zawierająca jedną lub więcej metod abstrakcyjnych nazywa się klasą abstrakcyjną (ang. abstract class). Aby zadeklarować klasę abstrakcyjną, na początku deklaracji, przed słowem kluczowym class należy umieścić słowo abstract. Niżej został podany bardzo prosty przykład zastosowania klasy i metody abstrakcyjnej: plik kwadrat.java abstract class kwadrat // klasa abstrakcyjna {abstract int kw(int g);//metoda abstrakcyjna

52 Wykład Java ver plik kw2.java class kw2 extends kwadrat { int kw(int i){return i*i; /* klasa kw2 musi zawierać implementację metody kw. w przeciwnym wypadku pojawi się błąd kompilacji*/ plik wynik.java class wynik {public static void main(string args[]) {kw2 ob=new kw2(); System.out.println("Kwadrat liczby 10: "+ob.kw(10)); Wynik zadziałania programu: Kwadrat liczby 10: 100 Ponieważ metoda kw() jest metodą abstrakcyjną, również klasa Kwadrat musi być abstrakcyjna. Oznacza to, że klasa kw2, stanowiąca rozszerzenie klasy Kwadrat musi zawierać implementację metody kw. Niezastosowanie się do tego wymogu spowodowałoby wygenerowanie błędu kompilacji (zgodnie z uwagami zamieszczonymi w komentarzach programu). Aby się o tym przekonać, wystarczy usunąć główną część z metody kw należącej do klasy kw2 Nie istnieje możliwość tworzenia obiektów klas abstrakcyjnych. Innymi słowy, niedozwolone jest tworzenie egzemplarzy klasy abstrakcyjnej za pomocą operatora new. Łatwo jest zrozumieć przyczynę takiego ograniczenia: obiekty klas abstrakcyjnych byłyby bezużyteczne, ponieważ zawierałyby niezdefiniowane metody. Inne ograniczenia mówią, że nie wolno deklarować abstrakcyjnych konstruktorów oraz abstrakcyjnych metod statycznych. Każda podklasa klasy abstrakcyjnej musi implementować wszystkie metody abstrakcyjne nadklasy, chyba że sama została zadeklarowana jako abstrakcyjna. Metody i zmienne statyczne Nieraz trzeba utworzyć metodę, która byłaby dostępna bez konieczności tworzenia obiektów jej klasy. W tym celu należy ją zadeklarować ze słowem kluczowym static, tak jak w przypadku metody main(). Metody statyczne mogą wywoływać bezpośrednio tylko inne metody statyczne i nie mogą korzystać ze słów kluczowych this i super. Istnieje również możliwość tworzenia zmiennych statycznych, ale należy pamiętać o tym, że w istocie są one zmiennymi globalnymi, dostępnymi z każdego miejsca programu.

53 Wykład Java ver Jeżeli inicjalizacja zmiennych statycznych wymaga wykonania dodatkowych instrukcji, to można je umieścić w bloku o nazwie static, który jest wykonywany tylko raz, podczas pierwszego ładowania klasy. Podana niżej klasa o nazwie stat zawiera metodę statyczną metoda(int x), dwie zmienne statyczne oraz blok inicjalizacyjny static. class stat {static int a=3; static int b; static void metoda(int x) {System.out.println("x= "+x); System.out.println("a= "+a); System.out.println("b= "+b); stat{system.out.println(" Inicjalizacja bloku statycznego"); b=a*4; public static void main(string args[]) {metoda(50); Po pierwszym załadowaniu klasy wykonywane są instrukcje z deklaracjami zmiennych a i b, a bezpośrednio po nich - blok static, wyświetlający odpowiedni komunikat oraz przypisujący zmiennej b wynik wyrażenia a * 4, czyli liczbę 12. Następnie interpreter wywołuje metodę main(), która wywołuje metodę statyczną (), przekazując jej argument o wartości 50. Pierwsza instrukcja z metodą println() wyświetla wartość zmiennej lokalnej (parametru formalnego) x, a dwie następne - wartości zmiennych statycznych a i b. In formacje wyświetlane przez ten program wyglądają następująco: Wynik zadziałania programu: Inicjalizacja bloku statycznego x= 50 a= 3 b= 12 Jak już wiemy, korzystanie z metod i zmiennych statycznych nie wymaga tworzenia obiektów ich klas. Wykonuje się to podobnie jak w przypadku stosowania pozostałych,elementów klas, z tym że przed operatorem "kropka" nie umieszcza się nazwy obiektu lecz nazwę klasy. W taki właśnie sposób niejednokrotnie wywoływaliśmy w programach przykładowych metody

54 Wykład Java ver standardowe Javy. Jak widać, stanowią one odpowiednik funkcji globalnych występujących w takich językach, jak C i C++, lecz mają w porównaniu z nimi tę zaletę, że ich nazwy są definiowane względem danej klasy. Dzięki temu nie jest możliwe przypadkowe zdefiniowanie funkcji, która by miała tę samą nazwę, co jedna z istniejących już funkcji bibliotecznych. Podane uwagi odnoszą się również do zmiennych statycznych. Pakiety i interfejsy Pakiety umożliwiają grupowanie klas i nadawanie im takich samych nazw w różnych grupach. Można na przykład zdefiniować klasę o nazwie List i umieścić ją w nowym pakiecie, nie obawiając się, że wystąpi konflikt między tą a inną, istniejącą już klasą o takiej samej nazwie. Podobnie jak klasy, pakiety tworzą strukturę hierarchiczną.. Aby można było korzystać z klas danego pakietu, trzeba go zaimportować. Interfejs jest specyfikacją zestawu metod, które w tworzonej klasie trzeba zaimplementować. Interfejsy są więc podobne do klas abstrakcyjnych, ale różnią się od nich tym, że nie zawierają ani jednej definicji metody. Dla programisty istotny jest również fakt, że interfejsy można wielokrotnie implementować, czyli że pojedyncza klasa może dziedziczyć wiele interfejsów (Pamiętej! wielokrotne dziedziczenie klas jest w Javie zabronione). Pakiety Wszystkie identyfikatory, których używaliśmy dotychczas do tworzenia klas, należały do tej samej przestrzeni nazw (ang. name space). Oznacza to, że każda klasa musiała mieć inną nazwę, gdyż w przeciwnym wypadku wystąpiłby między nimi konflikt. Brak mechanizmu umożliwiającego zarządzanie przestrzenią nazw spowodowałby, że już w krótkim czasie zabrakłoby nam nazw, które by się nie powtarzały, a jednocześnie w sensowny sposób opisywały tworzone klasy. Jeszcze trudniej dochodziłoby do kompromisów zawieranych między różnymi programistami. Wyobraźmy sobie na przykład sytuację, w której tysiące programistów na całym świecie próbuje uzgodnić nazwy klas występujących w przygotowywanych przez nich programach dla Internetu. Na szczęście, Java zawiera mechanizm umożliwiający dzielenie przestrzeni nazw na mniejsze fragmenty. Tworzy on pakiety i pozwala nie tylko używać powtarzających się nazw klas, ale także określać zakres ich elementów. Można na przykład utworzyć klasę, której zmienne i metody będą dostępne tylko dla innych klas należących do tego samego pakietu. Każdy plik z

55 Wykład Java ver rozszerzeniem java może składać się z czterech części, z których do tej pory wykorzystywaliśmy tylko jedną. Ogólna postać pliku źródłowego Javy wygląda następująco: pojedyncza instrukcja package (część opcjonalna), dowolna liczba instrukcji import (część opcjonalna), pojedyncza deklaracja klasy publicznej, dowolna liczba deklaracji klas prywatnych (część opcjonalna). Na samym początku pliku źródłowego Javy może znajdować się instrukcja package, informująca kompilator o nazwie pakietu, do którego mają należeć wszystkie zdefiniowane niżej klasy. Pominięcie jej powoduje, że klasy z danego pliku są umieszczane w pakiecie domyślnym, nie posiadającym żadnej nazwy. Ogólna postać instrukcji package wygląda następująco: package nawa_pakietu1[.nawa_pakietu2[.nawa_pakietu3]]; Zwróć uwagę, że można tworzyć strukturę hierarchiczną pakietów, oddzielając ich nazwę za pomocą kropki. Struktura pakietów musi być skorelowana ze strukturą katalogów na dysku. Na przykład wszystkie pliki źródłowe z definicjami klas należących do pakietu MyPackage trzeba umieścić w katalogu MyPackage, natomiast pliki zawierające instrukcję package jawa.awt.image muszą się znajdować w katalogu java\awt\image, java\awt\image lub java:awt:image, w zależności od używanego systemu operacyjnego. Należy pamiętać o tym, że w Javie rozróżniane są małe i duże litery, zarówno w nazwach klas, jak i w nazwach plików i katalogów. Uwaga: Katalog główny struktury katalogów odpowiadających poszczególnym pakietom określa się za pomocą zmiennej środowiskowej CLASSPATH. Ponieważ dozwolone jest podanie większej liczby katalogów, istnieje możliwość umieszczania pakietów w różnych miejscach. Kompilowanie i uruchamianie klas należących do pakietów Pakiety pozwalają rozwiązać wiele problemów związanych ze sterowaniem dostępem do klas i podziałem ich przestrzeni nazw. Z drugiej jednak strony, stwarzają one pewne trudności podczas kompilowania i uruchamiania programów. Wszystkie klasy, które tworzyliśmy do tej pory, zapisywaliśmy w domyślnym pakiecie bez nazwy. Dzięki temu mogliśmy w prosty sposób kompilować pliki źródłowe i uruchamiać ich wersje bajtowe za pomocą interpretera przez podawanie ich nazw w wierszu poleceń. Było tak dlatego, że wśród katalogów

56 Wykład Java ver określonych za pomocą zmiennej środowiskowej CLASSPATH znajdował się bieżący katalog roboczy, oznaczany kropką. Sytuacja nieco komplikuje się wówczas, gdy tworzone klasy umieszczane są w osobnych pakietach. Jak już wiemy, ich struktura powinna pokrywać się ze strukturą katalogów na dysku. Oznacza to, że na przykład klasy pakietu test powinny znajdować się w katalogu test. Ta zasada wydaje się raczej oczywista. Na tym jednak problemy się nie kończą. Powiedzmy, że w katalogu głównym bieżącego dysku utworzyliśmy katalog test i umieściliśmy w nim plik PackTestjava, zawierający definicję klasy PackTest z pakietu test. Niestety, kiedy spróbowaliśmy ją uruchomić za pomocą polecenia java PackTest, interpreter wyświetlił komunikat can't find class PackTest (nie mogę znaleźć klasy PackTest). Również wpisanie polecenia java test.packtest, określającego pakiet, do którego należy klasa PackTest, nie zakończyło się pomyślnie - znów pojawił się komunikat stwierdzający, że kompilator nie może jej odnaleźć. Wyjaśnienie tej zagadki kryje się w tym, że interpreter rozpoczyna szukanie klas od katalogów określonych za pomocą zmiennej środowiskowej CLASSPATH. Jeżeli zmienna ma wartość.;c:\ java\classes (co jest najbardziej prawdopodobne), to wpisanie polecenia java PackTest spowoduje, że interpreter będzie najpierw szukał pliku PackTest.class w bieżącym katalogu roboczym, a następnie w katalogu C:\ java\classes. Podobnie, polecenie java test.packtest doprowadzi do uruchomienia klasy PackTest tylko wtedy, gdy jej kod bajtowy będzie znajdować się w podkatalogu test bieżącego katalogu roboczego lub w katalogu C: java\classes\test. Powstały problem można więc rozwiązać na dwa sposoby. Pierwszy, niewarty polecenia, polega na przejściu do katalogu C:\test i wpisaniu polecenia java PackTest. Drugi sposób jest dużo lepszy i polega na takim zmodyfikowaniu zmiennej środowiskowej CLASSPATH, aby wskazywała również na początek struktury katalogów, w której będziemy umieszczać nasze programy Javy, i uruchamianiu ich z podawaniem nazw pakietów. W opisywanym przypadku zmienną CLASSPATH trzeba ustawić na.;c:\ java\classes;c:\. Zwykle jednak plików Javy nie zapisuje się w katalogu głównym, lecz w innym, specjalnie do tego celu utworzonym. Zakładając, że nazywa się on MyJava, zmienna CLASSPATH powinna mieć wartość; C:\java\classes;C:\MyJava (plik PackTest.java powinien się wówczas znajdować w katalogu C: \MyJava\test).

57 Wykład Java ver Importowanie klas z innych pakietów Między instrukcją package a pierwszą definicją klasy mogą znajdować się w pliku źródłowym instrukcje import. Biorąc pod uwagę fakt, że umieszczanie klas w pakietach pozwala uniknąć konfliktu występującego między ich nazwami, nietrudno zrozumieć, dlaczego ani jedna wbudowana klasa Javy nie znajduje się w domyślnym pakiecie bez nazwy. Jednak konieczność wpisywania dla każdej używanej klasy jej pełnej ścieżki, czyli nazw wszystkich pakietów oddzielonych kropką, sprawiałaby programistom dużo kłopotów. Dlatego Java zawiera słowo kluczowe import, pozwalające określać klasy, do których można uzyskiwać dostęp przez podanie samej ich nazwy. Zostało ono wprowadzone jedynie w celu ułatwienia programistom pracy i jego stosowanie nie jest konieczne do poprawnego skompilowania programu. Jeżeli jednak liczy on dużo instrukcji i odwołuje się do klas należących do wielu pakietów, to słowo import w sposób istotny upraszcza tekst źródłowy. Ogólna postać instrukcji import wygląda następująco: import nazwa-pakietu1[.nazwa-pakietu2]. (nazwa_klasy *); nazwa_pakietu1 oznacza nazwę pakietu najwyższego poziomu, nazwa_pakietu2 opcjonalną nazwę pakietu drugiego poziomu itp. Maksymalna głębokość struktury pakietów jest nieograniczona. Na końcu instrukcji import trzeba podać nazwę jednej ze znajdujących się w nim klas lub gwiazdkę, oznaczającą zaimportowanie wszystkich klas należących do danego pakietu. Oto przykład użycia obu postaci instrukcji import: import java.util.date; import java.io; OSTRZEŻENIE: Umieszczenie gwiazdki w większej liczbie instrukcji import powoduje wydłużenie czasu kompilowania programu, szczególnie wtedy, gdy importowane pakiety zawierają dużo klas. Wynika to z faktu, że po napotkaniu odwołania do klasy, która nie należy do bieżącego pakietu i nie została zaimportowana przez podanie jej nazwy w instrukcji import, kompilator szuka jej we wszystkich pakietach zaimportowanych w całości. Dlatego nieraz lepiej jest importować pojedyncze klasy. Warto jednak pamiętać o tym, że stosowanie gwiazdki nie ma żadnego wpływu na sposób i szybkość działania skompilowanego programu. Podany niżej przykład pokazuje sposób korzystania z zaimportowanych klas: import java.util.*; class MojeDane extends Date {

58 Wykład Java ver Gdyby pominięto instrukcję import, deklaracja klasy MojeDane musiałaby wyglądać następująco: class MojeDane extends java.util.date { Można również importować klasy, które mają taką samą nazwę i występują w różnych pakietach, ale i tak trzeba się do nich odwoływać przez podanie ich ścieżek, czyli pełnej hierarchii pakietów. Wszystkie wbudowane, standardowe klasy Javy należą do pakietu o nazwie java, natomiast pakiet java.lang zawiera podstawowe funkcje językowe. Ponieważ bez tych funkcji Java jest praktycznie bezużyteczna, to w przeciwieństwie do samodzielnie tworzonych klas, klasy z pakietu java.lang są importowane przez kompilator automatycznie. Tak więc każdy plik źródłowy jest kompilowany w taki sposób, jakby na jego początku znajdowała się instrukcja import java.lang.*; Ochrona dostępu do elementów klas W Javie istnieją dwa sposoby określania zakresu zmiennych i metod. Pierwszy z nich polega na odpowiednim rozmieszczaniu elementów programów w klasach i pakietach. Na przykład wszystkie zmienne egzemplarzowe i metody należące do określonej klasy są dostępne dla wszystkich innych jej elementów. Wszystkie pozostałe klasy można podzielić na następujące cztery kategorie: podklasy znajdujące się w tym samym pakiecie, inne klasy znajdujące się w tym samym pakiecie, podklasy znajdujące się w innych pakietach, inne klasy znajdujące się w innych pakietach. Drugi sposób określania zakresu zmiennych i metod polega na stosowaniu znanych z języka C++ modyfikatorów public, private i protected oraz domyślnego poziomu dostępu, nie oznaczanego żadnym słowem kluczowym. Tabela pokazuje dostępność poszczególnych rodzajów elementów typów Javy w wymienionych wyżej kategoriach klas. Kolumny odpowiadają modyfikatorom, za pomocą których można deklarować elementy klas, natomiast wiersze - kategorie klas, w których istnieją instrukcje odwołujące się do elementów. Słowa znajdujące się na przecięciu poszczególnych wierszy i kolumn określają dostępność danego rodzaju elementu w określonym miejscu programu. Na przykład elementy chronione (protected) są widoczne we wszystkich podklasach oraz klasach należących do tego samego

59 Wykład Java ver pakietu, natomiast prywatne chronione (private protected) - w danej klasie oraz we wszystkich jej podklasach. Specyfikatory dostępu Kategoria klas Prywatne Bez modyfikatora Prywatne Chronione Publiczne chronione Ta sama klasa TAK TAK TAK TAK TAK Podklasy znajdujące się w tym samym pakiecie NIE TAK TAK TAK TAK Inne klasy znajdujące się w tym samym pakiecie Podklasy znajdujące się w innych pakietach Inne klasy znajdujące się w innych pakietach NIE TAK NIE TAK TAK NIE NIE TAK TAK TAK NIE NIE NIE NIE TAK Mimo iż zawartość tabeli wygląda dość skomplikowanie, to jednak można podać kilka ogólnych zasad ułatwiających jej zrozumienie i stosowanie. Słowo kluczowe public udostępnia dany element wszystkim klasom programu, natomiast słowo private zabrania dostępu wszystkim klasom z wyjątkiem klasy, w której dany element występuje. Elementy zadeklarowane bez żadnego modyfikatora są dostępne dla wszystkich klas danego pakietu. Jeżeli element klasy ma być widoczny dodatkowo we wszystkich jej podklasach należących do innych pakietów, to trzeba go zadeklarować za pomocą słowa kluczowego protected. Wreszcie, element klasy, który ma być widoczny tylko w jego klasie oraz wszystkich jej podklasach, niezależnie od ich położenia, powinien zostać zadeklarowany z użyciem modyfikatorów private protected. OSTRZEŻENIE: Jeśli jesteś programistą C++, to zwróć uwagę, że modyfikator Javy protected ma inne znaczenie niż w C++; jest raczej podobny do słowa kluczowego friend. Odpowiednikiem modyfikatora protected z języka C++ jest w Javie para słów private protected. Interfejsy Interfejsy Javy umożliwiają dynamiczne rozróżnianie metod w czasie działania programu. Jeżeli jedna metoda wywołuje drugą, należącą do innej klasy, to obie klasy muszą istnieć podczas kompilacji. W przeciwnym razie kompilator nie mógłby sprawdzić, czy liczba i typy przekazywanych argumentów są zgodne z sygnaturą

60 Wykład Java ver typów wywoływanej metody. Wymaganie to ogranicza w znacznym stopniu możliwości rozszerzania klas i nadaje im charakter statyczny. W tego rodzaju systemach większość funkcji jest realizowana przez klasy znajdujące się na wysokim poziomie hierarchii klas, tak aby były one dostępne dla jak największej liczby podklas. Musi więc istnieć mechanizm umożliwiający oddzielenie definicji metod od struktury ich dziedziczenia. Interfejsy przypominają klasy, ale nie występują w nich zmienne egzemplarzowe, a ich metody są pozbawione części głównej. Mówiąc inaczej, interfejsy określają sposób korzystania z metod, ale nie zawierają ich implementacji (definicji). Każda klasa może implementować dowolną liczbę interfejsów. Implementacja interfejsu jest podobna do dziedziczenia klasy i polega na zdefiniowaniu wszystkich zadeklarowanych w nim metod, oczywiście z zachowaniem ich sygnatur typów. Ponieważ hierarchia interfejsów jest niezależna od hierarchii klas, wiele nie powiązanych ze sobą klas może dziedziczyć ten sam interfejs. Stanowi to jedną z głównych korzyści odnoszonych ze stosowania interfejsów. UWAGA: Implementowanie interfejsów umożliwia rozwiązywanie problemów, które w języku C++ wymagałyby wielokrotnego dziedziczenia klas. Interfejsy mają czytelniejszą postać niż klasy i są od nich bardziej uniwersalne, gdyż nie zawierają zmiennych egzemplarzowych i definicji metod. Słowo kluczowe interface. Ogólna postać definicji interfejsu jest podobna do definicji klasy i wygląda następująco: interface nazwa { typ nazwa_metody1(lista-parametrów); typ nazwa_metody2(lista-parametrów);... typ nazwa_metodyn(lista-parametrów); typ nazwa_zmiennej_1 = wartość; typ nazwa_zmiennej_2 = wartość; typ nazwa_zmiennej_n = wartość; Słowo nazwa oznacza dowolny identyfikator i jest odpowiednikiem nazwy klasy. Zwróć uwagę, że żadna z metod nie ma części głównej, czyli bloku instrukcji umieszczonego w nawiasach klamrowych; za nawiasem zamykającym listę

61 Wykład Java ver parametrów występuje średnik. Oprócz metod interfejs może zawierać zmienne finalne, czyli odpowiedniki stałych z innych języków programowania. Podany niżej przykładowy interfejs zawiera metodę o nazwie dom(), pobierającą jeden parametr typu inf. interface dane { void dom(int param); Słowo kluczowe implements Ogólna postać definicji klasy implementującej jeden lub więcej interfejsów wygląda następująco ( jest to rozszerzenie definicji podanej wcześniej): class nazwa_klasy [extends nazwa_nadkląsy] [implements interfejs0 [,interfejs1...]] { główna_część_klasy Jeżeli klasa dziedziczy więcej niż jeden interfejs, to ich nazwy oddziela się przecinkami. Wszystkie metody implementujące interfejsy muszą być zadeklarowane ze słowem kluczowym public. Dozwolone jest deklarowanie zmiennych jako odwołań od interfejsów i odwoływanie się za ich pomocą do egzemplarzy wszystkich klas, które dany interfejs implementują. Wersja metody wywoływanej za pomocą tego rodzaju zmiennej jest określana na podstawie typu obiektu, na który zmienna ta w danej chwili wskazuje. Metody są wybierane dynamicznie w czasie przebiegu, co pozwala tworzyć implementacje interfejsów później niż klasy, które z nich korzystają. Dla wywołującej metody nie są istotne szczegóły dotyczące działania metody wywoływanej, lecz rodzaj wykonywanego przez nią zadania oraz sposób jej wywołania. OSTRZEŻENIE: Ponieważ odszukiwanie metod w czasie działania programu wpływa negatywnie na szybkość jego działania, to w miejscach, w których ma ona decydujące znaczenie, należy unikać deklarowania zmiennych jako odwołań od interfejsów. Zmienne w interfejsach

62 Wykład Java ver Interfejsów można także używać do deklarowania często wykorzystywanych zmiennych finalnych (stałych). Działanie to przypomina tworzenie plików nagłówkowych C++ zawierających instrukcje #define lub enum. Aby w tworzonej klasie uzyskać dostęp do zmiennych należących do danego interfejsu, należy go zaimplementować. Jeżeli nie zawiera on żadnej metody, to wystarczy umieścić jego nazwę za słowem implements, występującym w deklaracji klasy. Wówczas interfejs nie jest w zasadzie implementowany, lecz raczej importowany. Najlepszym momentem na wyłapanie błędu jest kompilacja jeszcze przed próbą uruchomienia programu. Jednak nie wszystkie błędy można wykryć podczas kompilacji. Pozostałe problemy muszą być obsłużone podczas wykonania programu przez jakiś mechanizm, pozwalający sprawcy błędu przekazać odpowiednią informację do odbiorcy, który będzie wiedział, jak ma rozwiązać zaistniałą sytuację. W C i innych starszych językach stosowano kilka takich mechanizmów. Jednak nie były one częścią języka, tylko zostały ustanowione przez konwencję. Najczęściej polegały na zwróceniu specjalnej wartości lub ustawieniu znacznika. Odbiorca musiał sprawdzać wartość lub znacznik, aby stwierdzić, czy coś poszło nie tak, jak powinno. Jednak z upływem lat odkryto, że programiści, którzy używają takich bibliotek, mają skłonność do megalomanii: "tak, takie błędy mogą zdarzać się innym, ale nigdy w moim kodzie". Nic dziwnego więc, że zaprzestali sprawdzania sytuacji wyjątkowych (a zdarzało się tak, że sytuacje wyjątkowe były zbyt banalne, żeby ktoś nawet pomyślał, by je sprawdzać)'. Z drugiej strony, jeśli ktoś był na tyle dokładny, by sprawdzać wystąpienie błędu przy każdym wywołaniu metody, to jego kod szybko zmieniał się w nieczytelny koszmar. Rozwiązaniem tego problemu jest odrzucenie przypadkowości w obsługiwaniu błędów i wymuszenie pewnych zachowań. Pomysł ten ma już długą historię, ponieważ próby implementacji obsługi sytuacji wyjątkowych (ang. exception handling) sięgają systemów operacyjnych z lat 60. czy nawet znanego z BASIC-a "on error goto". Ale obsługa wyjątków w C++ była oparta na Adzie, a Java opiera się głównie na C. Słowo "wyjątek" występuje tu w znaczeniu: "przyjmuję możliwość wystąpienia wyjątku od tego". W momencie wystąpienia problemu możemy nie wiedzieć, co z nim zrobić, ale wiemy, że nie można go beztrosko zignorować. Trzeba się zatrzymać, a ktoś gdzieś musi wymyślić, co robić dalej. W danym kontekście brakuje informacji potrzebnych do rozwiązania

63 Wykład Java ver problemu. Zatem przekazujemy problem do szerszego kontekstu, gdzie znajdzie się ktoś z kwalifikacjami odpowiednimi do podjęcia odpowiedniej decyzji (podobnie jak w strukturach władzy). class Raz { String m_snazwa= "Raz"; String s() { return "1"; class Dwa extends Raz { String m_snazwa= "Dwa"; String s() { return "2"; class Trzy extends Dwa { String m_snazwa= "Trzy"; String s() { return "3"; void test() { java.io.printwriter stdout =new java.io.printwriter(system.out,true); stdout.println("s()=\t\t\t"+s()); stdout.println("m_snazwa=\t\t"+m_snazwa); stdout.println("..."); stdout.println("super.s()=\t\t"+super.s()); stdout.println("super.m_snazwa=\t\t"+super.m_snazwa); stdout.println("..."); stdout.println("((dwa)this).s()=\t"+((dwa)this).s()); stdout.println("((dwa)this).m_snazwa=\t"+((dwa)this).m_snazwa); stdout.println("..."); stdout.println("((raz)this).s()=\t"+((raz)this).s()); stdout.println("((raz)this).m_snazwa=\t"+((raz)this).m_snazwa); public class SuperTest { public static void main(string args[]) throws Exception { //Tworzymy nowy obiekt trzy typu Trzy Trzy trzy = new Trzy(); //Wywołanie metody test() trzy.test(); //Zatrzymanie aplikacji do czasu nacisnięcia klawisza Enter pauza(); static void pauza() throws Exception { System.out.print("Nacisnij Enter..."); System.in.read();

64 Wykład Java ver Sytuacja wyjątkowa to problem, który wstrzymuje wykonywanie metody lub bloku. Ważne jest, by oddzielić sytuację wyjątkową od zwykłego problemu, to jest takiego, kiedy w aktualnym kontekście istnieje dość przesłanek, by jakoś poradzić sobie z trudnościami. W sytuacji wyjątkowej nie można kontynuować przetwarzania, ponieważ w aktualnym kontekście nie ma dostępu do informacji koniecznej do rozwiązania problemu. Wszystko, co można zrobić, to wyjść z aktualnego kontekstu i przekazać problem do kontekstu wyżej. Tak się właśnie dzieje, kiedy zgłaszany jest wyjątek. Prostym przykładem jest dzielenie. Jeśli próbujemy dzielić przez zero, to warto się upewnić, że takie dzielenie nie nastąpi. Ale co oznacza zerowy mianownik przy danym zastosowaniu naszej metody? Być może, w kontekście danego problemu, wiadomo, co zrobić z zerowym mianownikiem. Jeśli jednak jest to wartość nieoczekiwana, nie można z nią nic zrobić i zamiast iść dalej, trzeba zgłosić wyjątek. Kiedy zgłaszany jest wyjątek, dzieje się kilka rzeczy. Po pierwsze, w taki sam sposób, jak każdy obiekt Javy, tworzony jest obiekt wyjątku - odkładany na stercie poprzez instrukcję new. Aktualna ścieżka wykonania (ta, która nie może być kontynuowana) jest przerywana i obiekt wyjątku jest wyrzucany z aktualnego kontekstu. W tym momencie sterowanie przejmuje mechanizm obsługi wyjątków i zaczyna szukać miejsca odpowiedniego do podjęcia dalszego wykonywania programu. Tym odpowiednim miejscem jest procedura obsługi wyjątku. Jej zadaniem jest wybrnąć z problemu tak, żeby program mógł spróbować innego rozwiązania lub po prostu kontynuować wykonanie, ignorując błąd. Jako prosty przykład zgłaszania wyjątku rozważmy obiekt o nazwie t. Może się zdarzyć, że otrzymamy uchwyt, który nie został zainicjowany, więc chcielibyśmy to sprawdzić przed wywołaniem metody używającej tego uchwytu. Można przesłać informację o błędzie do szerszego kontekstu przez stworzenie obiektu reprezentującego wiadomość i "wyrzucenie" go na zewnątrz aktualnego kontekstu. Nazywa się to zgłoszeniem (wyrzuceniem) wyjątku (ang. throwing), wygląda natomiast następująco: if(t==null) throw new NullPointerException(); Zostanie zgłoszony wyjątek, co w aktualnym kontekście zwalnia nas od odpowiedzialności.

65 Wykład Java ver Parametry wyjątków Jak każdy obiekt Javy, wyjątek tworzony jest na stercie przez instrukcję new, która przydziela pamięć i wywołuje konstruktor. We wszystkich standardowych wyjątkach istnieją dwa konstruktory: pierwszy jest konstruktorem domyślnym, a drugi przyjmuje łańcuch jako parametr tak, że można w wyjątku umieścić własny komentarz: if(t==null) throw new NullPointerException( t=null ); jak zobaczymy dalej, można później wydobyć ten łańcuch na wiele sposobów. słowo kluczowe throw powoduje kilka względnie "magicznych" rzeczy. Normalnie najpierw używamy new, aby stworzyć obiekt, który reprezentuje warunki zaistnienia błędu. Otrzymany uchwyt obiektu należy przekazać do throw. W rezultacie obiekt jest "zwracany" przez metodę nawet wtedy, gdy typ tego obiektu nie jest taki sam, jak zadeklarowany typ zwracany z metody. W uproszczeniu można obsługę wyjątków traktować jako alternatywną metodę zwracania wartości ~ bloku. Chociaż zbyt dosłowne traktowanie tej analogii prowadzi do kłopotów. Również ze zwykłego bloku można wyjść, zgłaszając wyjątek - wtedy zostanie zwrócona domyślna wartość metoda lub blok będzie opuszczony. Blok try Jeśli wyrzucimy wyjątek, znajdując się wewnątrz metody (albo jedna z wywoływanych wewnątrz metod wyrzuci wyjątek), to wykonanie metody zostanie przerwane przez proces zwracania wyjątku. Jeśli nie chcemy, aby throw powodowało wyjście z metody, to należy w tej metodzie wstawić specjalny blok przechwytujący wyjątki. Nazywa się on blokiem prób (ang. try), ponieważ wewnątrz niego "próbujemy" wywołać różne metody. Blok prób jest normalnym blokiem poprzedzonym słowem kluczowym try: try { // Kod który może spowodować wyjątek Obsługa błędów w językach programowania nie posiadających mechanizmu obsługi wyjątków wymagała otoczenia każdego wywołania metody kodem ustawiającym i testującym kody błędów, nawet jeśli ta sama metoda była wywoływana kilkakrotnie. Z obsługą wyjątków można wstawić wszystko w blok try i przechwytywać wszystkie wyjątki w jednym miejscu. Oznacza to, że kod jest łatwiej pisać i łatwiej czytać, ponieważ jego przeznaczenie nie jest przesłonięte przez obsługę błędów. Obsługa wyjątków Oczywiście każdy wyrzucony wyjątek musi się gdzieś znaleźć. Tym "miejscem" jest procedura obsługi wyjątku i dla każdego typu wyjątków, który chcemy obsłużyć, musi istnieć osobna procedura. Procedury obsługi wyjątków następują bezpośrednio po bloku try i są oznaczone przez słowo kluczowe catch: try { // Kod który może spowodować wyjątek catch{typel idl) { // Obsłuż wyjątek typu Typel catch(type2 id2) { // Obsłuż wyjątek typu Type2 catch(type3 id3) {

66 Wykład Java ver // Obsłuż wyjątek typu Type3 [finally { // domyślna obsługa wyjątku- czynności, które są obsługiwane za każdym razem ] // itd... Każdy człon catch (procedura obsługi wyjątku) działa jak mała metoda, która pobiera tylko jeden parametr konkretnego typu. Identyfikatory (id1, id2 itd.) mogą być używane wewnątrz procedury tak samo jak parametry metody. Czasami nigdy nie używa się identyfikatorów, ponieważ sam typ wyjątku dostarcza wystarczającą ilość informacji, aby poradzić sobie z wyjątkiem. Mimo to zawsze trzeba deklarować identyfikator. Procedury obsługi muszą następować bezpośrednio po bloku try. Jeśli zostanie wyrzucony wyjątek, to mechanizm obsługi wyjątków rozpoczyna poszukiwanie pierwszej procedury, której parametr odpowiada typowi wyrzuconego wyjątku. Po wejściu w sekcję catch wyjątek uważa się za obsłużony. Poszukiwanie procedur zostaje zatrzymane po wyjściu z sekcji catch. Wykonywany jest tylko kod pasującej sekcji catch, a nie jak w instrukcji switch, która potrzebuje break na końcu każdego przypadku case, aby zapobiec wykonywaniu kolejnych przypadków. Zauważ, iż wewnątrz bloku try dowolna liczba różnych wywoływanych metod może generować ten sam wyjątek, ale wystarczy dla nich tylko jedna procedura obsługi. Kończenie czy wznawianie W teorii obsługi wyjątków wyróżnia się dwa modele. Przy kończeniu (tak wyjątki obsługuje Java i C++) zakłada się, że błąd jest tak krytyczny, że nie ma możliwości powrotu do miejsca, w którym pojawił się wyjątek. Ktokolwiek wyrzucił wyjątek, zdecydował, że nie ma sposobu, aby uratować sytuację i nie życzy sobie, aby wracać do tego miejsca. Alternatywne rozwiązanie nazywa się wznawianiem. Oznacza to, że spodziewamy się, iż procedu ra obsługi wyjątku zrobi coś, by naprawić system, a następnie można próbować wywołać wadliwą metodę, zakładając powodzenie drugiej próby. Jeśli chcemy wznowienia, to ciągle mamy nadzieję na kontynuację wykonania po obsłużeniu wyjątku. W tym wypadku wyjątek przypomina raczej wywołanie metody - i tak właśnie należy radzić sobie w Javie w sytuacjach, kiedy konieczne jest zachowanie w stylu wznawiania (czyli nie wyrzucamy wyjątku - wywołujemy metodę, która naprawi problem). Alternatywnie można umieścić blok try wewnątrz pętli while, która będzie powtarzała blok try aż do uzyskania żądanego rezultatu. W przeszłości programiści używający systemów operacyjnych, które obsługiwały wznawianą obsługę wyjątków, ostatecznie wybierali kod podobny do przerywającego, pomijając wznawianie. Zatem mimo iż na początku wznawianie może się wydawać atrakcyjne, to w praktyce nie jest zbyt użyteczne. Podstawowym powodem jest najprawdopodobniej powstającą wtedy zależność fragmentów kodu od siebie - procedura obsługi musi wiedzieć, skąd wyrzucono wyjątek, i zawierać odpowiedni kod, specyficzny dla każdego takiego miejsca. Powoduje to, że taki kod trudno jest tworzyć i utrzymywać, szczególnie w przypadku dużych systemów, gdzie wyjątek może być generowany w wielu miejscach. Typy Wyjątków Na szczycie hierarchii klas reprezentujących wyjątki znajduje się klasa Throwable. Każda klasa o nazwie występującej w podanym wyżej schemacie w nawiasach umieszczonych za słowem catch jest właśnie jedną z podklas klasy Throwable. Ma ona dwie bezpośrednie

67 Wykład Java ver podklasy, Exception i Error, dzielące wszystkie dalsze podklasy na dwie oddzielne grupy. Klasy Exception używa się z wyjątkami przechwytywanymi i generowanymi przez program. Natomiast klasa Error pozwala określać wyjątki, które w normalnej sytuacji nie powinny być przechwytywane. Podczas przechwytywania podklas klasy Error należy być bardzo ostrożnym, ponieważ zwykle oznaczają one wystąpienie bardzo poważnego błędu. Jeszcze bardziej specjalistyczny charakter ma podklasa klasy Exception o nazwie RuntimeException, reprezentująca wyjątki, których wystąpienie zostało spowodowane przez system czasu przebiegu Javy. Są one zwykle generowane automatycznie w następstwie nieprawidłowego działania programu. Obiekty reprezentujące wyjątki są tworzone automatycznie przez system czasu przebiegu w następstwie wystąpienia każdej sytuacji nietypowej. Na przykład zamieszczony niżej program przykładowy zawiera wyrażenie, które powoduje wygenerowanie wyjątku oznaczającego próbę dzielenia przez zero. plik: Dzielenie.java class Dzielenie { public static void main(string args[]) { int d=0; int a=42 /d; System.out.println("a/d="+a); Podczas próby wykonania tego działania system czasu przebiegu Javy, stwierdza, że dzielna jest równa zeru, w związku z czym tworzy obiekt wyjątku w celu przerwania wykonywania aktualnej instrukcji i umożliwienia programowi obsługi zaistniałego błędu. Mówimy wówczas, że system czasu przebiegu generuje (ang. throws) wyjątek. Przerwanie normalnego toku wykonywania programu w miejscu, w którym występuje instrukcja dzielenia, wiąże się z przejrzeniem aktualnego stosu wywołań (zawierającego adresy wywoływanych metod, ang. cali stack) w celu odnalezienia procedury obsługi wygenerowanego wyjątku. Przez procedurę obsługi wyjątku (ang. exception handler) rozumiemy sekwencję instrukcji wykonującą działania mające przeciwdziałać zaistniałej sytuacji nietypowej. W podanym przykładzie procedura taka nie została zdefiniowana, w związku z czym wykonana zostaje

68 Wykład Java ver procedura domyślna, należąca do systemu czasu przebiegu. Procedura ta wyświetla łańcuch (wartość obiektu typu String) zapisany w utworzonym obiekcie oraz zawartość stosu wywołań, opisującą miejsce, w którym pojawił się wyjątek. Komunikat wyświetlany przez podany wyżej przykład wygląda następująco: Zwróć uwagę na sposób wyświetlenia nazwy klasy Dzielenie(), nazwy metody main(), nazwy pliku Dzielenie.java oraz numeru wiersza zawierającego błędną instrukcję. Zauważ także, że typem utworzonego obiektu nie jest klasa Exception, czy tym bardziej Throwable, lecz specjalna podklasa klasy Exception, o nazwie ArithmeticException, dokładniej opisująca rodzaj zaistniałego błędu. Wprawdzie dokładne wyświetlanie zawartości stosu wywołań przez system przebiegu Javy po pojawieniu się wyjątku jest bardzo wygodne, ale często bardziej pożądane jest jego przechwycenie i obsłużenie przez program, a następnie kontynuowanie wykonywania programu. Za pomocą słowa kluczowego try można określić sekwencję instrukcji, w której mogą pojawić się przechwytywane przez program wyjątki. Bezpośrednio za blokiem try umieszcza się jeden lub więcej bloków catch, określających typy wyjątków, które mają być przechwytywane. Przedstawiony niżej program jest odpowiednikiem poprzedniego przykładu, z tym że zawiera konstrukcję try-catch.

69 Wykład Java ver plik: Dzielenie class Dzielenie { public static void main(string args[]) { try { int d=0; int a=42 /d; System.out.println("a/d="+a); catch(arithmeticexception e) { System.out.println("Dzielenie przez zero");

70 Wykład Java ver pliki:dziel.java class Dziel {public static void main(string args[]) { try { int a=args.length; System.out.println("a="+a); int b=42 /a; int c[]={ 1 ; c[42]=99; catch(arithmeticexception e) { System.out.println("Dzielenie przez zero"+e); catch(arrayindexoutofboundsexception e) { System.out.println("Przekroczenie zakresu tablicy"+e); catch(throwable t) { System.out.println("Otrzymano t:"+t); finally{system.out.println("koniec programu!!!");

71 Wykład Java ver Zakres bloku catch jest ograniczony do instrukcji znajdującej się bezpośrednio za słowem kluczowym try. Najczęściej jest to instrukcja złożona, składająca się z większej liczby instrukcji prostych; jeżeli ta część instrukcji try zawiera tylko jedną instrukcję prostą, to nie trzeba jej umieszczać w nawiasach klamrowych, ale pozostawienie ich nie jest błędem. Celem większości dobrze skonstruowanych bloków catch powinno być rozwiązanie zaistniałego problemu przez właściwe ustawienie odpowiednich zmiennych w celu umożliwienia dalszego działania programu, tak jakby błąd nie wystąpił. Jeżeli obsługą wyjątku nie zajął się wywołany podprogram, to zadanie to przejmuje metoda znajdująca się na stosie wywołań bezpośrednio nad nim. Jeśli i ta metoda nie obsługuje wyjątku, to otrzymuje go następna, aż do osiągnięcia maksymalnego poziomu, zajmowanego przez domyślną procedurę obsługi wyjątków, należącą do systemu czasu przebiegu Javy. Po wygenerowaniu wyjątku instrukcje aktualnej metody przestają być nagle wykonywane liniowo - część instrukcji jest chwilowo pomijana, a w przypadku braku odpowiedniego bloku catch dochodzi nawet do zakończenia działania programu. Czasami jednak chcemy mieć pewność, że określony fragment danego programu będzie zawsze wykonywany, niezależnie od tego, które wyjątki zostały wygenerowane czy przechwycone. Fragment taki można wskazać za pomocą słowa kluczowego finally. Nawet jeśli nie istnieje blok catch odpowiadający typowi wygenerowanego wyjątku, blok finally jest wykonywany przed przekazaniem sterowania pierwszej instrukcji znajdującej się za konstrukcją try. W każdej konstrukcji try musi znajdować się co najmniej jeden blok catch lub finally. Blok finally jest wykonywany tuż przed powrotem do metody wywołującej, spowodowanym brakiem odpowiedniego bloku catch lub wystąpieniem instrukcji return. Jest to wygodny sposób zamykania plików i zwalniania wszystkich innych zasobów, które zostały przydzielone aktualnej metodzie na początku jej wykonywania. Blok finally jest opcjonalny i w prostych konstrukcjach try-catch, nie wymagających gwarancji wykonania jakichkolwiek instrukcji, można go pominąć. Instrukcje try zagnieżdża się w podobny sposób Jak zakresy zmiennych. Na przykład w pewnym bloku try można umieścić wywołanie metody zawierającej kolejną konstrukcję try, związaną z inną sekwencją instrukcji. Kontekst każdej instrukcji try jest pamiętany od rozpoczęcia do zakończenia jej wykonywania. Jeżeli instrukcja try najniższego poziomu nie zawiera bloku catch odpowiadającego typowi wygenerowanego wyjątku, to jest on przekazywany do metody wyższego poziomu. W przypadku, gdy w żadnej z metod programu

72 Wykład Java ver nie ma bloku catch, który by obsługiwał wyjątki danego typu, wykonywana jest domyślna procedura systemu czasu przebiegu. Instrukcji throw używa się do ponownego, "ręcznego" generowania wyjątków. W tym celu należy najpierw uzyskać uchwyt egzemplarza klasy Throwable, odczytując wartość parametru pobieranego przez blok catch lub korzystając z operatora new Ogólna postać instrukcji throw wygląda następująco: throw EgzemplarzKlasyThrowable Natychmiast po napotkaniu instrukcji throw normalny tok wykonywania programu, ulega przerwaniu i zamiast następnej instrukcji wykonywany jest blok catch obsługujący wyjątki o typie określonym za słowem throw i związany z wykonywanym blokiem try. Jeżeli blok taki nie istnieje w aktualnie wykonywanej konstrukcji try, to jest on szukany w konstrukcjach nadrzędnych. W przypadku, gdy odpowiedni blok catch nie istnieje. w całym programie, wywoływana jest domyślna procedura obsługi wyjątków (należąca do systemu czasu przebiegu), która wyświetla odpowiedni komunikat i przerywa wykonywanie programu. Podany niżej program przykładowy zawiera metodę generującą dwukrotnie ten sam wyjątek. Za drugim razem jest on przekazywany metodzie wyższego poziomu: plik:insthrow class insthrow {static void ruszaj() {try{throw new NullPointerException("wyswietl ruszaj"); catch(nullpointerexception e) {System.out.println("Przechwycony w metodzie ruszaj()"); throw e; public static void main(string args[]) {try {ruszaj(); catch(nullpointerexception t) {System.out.println("Ponownie przechwycony:" +t);

73 Wykład Java ver Jeżeli metoda jest zdolna generować wyjątek, którego sama nie przechwytuje, należy to zaznaczyć w tekście programu, aby metody ją wywołujące mogły się przed nim zabezpieczyć. Listę wszystkich wyjątków generowanych przez daną metodę tworzy się za pomocą słowa kluczowego throws. Kompilator wymaga deklarowania wyjątków reprezentowanych przez klasę Exception oraz większość jej podklas Stwierdzenie to nie dotyczy klas Error i RuntimeException oraz ich wszystkich podklas, ponieważ zakłada się, że podczas normalnego wykonywania programu nie powinny się one pojawić. Tak więc za pomocą słowa kluczowego throws należy podać nazwy wszystkich wyjątków, które są generowane "ręcznie" przez daną metodę i są reprezentowane przez klasę Exception lub jedną z jej podklas, z wyłączeniem podklasy RuntimeException. W związku z tym pełna postać deklaracji metody wygląda następująco: typ nazwa_metody (lista_parametrów) throws lista_wyjątków { Podany niżej program zawiera metodę, która usiłuje wygenerować wyjątek, mimo iż sama go nie obsługuje i nie deklaruje jego nazwy za pomocą słowa kluczowego throws. Próba skompilowania tego programu kończy się wyświetleniem komunikatu o błędzie. I plik:insthrow1 class insthrow1 {static void ruszaj() throws IllegalAccessException {System.out.println("W metodzie ruszaj()"); throw new IllegalAccessException("do wgl\u0104du"); public static void main(string args[]) {try {ruszaj(); catch(illegalaccessexception l) {System.out.println("Ponownie przechwycony:" +l);

74 Wykład Java ver Wygenerowane i przechwycone mogą być wyłącznie wyjątki reprezentowane przez podklasy klasy Throwable. W charakterze wyjątków nie można używać typów prostych, takich jak int czy char, ani innych obiektów, w rodzaju String czy Object. Najczęściej do reprezentowania wyjątków używa się samodzielnie utworzonych klas będących podklasami klasy Exception. Implementacja takich klas jest bardzo prosta, a mimo to ich istnienie pozwala tworzyć programy z czytelną obsługą błędów oraz jasnymi, zorientowanymi obiektowo interfejsami przeznaczonymi dla użytkowników definiowanych klas. Interfejsy takie zawierają nie tylko definicje metod publicznych, ale także typy generowanych wyjątków. Podany niżej program przykładowy deklaruje nową podklasę klasy Exception, której następnie używa do zasygnalizowania błędu. plik: blad class blad extends Exception {private int dane; blad(int a) {dane=a; public String tostring() {return "Blad["+dane+"]"; plik:insthrow2 class insthrow2{ static void ruszaj(int a) throws blad {System.out.println("W metodzie ruszaj("+a+")"); if(a>10) throw new blad(a); System.out.println("Koniec ruszaj()"); public static void main(string args[]) {try {ruszaj(1); ruszaj(20); catch(blad l){system.out.println(" przechwycony przez wyj\u0104tek blad:" +l);

75 Wykład Java ver Zakończenie Obsługa wyjątków - to niezwykle wszechstronny. i pożyteczny mechanizm sterowania skomplikowanymi programami, których działanie może przebiegać na wiele różnych sposobów. Jednak słowa kluczowe try, throw i catch należy traktować wyłącznie jako elementy czytelnej obsługi błędów i nietypowych sytuacji pojawiających się podczas wykonywania programu. Niewłaściwe byłoby używanie ich w celu przechodzenia do innych metod, czyli w charakterze mechanizmu przypominającego istniejącą w innych językach instrukcję goto. Wyjątki systemowe Javy. Wszystkie wyjątki Javy dziedziczą po klasie Exception. Jest wiele możliwych wyjątków. Tutaj są przedstawione tylko najczęściej stosowane. ArithmeticException - Ten wyjątek napotkasz, gdy będziesz próbował wykonać niedozwoloną operację arytmetyczną, na przykład dzielenie przez zero. (Pamiętaj, że liczby zmiennopozycyjne nie zgłaszają wyjątków). ArrayIndexOutOfBoundsException - Java zgłosi ten wyjątek, gdy spróbujesz sięgnąć do elementu poza zakresem tablicy. ClassCastException - Ten wyjątek da o sobie znać, gdy spróbujesz rzutować obiekt do typu nie będącego na tej samej gałęzi hierarchii klas. (Na przykład, gdy spróbujesz rzutować Integer na String). InterruptedException - Ten wyjątek otrzymasz, gdy jeden wątek niespodziewanie przerwie pracę drugiego. IOException-Ten wyjątek oznacza, że stało się coś z wejściem- -wyjściem, na przykład nastąpiła próba czytania za końcem pliku. NullPointerException - Uzyskasz ten wyjątek wtedy, kiedy niepoprawnie użyjesz wskaźnika null. Jednym z częstszych sposobów uzyskania go jest sytuacja, gdy przy wywołaniu dwu metod jedna za drugą pierwsza z nich zwróci null zamiast obiektu, na przykład: firstmethod ().secondmethod (). OutOfMemoryException - Ten wyjątek otrzymasz, gdy zabraknie Ci pamięci operacyjnej.

76 Wykład Java ver Wątki i ich synchronizacja Programowanie wielowątkowe (ang. multi-threaded programming) charakteryzuje się tym, że tworzone programy dzieli się na dwa lub więcej procesów, które mogą przebiegać równocześnie. Okazuje się, że najlepiej jest, jeśli wiele zadań występujących w interakcyjnych programach jest wykonywanych współbieżnie. Do zadań takich należy między innymi: odczytywanie i zapisywanie plików, korzystanie z zasobów sieciowych, reagowanie na dane wprowadzane przez użytkownika, wykonywanie skomplikowanych, trwających nieraz kilka sekund obliczeń, a także wyświetlanie animacji i interfejsu użytkownika. Wszystkie te działania muszą programy wykonywać w taki sposób, aby użytkownik nie musiał czekać zbyt długo na ich zakończenie. Interesującą właściwością wszystkich wymienionych procesów przebiegających równolegle jest to, że większość z nich nie potrzebuje przez cały czas wszystkich zasobów komputera. Na przykład czas procesora niezbędny do transmisji danych jest minimalny, mimo iż wczytywanie strumienia danych z wolnej sieci może trwać minutę lub nawet dłużej. Również i reagowanie na dane wprowadzane przez użytkownika, na przykład za pomocą klawiatury, nie wymaga dużej aktywności ze strony jednostki centralnej - nawet najszybsza maszynistka nie jest w stanie nacisnąć w ciągu sekundy więcej niż dziesięć klawiszy. Rysunki tworzące animacje są zwykle wyświetlane od pięciu do dziesięciu razy na sekundę, więc również i podczas wykonywania tej czynności procesor przez większość czasu jest bezczynny. Nawet skomplikowane obliczenia nie muszą zajmować l00% czasu procesora, jeśli założyć, że ich wynik nie jest natychmiast potrzebny. Problem występujący w tradycyjnych jednowątkowych środowiskach polega na tym, że przed przystąpieniem do wykonywania następnego procesu trzeba poczekać na zakończenie poprzedniego. Nawet jeśli przez większość czasu procesor pozostaje bezczynny, to kolejne zadania muszą czekać na swoją kolej. W systemach jednowątkowych stosowane. jest rozwiązanie zwane pętlą zdarzeń z odpytywaniem (ang. event loop with polling). W takim modelu istnieje jedna pętla nieskończona, w której wykonywane są kolejne wątki pobierane z kolejki procesów. Poszczególne wątki, takie jak odczytanie pliku sieciowego czy wyświetlenie kolejnej klatki animacji, są wykonywane przez odpowiadające im procedury obsługi zdarzeń. Do zakończenia bieżącego wątku, czyli do czasu powrotu z odpowiedniej procedury, nie może być podjęte w systemie żadne inne działanie. W systemie wielowątkowym wykorzystuje się fakt, że większość czasu wykonywania wątków traci się na czekanie, aż potrzebny zasób stanie się dostępny. Jeżeli wszystkie procesy

77 Wykład Java ver są niezależnymi wątkami, a system potrafi przełączać się między wątkiem oczekującym aktualnie na jakiś zasób, a innym, gotowym do działania, to w tym samym czasie można wykonać znacznie więcej działań. Wystąpienie sytuacji, w której więcej wątków potrzebuje jednocześnie dużo czasu procesora, jest bardzo mało prawdopodobne. Ponieważ większość systemów operacyjnych nie ma dobrych mechanizmów przetwarzania wielowątkowego, to tradycyjne języki programowania, takie jak C++, nie zawierają elementów umożliwiających łatwe i czytelne opisywanie wątków. Poszczególne części programów są w tym przypadku synchronizowane za pomocą pojedynczej pętli zdarzeń. Innymi słowy, środowiska tradycyjne, do których zaliczają się między innymi Apple Macintosh, Microsoft Windows oraz X11/Motif, są synchronicznymi systemami zarządzanymi zdarzeniami. Java była projektowana od początku w warunkach. zarządzania wątkami na poziomie systemu operacyjnego. Z wątków korzysta w dużym stopniu system czasu przebiegu Javy, również wszystkie biblioteki klas były projektowane z myślą o przetwarzaniu wielowątkowym. Opóźnienia w utworzeniu systemów Javy dla Macintosha i MS-DOS-a wynikały właśnie z faktu, że żaden z tych systemów nie zawiera dobrych mechanizmów do zarządzania wątkami. Uwzględnienie wątków spowodowało, że środowisko programowania Javy stało się asynchroniczne. W programach Javy nie ma już pojedynczej pętli zdarzeń. Na przykład w czasie, gdy jeden wątek odczytuje dane z sieci, wszystkie pozostałe mogą działać bez jakichkolwiek przerw. Problemu nie stwarza również wątek czekający na dane wprowadzane przez użytkownika za pomocą klawiatury lub myszy czy wątek wyświetlający animację i nie wykonujący żadnych działań między wyświetlaniem kolejnych klatek. UWAGA: Jeżeli wykonywanie jakiegoś wątku zostało zablokowane, gdyż na przykład czeka on na wprowadzenie danych przez użytkownika, to wszystkie pozostałe wątki działają w sposób niezakłócony. Inaczej wygląda sytuacja w środowisku jednowątkowym, gdzie pojedynczy proces może zahamować działanie całego programu. Po uruchomieniu wątku można go zawiesić, czyli tymczasowo przerwać jego wykonywanie, a następnie wznowić. Wznowiony wątek kontynuuje działanie od miejsca, w którym został zawieszony. Istnieje również możliwość zatrzymania wątku, czyli natychmiastowego zakończenia jego wykonywania. Zatrzymanego wątku nie można ponownie wznowić. System czasu przebiegu Javy używa priorytetów w celu określenia wzajemnej zależności między wykonywaniem poszczególnych wątków. Priorytety wątków są liczbami całkowitymi z zakresu od 1 do 10 określającymi ważność jednego wątku względem drugiego. Mają one

78 Wykład Java ver znaczenie tylko wtedy, gdy są rozpatrywane łącznie. Jeśli w danej chwili istnieje w systemie tylko jeden wątek, to szybkość jego wykonywania nie zależy w najmniejszym stopniu od jego priorytetu -procesor może i tak wykonywać jednocześnie tylko jedną instrukcję. Priorytety stają się istotne dopiero wtedy, gdy więcej wątków ubiega się o przydział procesora. Przerwanie wykonywania jednego wątku i przydzielenie czasu procesora innemu nazywa się przełączaniem kontekstu (ang. context-switch). Zasady wykonywania tego zadania są proste, Każdy wątek może sam zwolnić procesor lub może zostać wywłaszczony. (ang. pre-empted). W pierwszym przypadku sterowanie przejmuje wątek o najwyższym priorytecie spośród wszystkich gotowych do działania. Druga sytuacja polega na tym, że wątek, który nie zwalnia procesora "dobrowolnie", jest go i tak pozbawiany, niezależnie od rodzaju wykonywanego zadania - następuje to wtedy, gdy pojawia się wątek o wyższym priorytecie. W zasadzie, wątek o wyższym priorytecie, który zgłasza gotowość do działania, otrzymuje natychmiast czas procesora. Takie rozwiązanie nazywa się wielozadaniowością z wywłaszczaniem (ang. pre-emptive multi-tasking). Jeżeli o czas procesora ubiegają się dwa wątki o takim samym priorytecie, to każdy z nim musi sam oddać sterowanie drugiemu. OSTRZEŻENIE: Niestety, w specyfikacji systemu czasu przebiegu Javy istnieje dwuznaczność. System działający w środowisku Windows 95 przydziela cyklicznie czas procesora kolejnym wątkom o takim samym priorytecie, podczas gdy system czasu przebiegu środowiska Solaris 2.x pozwala jednemu wątkowi całkowicie zablokować wykonywanie innych. Ponieważ istnienie wielu wątków powoduje asynchroniczne wykonywanie programów, programista musi mieć możliwość ich zsynchronizowania. Na przykład, jeśli dwa wątki mają współdzielić skomplikowaną strukturę danych, taką jak lista wiązana, to nie można dopuścić do tego, by wystąpiła między nimi kolizja. Dlatego w Javie został zaimplementowany znany od dawna model synchronizacji wewnątrzprocesowej, zwany monitorem. W modelu tym monitor można sobie wyobrazić jako bardzo małą skrzynkę, w której może się pomieścić tylko jeden wątek. W chwili, gdy do monitora dostaje się pewien wątek, wszystkie pozostałe muszą czekać, aż urządzenie to zostanie zwolnione. Tego rodzaju monitory można wykorzystywać do ochrony współdzielonych zasobów przed ich jednoczesnym wykorzystywaniem przez większą liczbę wątków. W większości systemów wielowątkowych funkcje monitorów pełnią obiekty. W Javie stosowane jest inne rozwiązanie. Nie ma tu klasy o nazwie Monitor, a zamiast tego każdy obiekt ma swój własny monitor, do którego każdy wątek może wejść przez wywołanie jednej z metod oznaczonych słowem kluczowym synchronized. W czasie, gdy jeden z wątków wykonuje metodę synchronizowaną, żaden inny nie może wywołać jakiejkolwiek innej metody synchronizowanej tego samego obiektu.

79 Wykład Java ver Podobnie jak wszystkie inne pojęcia Javy, wątki są reprezentowane przez obiekty określonej klasy. Nosi ona nazwę Thread i zawiera wszystkie metody niezbędne do zarządzania wątkami. Ważne jest, aby odróżniać wykonywany wątek od reprezentującego go obiektu klasy Thread, mimo iż występująca między nimi różnica jest subtelna. Obiekt typu Thread należy traktować jako panel sterowania wątku, zawierający metody, które umożliwiają jego uruchomienie, "uśpienie", zawieszenie i zatrzymanie. Klasa Thread jest jedynym elementem Javy pozwalającym na zarządzanie wątkami. Każdy wątek w pewnym momencie zaczyna się, następnie wykonuje określoną liczbę działań, po czym kończy się. Wszystkie programy przykładowe, które omawialiśmy do tej pory, składały się tylko z jednego wątku - od początku do końca ich działania był wykonywany tylko jeden wątek. W momencie uruchomienia każdego programu Javy jeden wątek już działa. O tym, który wątek jest w danej chwili wykonywany, można dowiedzieć się za pomocą metody statycznej Thread.currentThreadO. Po uzyskaniu uchwytu do bieżącego wątku pojawia się możliwość wykonania kilku interesujących działań. Ponieważ korzystanie z jednego tylko wątku nie jest zbyt interesujące, musimy odpowiedzieć na pytanie, w jaki sposób tworzy się kolejne wątki. Ogólnie mówiąc, polega to na tworzeniu kolejnych egzemplarzy klasy Thread. Nowo tworzony obiekt trzeba powiadomić o tym, który fragment programu ma być wykonywany w ramach nowego wątku. Może to być dowolny obiekt implementujący interfejs Runnable. Interfejs Runnable jest prostym interfejsem reprezentującym dowolny fragment programu działający asynchronicznie. Aby go zaimplementować, wystarczy zdefiniować tylko jedną metodę, o nazwie run(). Przykład utworzenia nowego wątku został podany niżej.

80 Wykład Java ver class wielo implements Runnable { wielo(int f) {Thread ct=thread.currentthread(); ct.setname("wątek pierwszy"); System.out.println("Utworzony wątek pierwszy: "+ct+f); Thread t= new Thread(this,"Wątek drugi"); System.out.println("Utworzony wątek drugi: "+t+f); t.start(); try{thread.sleep(3000); catch(interruptedexception e) {System.out.println("Przerwanie wątku głównego: "+e); System.out.println("wątek pierwszy stop: "+f); public void run() {try{ for(int n=5;n>=0;n--) {System.out.println("n="+n); Thread.sleep(1000); catch(interruptedexception e) {System.out.println("Przerwanie wątku potomnego"); System.out.println("wątek potomny stop"); public static void main(string args[]) {wielo zm=new wielo(4); wielo zm1=new wielo(8); Liczba 5 jest wartością domyślną priorytetu wątku Wątek pierwszy, została włą czona do reprezentacji łań cuchowej obiektu typu Thread. main to nazwa grupy do której on należy

Programowanie obiektowe

Programowanie obiektowe Programowanie obiektowe Wykład 2: Wstęp do języka Java 3/4/2013 S.Deniziak: Programowanie obiektowe - Java 1 Cechy języka Java Wszystko jest obiektem Nie ma zmiennych globalnych Nie ma funkcji globalnych

Bardziej szczegółowo

Podstawy programowania skrót z wykładów:

Podstawy programowania skrót z wykładów: Podstawy programowania skrót z wykładów: // komentarz jednowierszowy. /* */ komentarz wielowierszowy. # include dyrektywa preprocesora, załączająca biblioteki (pliki nagłówkowe). using namespace

Bardziej szczegółowo

1 Podstawy c++ w pigułce.

1 Podstawy c++ w pigułce. 1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,

Bardziej szczegółowo

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02 METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE Wykład 02 NAJPROSTSZY PROGRAM /* (Prawie) najprostszy przykład programu w C */ /*==================*/ /* Między tymi znaczkami można pisać, co się

Bardziej szczegółowo

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki Dariusz Brzeziński Politechnika Poznańska, Instytut Informatyki Język programowania prosty bezpieczny zorientowany obiektowo wielowątkowy rozproszony przenaszalny interpretowany dynamiczny wydajny Platforma

Bardziej szczegółowo

JAVA. Platforma JSE: Środowiska programistyczne dla języka Java. Wstęp do programowania w języku obiektowym. Opracował: Andrzej Nowak

JAVA. Platforma JSE: Środowiska programistyczne dla języka Java. Wstęp do programowania w języku obiektowym. Opracował: Andrzej Nowak JAVA Wstęp do programowania w języku obiektowym Bibliografia: JAVA Szkoła programowania, D. Trajkowska Ćwiczenia praktyczne JAVA. Wydanie III,M. Lis Platforma JSE: Opracował: Andrzej Nowak JSE (Java Standard

Bardziej szczegółowo

Zmienne, stałe i operatory

Zmienne, stałe i operatory Zmienne, stałe i operatory Przemysław Gawroński D-10, p. 234 Wykład 2 4 marca 2019 (Wykład 2) Zmienne, stałe i operatory 4 marca 2019 1 / 21 Outline 1 Zmienne 2 Stałe 3 Operatory (Wykład 2) Zmienne, stałe

Bardziej szczegółowo

Java EE produkcja oprogramowania

Java EE produkcja oprogramowania Java EE produkcja oprogramowania PPJ PODSTAWY PROGRAMOWANIA W JAVIE PODSTAWY JĘZYKA JAVA 1 Warszawa, 2016Z 2 Ogólna charakterystyka języka Java 3 Java 1/2 Język programowania Java został opracowany przez

Bardziej szczegółowo

Typy danych, zmienne i tablice. Tomasz Borzyszkowski

Typy danych, zmienne i tablice. Tomasz Borzyszkowski Typy danych, zmienne i tablice Tomasz Borzyszkowski Silne typy Javy Java jest językiem wyposażonym w silny system typów. Wywodzi się stąd siła i bezpieczeństwo tego języka. Co to znaczy silny system typów?

Bardziej szczegółowo

Czym jest Java? Rozumiana jako środowisko do uruchamiania programów Platforma software owa

Czym jest Java? Rozumiana jako środowisko do uruchamiania programów Platforma software owa 1 Java Wprowadzenie 2 Czym jest Java? Język programowania prosty zorientowany obiektowo rozproszony interpretowany wydajny Platforma bezpieczny wielowątkowy przenaszalny dynamiczny Rozumiana jako środowisko

Bardziej szczegółowo

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta 16.09.2006. Strona 1 z 26. Powrót. Full Screen. Zamknij.

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta 16.09.2006. Strona 1 z 26. Powrót. Full Screen. Zamknij. Programowanie Sobera Jolanta 16.09.2006 Strona 1 z 26 1 Wprowadzenie do programowania 4 2 Pierwsza aplikacja 5 3 Typy danych 6 4 Operatory 9 Strona 2 z 26 5 Instrukcje sterujące 12 6 Podprogramy 15 7 Tablice

Bardziej szczegółowo

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Program, to lista poleceń zapisana w jednym języku programowania zgodnie z obowiązującymi w nim zasadami. Celem programu jest przetwarzanie

Bardziej szczegółowo

1 Podstawy c++ w pigułce.

1 Podstawy c++ w pigułce. 1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,

Bardziej szczegółowo

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji. JAVA Java jest wszechstronnym językiem programowania, zorientowanym obiektowo, dostarczającym możliwość uruchamiania apletów oraz samodzielnych aplikacji. Java nie jest typowym kompilatorem. Źródłowy kod

Bardziej szczegółowo

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki Informatyka I Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki Politechnika Warszawska Wydział Transportu 2019 1 Plan wykładu

Bardziej szczegółowo

Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227 WYKŁAD 7 WSTĘP DO INFORMATYKI

Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227 WYKŁAD 7 WSTĘP DO INFORMATYKI Dr inż. Grażyna KRUPIŃSKA Grazyna.Krupinska@fis.agh.edu.pl D-10 pokój 227 WYKŁAD 7 WSTĘP DO INFORMATYKI Wyrażenia 2 Wyrażenia w języku C są bardziej elastyczne niż wyrażenia w jakimkolwiek innym języku

Bardziej szczegółowo

Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory

Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory Poniżej pozwoliłem sobie za cytować za wikipedią definicję zmiennej w informatyce.

Bardziej szczegółowo

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016 Wykład 1 3 marca 2016 Słowa kluczowe języka Java abstract, break, case, catch, class, const, continue, default, do, else, enum, extends, final, finally, for, goto, if, implements, import, instanceof, interface,

Bardziej szczegółowo

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static), Tworzenie obiektów Dostęp do obiektów jest realizowany przez referencje. Obiekty w języku Java są tworzone poprzez użycie słowa kluczowego new. String lan = new String( Lancuch ); Obszary pamięci w których

Bardziej szczegółowo

Języki Programowania II Wykład 3. Java podstawy. Przypomnienie

Języki Programowania II Wykład 3. Java podstawy. Przypomnienie Języki Programowania II Wykład 3 Java podstawy Przypomnienie Analiza, projektowanie, programowanie, testowanie, wdrażanie Iteracyjnie nie kaskadowo Przypadki użycia = opowiastki o używaniu systemu = wymagania

Bardziej szczegółowo

Podstawy programowania w języku C

Podstawy programowania w języku C Podstawy programowania w języku C WYKŁAD 1 Proces tworzenia i uruchamiania programów Algorytm, program Algorytm przepis postępowania prowadzący do rozwiązania określonego zadania. Program zapis algorytmu

Bardziej szczegółowo

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak Java język programowania obiektowego Programowanie w językach wysokiego poziomu mgr inż. Anna Wawszczak 1 Język Java Język Java powstał w roku 1995 w firmie SUN Microsystems Java jest językiem: wysokiego

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Przygotował: Jacek Sroka 1 Programowanie obiektowe Wykład 3 Java podstawy Przygotował: Jacek Sroka 2 Przypomnienie Analiza, projektowanie, programowanie, testowanie, wdrażanie Iteracyjnie nie kaskadowo

Bardziej szczegółowo

Podstawy i języki programowania

Podstawy i języki programowania Podstawy i języki programowania Laboratorium 2 - wprowadzenie do zmiennych mgr inż. Krzysztof Szwarc krzysztof@szwarc.net.pl Sosnowiec, 23 października 2017 1 / 26 mgr inż. Krzysztof Szwarc Podstawy i

Bardziej szczegółowo

Podstawy programowania w języku C i C++

Podstawy programowania w języku C i C++ Podstawy programowania w języku C i C++ Część czwarta Operatory i wyrażenia Autor Roman Simiński Kontakt roman.siminski@us.edu.pl www.us.edu.pl/~siminski Niniejsze opracowanie zawiera skrót treści wykładu,

Bardziej szczegółowo

Multimedia JAVA. Historia

Multimedia JAVA. Historia Multimedia JAVA mgr inż. Piotr Odya piotrod@sound.eti.pg.gda.pl Historia 1990 rozpoczęcie prac nad nowym systemem operacyjnym w firmie SUN, do jego tworzenia postanowiono wykorzystać nowy język programowania

Bardziej szczegółowo

Wstęp do programowania

Wstęp do programowania Wstęp do programowania wykład 2 Piotr Cybula Wydział Matematyki i Informatyki UŁ 2012/2013 http://www.math.uni.lodz.pl/~cybula Język programowania Każdy język ma swoją składnię: słowa kluczowe instrukcje

Bardziej szczegółowo

Java jako język programowania

Java jako język programowania Java jako język programowania Interpretowany programy wykonują się na wirtualnej maszynie (JVM Java Virtual Machine) Składnia oparta o język C++ W pełni zorientowany obiektowo (wszystko jest obiektem)

Bardziej szczegółowo

Java - wprowadzenie. Programowanie Obiektowe Mateusz Cicheński

Java - wprowadzenie. Programowanie Obiektowe Mateusz Cicheński Java - wprowadzenie Programowanie Obiektowe Mateusz Cicheński O języku Czym jest Java Cechy charakterystyczne języka Przykładowe zastosowania Składnia języka Podstawowe typy Wybrane słowa kluczowe Plan

Bardziej szczegółowo

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz Programowanie obiektowe Literatura: Autor: dr inŝ. Zofia Kruczkiewicz Java P. L. Lemay, Naughton R. Cadenhead Java Podręcznik 2 dla kaŝdego Języka Programowania Java Linki Krzysztof Boone oprogramowania

Bardziej szczegółowo

JAVA W SUPER EXPRESOWEJ PIGUŁCE

JAVA W SUPER EXPRESOWEJ PIGUŁCE JAVA W SUPER EXPRESOWEJ PIGUŁCE Obiekt Obiekty programowe to zbiór własności i zachowań (zmiennych i metod). Podobnie jak w świecie rzeczywistym obiekty posiadają swój stan i zachowanie. Komunikat Wszystkie

Bardziej szczegółowo

Powtórka algorytmów. Wprowadzenie do języka Java.

Powtórka algorytmów. Wprowadzenie do języka Java. Powtórka algorytmów. Wprowadzenie do języka Java. BEGIN Readln(a); Readln(b); Suma := 0; IF Suma < 10 THEN Writeln( Suma wynosi:, Suma); ELSE Writeln( Suma większa niż 10! ) END. 1. Narysować schemat blokowy

Bardziej szczegółowo

Ogólny schemat prostego formularza: A może lepiej zamiast przycisku opartego o input tak:

Ogólny schemat prostego formularza: A może lepiej zamiast przycisku opartego o input tak: Ogólny schemat prostego formularza: A może lepiej zamiast przycisku opartego o input tak: accept - typy zawartości MIME akceptowane przez serwer (opcjonalny) accept-charset - zestaw znaków akceptowanych

Bardziej szczegółowo

2 Przygotował: mgr inż. Maciej Lasota

2 Przygotował: mgr inż. Maciej Lasota Laboratorium nr 2 1/7 Język C Instrukcja laboratoryjna Temat: Wprowadzenie do języka C 2 Przygotował: mgr inż. Maciej Lasota 1) Wprowadzenie do języka C. Język C jest językiem programowania ogólnego zastosowania

Bardziej szczegółowo

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1 Podstawy programowania. Wykład Funkcje Krzysztof Banaś Podstawy programowania 1 Programowanie proceduralne Pojęcie procedury (funkcji) programowanie proceduralne realizacja określonego zadania specyfikacja

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Programowanie obiektowe Laboratorium 1. Wstęp do programowania w języku Java. Narzędzia 1. Aby móc tworzyć programy w języku Java, potrzebny jest zestaw narzędzi Java Development Kit, który można ściągnąć

Bardziej szczegółowo

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu Programowanie strukturalne Opis ogólny programu w Turbo Pascalu STRUKTURA PROGRAMU W TURBO PASCALU Program nazwa; } nagłówek programu uses nazwy modułów; } blok deklaracji modułów const } blok deklaracji

Bardziej szczegółowo

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

Temat 1: Podstawowe pojęcia: program, kompilacja, kod Temat 1: Podstawowe pojęcia: program, kompilacja, kod wynikowy. Przykłady najprostszych programów. Definiowanie zmiennych. Typy proste. Operatory: arytmetyczne, przypisania, inkrementacji, dekrementacji,

Bardziej szczegółowo

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h] 1. Typy. Java jest językiem programowania z silnym systemem kontroli typów. To oznacza, że każda zmienna, atrybut czy parametr ma zadeklarowany typ. Kompilator wylicza typy wszystkich wyrażeń w programie

Bardziej szczegółowo

Operacje wykonywane są na operandach (argumentach operatorów). Przy operacji dodawania: argumentami operatora dodawania + są dwa operandy 2 i 5.

Operacje wykonywane są na operandach (argumentach operatorów). Przy operacji dodawania: argumentami operatora dodawania + są dwa operandy 2 i 5. Operatory w Javie W Javie występują następujące typy operatorów: Arytmetyczne. Inkrementacji/Dekrementacji Przypisania. Porównania. Bitowe. Logiczne. Pozostałe. Operacje wykonywane są na operandach (argumentach

Bardziej szczegółowo

Programowanie strukturalne i obiektowe

Programowanie strukturalne i obiektowe Programowanie strukturalne i obiektowe Język C część I Opracował: Grzegorz Flesik Literatura: A. Majczak, Programowanie strukturalne i obiektowe, Helion, Gliwice 2010 P. Domka, M. Łokińska, Programowanie

Bardziej szczegółowo

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach? Część XVIII C++ Funkcje Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach? Umiemy już podzielić nasz

Bardziej szczegółowo

Powtórka algorytmów. Wprowadzenie do języka Java.

Powtórka algorytmów. Wprowadzenie do języka Java. Powtórka algorytmów. Wprowadzenie do języka Java. BEGIN Readln(a); Readln(b); Suma := 0; IF Suma < 10 THEN Writeln( Suma wynosi:, Suma); ELSE Writeln( Suma większa niż 10! ) END. Ważne terminy: Java DevelopRment

Bardziej szczegółowo

Języki programowania C i C++ Wykład: Typy zmiennych c.d. Operatory Funkcje. dr Artur Bartoszewski - Języki C i C++, sem.

Języki programowania C i C++ Wykład: Typy zmiennych c.d. Operatory Funkcje. dr Artur Bartoszewski - Języki C i C++, sem. Języki programowania C i C++ Wykład: Typy zmiennych c.d. Operatory Funkcje 1 dr Artur Bartoszewski - Języki C i C++, sem. 1I- WYKŁAD programowania w C++ Typy c.d. 2 Typy zmiennych Instrukcja typedef -

Bardziej szczegółowo

Podstawy programowania. 1. Operacje arytmetyczne Operacja arytmetyczna jest opisywana za pomocą znaku operacji i jednego lub dwóch wyrażeń.

Podstawy programowania. 1. Operacje arytmetyczne Operacja arytmetyczna jest opisywana za pomocą znaku operacji i jednego lub dwóch wyrażeń. Podstawy programowania Programowanie wyrażeń 1. Operacje arytmetyczne Operacja arytmetyczna jest opisywana za pomocą znaku operacji i jednego lub dwóch wyrażeń. W językach programowania są wykorzystywane

Bardziej szczegółowo

Początki Javy. dr Anna Łazińska, WMiI UŁ Podstawy języka Java 1 / 8

Początki Javy. dr Anna Łazińska, WMiI UŁ Podstawy języka Java   1 / 8 Początki Javy Java została pierwotnie zaprojektowana dla telewizji interaktywnej, ale była to zbyt zaawansowaną technologią dla branży cyfrowej telewizji kablowej. James Gosling, Mike Sheridan i Patrick

Bardziej szczegółowo

Programowanie w Internecie. Java

Programowanie w Internecie. Java Programowanie w Internecie Java Autor: dr inż. Zofia Kruczkiewicz Literatura: L. Lemay, R. Cadenhead P. Naughton Krzysztof Barteczko Boone Barry Java 2 dla każdego Podręcznik Języka Programowania Java

Bardziej szczegółowo

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów Operatory są elementami języka C++. Istnieje zasada, że z elementami języka, takimi jak np. słowa kluczowe, nie można dokonywać żadnych zmian, przeciążeń, itp. PRZECIĄŻANIE OPERATORÓW Ale dla operatorów

Bardziej szczegółowo

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut. Konstruktory Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut. Rozpatrzmy przykład przedstawiający klasę Prostokat: class

Bardziej szczegółowo

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie Część X C++ Typ znakowy służy do reprezentacji pojedynczych znaków ASCII, czyli liter, cyfr, znaków przestankowych i innych specjalnych znaków widocznych na naszej klawiaturze (oraz wielu innych, których

Bardziej szczegółowo

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6 JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM Wykład 6 1 SPECYFIKATOR static Specyfikator static: Specyfikator ten powoduje, że zmienna lokalna definiowana w obrębie danej funkcji nie jest niszczona

Bardziej szczegółowo

Materiały pomocnicze do wykładu 3 - Elementy języka Java

Materiały pomocnicze do wykładu 3 - Elementy języka Java Materiały pomocnicze do wykładu 3 - Elementy języka Java 1) Typy danych Typy całkowite Typ Rozmiar Zakres przechowywanych danych byte 8 bitów -128 do 127 short 16 bitów -32768 do 32767 int 32 bity -2147483648

Bardziej szczegółowo

Informatyka, Ćwiczenie 1. 1. Uruchomienie Microsoft Visual C++ Politechnika Rzeszowska, Wojciech Szydełko. I. ZałoŜenie nowego projektu

Informatyka, Ćwiczenie 1. 1. Uruchomienie Microsoft Visual C++ Politechnika Rzeszowska, Wojciech Szydełko. I. ZałoŜenie nowego projektu Informatyka, Ćwiczenie 1 1. Uruchomienie Microsoft Visual C++ I. ZałoŜenie nowego projektu Wybieramy menu: File>New>Files jak na rys. poniŝej Zapisujemy projekt pod nazwą LAN, w katalogu d:\temp\lab typu

Bardziej szczegółowo

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Tablice (jedno i wielowymiarowe), łańcuchy znaków Tablice (jedno i wielowymiarowe), łańcuchy znaków wer. 8 z drobnymi modyfikacjami! Wojciech Myszka Katedra Mechaniki i Inżynierii Materiałowej 2017-04-07 09:35:32 +0200 Zmienne Przypomnienie/podsumowanie

Bardziej szczegółowo

Wykład 8: klasy cz. 4

Wykład 8: klasy cz. 4 Programowanie obiektowe Wykład 8: klasy cz. 4 Dynamiczne tworzenie obiektów klas Składniki statyczne klas Konstruktor i destruktory c.d. 1 dr Artur Bartoszewski - Programowanie obiektowe, sem. 1I- WYKŁAD

Bardziej szczegółowo

Wprowadzenie do języka Java

Wprowadzenie do języka Java WSNHiD, Programowanie 2 Lab. 1 [ część 1 ] Wprowadzenie do języka Java Wprowadzenie Język programowania Java jest obiektowym językiem programowania. Powstał w 1995 i od tej pory był intensywnie rozwijany.

Bardziej szczegółowo

Język JAVA podstawy. wykład 2, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Język JAVA podstawy. wykład 2, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna Język JAVA podstawy wykład 2, część 1 1 Język JAVA podstawy Plan wykładu: 1. Rodzaje programów w Javie 2. Tworzenie aplikacji 3. Tworzenie apletów 4. Obsługa archiwów 5. Wyjątki 6. Klasa w klasie! 2 Język

Bardziej szczegółowo

Powtórka algorytmów. Wprowadzenie do języka Java.

Powtórka algorytmów. Wprowadzenie do języka Java. Powtórka algorytmów. Wprowadzenie do języka Java. Przypomnienie schematów blokowych BEGIN Readln(a); Readln(b); Suma := 0; IF Suma < 10 THEN Writeln( Suma wynosi:, Suma); ELSE Writeln( Suma większa niż

Bardziej szczegółowo

Java Podstawy. Michał Bereta

Java Podstawy. Michał Bereta Prezentacja współfinansowana przez Unię Europejską ze środków Europejskiego Funduszu Społecznego w ramach projektu Wzmocnienie znaczenia Politechniki Krakowskiej w kształceniu przedmiotów ścisłych i propagowaniu

Bardziej szczegółowo

Podstawy i języki programowania

Podstawy i języki programowania Podstawy i języki programowania Laboratorium 3 - operatory oraz instrukcje warunkowe i wyboru mgr inż. Krzysztof Szwarc krzysztof@szwarc.net.pl Sosnowiec, 19 października 2018 1 / 35 mgr inż. Krzysztof

Bardziej szczegółowo

Język C zajęcia nr 11. Funkcje

Język C zajęcia nr 11. Funkcje Język C zajęcia nr 11 Funkcje W języku C idea podprogramów realizowana jest wyłącznie poprzez definiowanie i wywołanie funkcji. Każda funkcja musi być przed wywołaniem zadeklarowana. Deklaracja funkcji

Bardziej szczegółowo

Jeśli chcesz łatwo i szybko opanować podstawy C++, sięgnij po tę książkę.

Jeśli chcesz łatwo i szybko opanować podstawy C++, sięgnij po tę książkę. Języki C i C++ to bardzo uniwersalne platformy programistyczne o ogromnych możliwościach. Wykorzystywane są do tworzenia systemów operacyjnych i oprogramowania użytkowego. Dzięki niskiemu poziomowi abstrakcji

Bardziej szczegółowo

Rozdział 4 KLASY, OBIEKTY, METODY

Rozdział 4 KLASY, OBIEKTY, METODY Rozdział 4 KLASY, OBIEKTY, METODY Java jest językiem w pełni zorientowanym obiektowo. Wszystkie elementy opisujące dane, za wyjątkiem zmiennych prostych są obiektami. Sam program też jest obiektem pewnej

Bardziej szczegółowo

Operatory. Operatory bitowe i uzupełnienie informacji o pozostałych operatorach. Programowanie Proceduralne 1

Operatory. Operatory bitowe i uzupełnienie informacji o pozostałych operatorach. Programowanie Proceduralne 1 Operatory Operatory bitowe i uzupełnienie informacji o pozostałych operatorach. Programowanie Proceduralne 1 Przypomnienie: operatory Operator przypisania = przypisanie x = y x y Operatory arytmetyczne

Bardziej szczegółowo

Odczyt danych z klawiatury Operatory w Javie

Odczyt danych z klawiatury Operatory w Javie Odczyt danych z klawiatury Operatory w Javie Operatory W Javie występują następujące typy operatorów: Arytmetyczne. Inkrementacji/Dekrementacji Przypisania. Porównania. Bitowe. Logiczne. Pozostałe. Operacje

Bardziej szczegółowo

Część 4 życie programu

Część 4 życie programu 1. Struktura programu c++ Ogólna struktura programu w C++ składa się z kilku części: część 1 część 2 część 3 część 4 #include int main(int argc, char *argv[]) /* instrukcje funkcji main */ Część

Bardziej szczegółowo

KOTLIN. Język programowania dla Androida

KOTLIN. Język programowania dla Androida KOTLIN Język programowania dla Androida Historia Kotlin został opracowany przez firmę JetBrains Prace rozpoczęto w 2011 r., od 2012 r. dostępny na licencji Apache 2. Nazwa pochodzi od wyspy koło Petersburga

Bardziej szczegółowo

Podstawy Programowania C++

Podstawy Programowania C++ Wykład 3 - podstawowe konstrukcje Instytut Automatyki i Robotyki Warszawa, 2014 Wstęp Plan wykładu Struktura programu, instrukcja przypisania, podstawowe typy danych, zapis i odczyt danych, wyrażenia:

Bardziej szczegółowo

WPROWADZENIE DO JĘZYKA JAVA

WPROWADZENIE DO JĘZYKA JAVA WPROWADZENIE DO JĘZYKA JAVA programowanie obiektowe KRÓTKA HISTORIA JĘZYKA JAVA KRÓTKA HISTORIA JĘZYKA JAVA 1991 - narodziny języka java. Pierwsza nazwa Oak (dąb). KRÓTKA HISTORIA JĘZYKA JAVA 1991 - narodziny

Bardziej szczegółowo

Języki i metody programowania Java. Wykład 2 (część 2)

Języki i metody programowania Java. Wykład 2 (część 2) Języki i metody programowania Java INF302W Wykład 2 (część 2) Autor Dr inż. Zofia Kruczkiewicz 1 Struktura wykładu 1. Identyfikacja danych reprezentowanych przez klasy podczas opracowania koncepcji prostego

Bardziej szczegółowo

Wykład 2 Składnia języka C# (cz. 1)

Wykład 2 Składnia języka C# (cz. 1) Wizualne systemy programowania Wykład 2 Składnia języka C# (cz. 1) 1 dr Artur Bartoszewski -Wizualne systemy programowania, sem. III- WYKŁAD Wizualne systemy programowania Budowa projektu 2 Struktura programu

Bardziej szczegółowo

Programowanie obiektowe zastosowanie języka Java SE

Programowanie obiektowe zastosowanie języka Java SE Programowanie obiektowe zastosowanie języka Java SE Wstęp do programowania obiektowego w Javie Autor: dr inŝ. 1 Java? Java język programowania obiektowo zorientowany wysokiego poziomu platforma Javy z

Bardziej szczegółowo

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość 1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość 2. Poprawna definicja wskażnika b to: a) float *a, **b = &a; b) float

Bardziej szczegółowo

Język ludzki kod maszynowy

Język ludzki kod maszynowy Język ludzki kod maszynowy poziom wysoki Język ludzki (mowa) Język programowania wysokiego poziomu Jeśli liczba punktów jest większa niż 50, test zostaje zaliczony; w przeciwnym razie testu nie zalicza

Bardziej szczegółowo

Jak napisać program obliczający pola powierzchni różnych figur płaskich?

Jak napisać program obliczający pola powierzchni różnych figur płaskich? Część IX C++ Jak napisać program obliczający pola powierzchni różnych figur płaskich? Na początku, przed stworzeniem właściwego kodu programu zaprojektujemy naszą aplikację i stworzymy schemat blokowy

Bardziej szczegółowo

/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h>

/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h> Szablon programu: /* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include /* opcjonalne: deklaracja typów o rozmiarze jednego i dwóch

Bardziej szczegółowo

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście. Typy, operatory, wyrażenia. Wejście i wyjście. Typy, operatory, wyrażenia Zmienna: [] [ '[' ']' ] ['=' ]; Zmienna to fragment pamięci o określonym

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Programowanie obiektowe Literatura: Autor: dr inŝ. Zofia Kruczkiewicz Java P. L. Krzysztof Lemay, Naughton Barteczko R. Cadenhead JAVA, Java Podręcznik 2 wykłady dla kaŝdego Języka i ćwiczenia Programowania

Bardziej szczegółowo

MATERIAŁY DO ZAJĘĆ II

MATERIAŁY DO ZAJĘĆ II MATERIAŁY DO ZAJĘĆ II Zmienne w C# Spis treści I. Definicja zmiennej II. Hierarchia typów (CTS) III. Typy wbudowane IV. Deklaracja zmiennych V. Literały VI. Pobieranie i wypisywanie wartości zmiennych

Bardziej szczegółowo

utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,

utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy, Lista 3 Zestaw I Zadanie 1. Zaprojektować i zaimplementować funkcje: utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy, zapisz

Bardziej szczegółowo

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny Technologiczny Politechnika Śląska

Instytut Mechaniki i Inżynierii Obliczeniowej  Wydział Mechaniczny Technologiczny Politechnika Śląska Instytut Mechaniki i Inżynierii Obliczeniowej www.imio.polsl.pl fb.com/imiopolsl @imiopolsl Wydział Mechaniczny Technologiczny Politechnika Śląska Języki programowania z programowaniem obiektowym Laboratorium

Bardziej szczegółowo

Microsoft IT Academy kurs programowania

Microsoft IT Academy kurs programowania Microsoft IT Academy kurs programowania Podstawy języka C# Maciej Hawryluk Język C# Język zarządzany (managed language) Kompilacja do języka pośredniego (Intermediate Language) Kompilacja do kodu maszynowego

Bardziej szczegółowo

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Java - tablice, konstruktory, dziedziczenie i hermetyzacja Java - tablice, konstruktory, dziedziczenie i hermetyzacja Programowanie w językach wysokiego poziomu mgr inż. Anna Wawszczak PLAN WYKŁADU zmienne tablicowe konstruktory klas dziedziczenie hermetyzacja

Bardziej szczegółowo

Języki i metodyka programowania. Wprowadzenie do języka C

Języki i metodyka programowania. Wprowadzenie do języka C Literatura: Brian W. Kernighan, Dennis M. Ritchie Język Ansi C, Wydawnictwa Naukowo - Techniczne, 2007 http://cm.bell-labs.com/cm/cs/cbook/index.html Scott E. Gimpel, Clovis L. Tondo Język Ansi C. Ćwiczenia

Bardziej szczegółowo

Operatory w C++ Operatory arytmetyczne. Operatory relacyjne (porównania) Operatory logiczne. + dodawanie - odejmowanie * mnożenie / dzielenie % modulo

Operatory w C++ Operatory arytmetyczne. Operatory relacyjne (porównania) Operatory logiczne. + dodawanie - odejmowanie * mnożenie / dzielenie % modulo Operatory w C++ Operatory arytmetyczne + dodawanie - odejmowanie * mnożenie / dzielenie % modulo Operatory relacyjne (porównania) < mniejszy niż większy niż >= większy lub równy

Bardziej szczegółowo

Mikrokontroler ATmega32. Język symboliczny

Mikrokontroler ATmega32. Język symboliczny Mikrokontroler ATmega32 Język symboliczny 1 Język symboliczny (asembler) jest językiem niskiego poziomu - pozwala pisać programy złożone z instrukcji procesora. Kody instrukcji są reprezentowane nazwami

Bardziej szczegółowo

Algorytm. a programowanie -

Algorytm. a programowanie - Algorytm a programowanie - Program komputerowy: Program komputerowy można rozumieć jako: kod źródłowy - program komputerowy zapisany w pewnym języku programowania, zestaw poszczególnych instrukcji, plik

Bardziej szczegółowo

Lab 9 Podstawy Programowania

Lab 9 Podstawy Programowania Lab 9 Podstawy Programowania (Kaja.Gutowska@cs.put.poznan.pl) Wszystkie kody/fragmenty kodów dostępne w osobnym pliku.txt. Materiały pomocnicze: Wskaźnik to specjalny rodzaj zmiennej, w której zapisany

Bardziej szczegółowo

Programowanie C++ Wykład 2 - podstawy języka C++ dr inż. Jakub Możaryn. Warszawa, Instytut Automatyki i Robotyki

Programowanie C++ Wykład 2 - podstawy języka C++ dr inż. Jakub Możaryn. Warszawa, Instytut Automatyki i Robotyki Wykład 2 - podstawy języka C++ Instytut Automatyki i Robotyki Warszawa, 2014 Wstęp Plan wykładu Struktura programu. Zmienne i ich nazwy, podstawowe typy: całkowite, rzeczywiste, znakowe i napisowe. Instrukcje:

Bardziej szczegółowo

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main. Część XVI C++ Funkcje Jeśli nasz program rozrósł się już do kilkudziesięciu linijek, warto pomyśleć o jego podziale na mniejsze części. Poznajmy więc funkcje. Szybko się przekonamy, że funkcja to bardzo

Bardziej szczegółowo

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost; Klasy w C++ są bardzo ważnym narzędziem w rękach programisty. Klasy są fundamentem programowania obiektowego. Z pomocą klas będziesz mógł tworzyć lepszy kod, a co najważniejsze będzie on bardzo dobrze

Bardziej szczegółowo

Podstawy Programowania Podstawowa składnia języka C++

Podstawy Programowania Podstawowa składnia języka C++ Podstawy Programowania Podstawowa składnia języka C++ Katedra Analizy Nieliniowej, WMiI UŁ Łódź, 3 października 2013 r. Szablon programu w C++ Najprostszy program w C++ ma postać: #include #include

Bardziej szczegółowo

Dokumentacja do API Javy.

Dokumentacja do API Javy. Dokumentacja do API Javy http://java.sun.com/j2se/1.5.0/docs/api/ Klasy i obiekty Klasa jest to struktura zawierająca dane (pola), oraz funkcje operujące na tych danych (metody). Klasa jest rodzajem szablonu

Bardziej szczegółowo

Wiadomości wstępne Środowisko programistyczne Najważniejsze różnice C/C++ vs Java

Wiadomości wstępne Środowisko programistyczne Najważniejsze różnice C/C++ vs Java Wiadomości wstępne Środowisko programistyczne Najważniejsze różnice C/C++ vs Java Cechy C++ Język ogólnego przeznaczenia Można programować obiektowo i strukturalnie Bardzo wysoka wydajność kodu wynikowego

Bardziej szczegółowo

Spis treści. 1 Java T M

Spis treści. 1 Java T M Spis treści 1 Java T M 1 2 Co to jest Platforma Java T M 1 3 Przygotowanie komputera 2 4 Pierwszy program 2 5 Dokumentacja 3 6 Budowa aplikacji. Klasy. 3 7 Pola i metody 4 8 Konstruktory 5 9 Inne proste

Bardziej szczegółowo

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 10 Kurs C++

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 10 Kurs C++ Podstawy Informatyki Inżynieria Ciepła, I rok Wykład 10 Kurs C++ Historia Lata 70-te XX w język C (do pisania systemów operacyjnych) "The C programming language" B. Kernighan, D. Ritchie pierwszy standard

Bardziej szczegółowo

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu. Część XIX C++ w Każda poznana do tej pory zmienna może przechowywać jedną liczbę. Jeśli zaczniemy pisać bardziej rozbudowane programy, okaże się to niewystarczające. Warto więc poznać zmienne, które mogą

Bardziej szczegółowo

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44 Programowanie w C++ Wykład 2 Katarzyna Grzelak 4 marca 2019 K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44 Na poprzednim wykładzie podstawy C++ Każdy program w C++ musi mieć funkcję o nazwie main Wcięcia

Bardziej szczegółowo

Podstawy programowania obiektowego

Podstawy programowania obiektowego Podstawy programowania obiektowego Technologie internetowe Wykład 5 Program wykładu Podejście obiektowe kontra strukturalne do tworzenie programu Pojęcie klasy i obiektu Składowe klasy: pola i metody Tworzenie

Bardziej szczegółowo