Odkryj ścieżki Javy

Steven Feuerstein

Rozpoczynam teraz pracę nad projektem, który udokumentuje
ścieżki, jakie muszę przejść od mojego obecnego stanu, czyli proceduralnego developera PL/SQL, do zorientowanej obiektowo istoty
– CzlowiekJava. Ale nie martwcie się! Nie mam zamiaru porzucić PL/SQL. Bardzo mi do tego daleko. Dlaczego? Ponieważ zarówno PL/SQL, jak i Java będą językami wiodącymi w
świecie Oracle przez najbliższe nadchodzące lata.

Mam zamiar bardziej skupić się na samym procesie uczenia się, niż na wyuczonym materiale. Bardzo istotne jest, aby zrozumieć jak Java działa. Jednak moim zdaniem do ważniejszych umiejętności należą logiczne rozwiązywanie problemów i abstrakcyjne myślenie. Chciałbym nauczyć tego, przynajmniej częściowo, przy wykorzystaniu przykładów, porównań i fragmentów kodu.

Skoncentruję się oczywiście także dość szczegółowo na wyzwaniach, jakie my
– developerzy PL/SQL spotykamy, rozszerzając integrację Javy i naszych kluczowych dla przedsiębiorstwa systemów.
Przedstawię porównania tych dwóch języków. Zaimplementuję w Javie niektóre interesujące programy, wynikające z mojego doświadczenia w PL/SQL, w szczególności elementy PL/Vision (biblioteka PL/SQL mojego autorstwa, jest ona dostępna na stronie firmy RevealNet, www.revealnet.com).

Krótki wstęp


Ten artykuł obejmuje moją aktualną wiedzę i jest jednocześnie wyrazem wielkiego zadowolenia, że mogę się nią podzielić tworząc
„Odkryj ścieżki Javy". Jest to tematyka rozwijająca się bardzo szybko, dlatego też nowy materiał zostanie zaprezentowany niebawem. Nie chcę przedstawiać czytelnikom problemów dotyczących programowania obiektowego i pojęć z tym związanych. Jest wiele książek, na te tematy, napisanych przez znacznie lepszych specjalistów ode mnie. Wielu spojrzy zapewne z niedowierzaniem: specjalista PL/SQL, który odkrył wszystkie
ścieżki Javy…
Mam inną propozycję. Spróbujmy odkryć je razem!

Kreślenie ścieżek


Zacznę od przypomnienia podstawowych elementów składni języka Java, a następnie porównam je do PL/SQL. Od tego miejsca spróbuję wyjaśnić, jak się tworzy programy w Javie (klasy oczywiście!), by później powrócić do rodzimych struktur, które tak dobrze wszyscy dobrze znamy i kochamy (naprawdę, nie wstydźcie się do tego przyznać) w PL/SQL.

Java jest czystym językiem zorientowanym obiektowo. Wszystko, co stworzysz w Javie jest klasą, a obiekt jest urzeczywistnieniem klasy. Mamy tu wiele rodzajów klas: publiczne (public) i prywatne (private), klasy abstrakcyjne (abstract), klasy wewnętrzne, interfejsy i inne. Częściowo są to typy łatwe do zrozumienia, niektóre są prawie wyzwaniem.

Poza orientacją obiektową, jest jeszcze jeden aspekt Javy, który uderzył mnie od samego początku
– to budzący grozę – choć może słowo "przygniatający” byłoby bardziej odpowiednim określeniem moich uczuć
– zakres predefiniowanych, czy wbudowanych funkcji. Wraz z Java SDK (Software Development Kit) wprowadzono niesamowicie dużo klas, co w praktyce oznacza, że jest mnóstwo rzeczy, których nie musimy pisać, do momentu oczywiście, kiedy wiemy, co się za czym kryje i jak tego używać.

Obracam się w moim fotelu, rozglądam po biurze i naliczyłem właśnie 16 książek o Javie tylko z wydawnictwa
"O’Reilly and Associates". Uzupełniam tą pierwszorzędną kolekcję innymi pozycjami:

  • Thinking in Java, Bruce Eckel. Jego styl pisarski oraz osiągnięcia techniczne przypominają mi siebie samego w
    świecie PL/SQL.
  • The Java Programming Language, 2nd Edition, Ken Arnold, James Gosling. Gosling jest developerem Javy.

Tak wiele materiału do nauczenia i tak mało czasu. Tak zawsze było w naszej dziedzinie, ale przeczuwam, że w przypadku Javy krzywa absorpcji znacznie wzrosła. Oczywiście, odwracając kota ogonem, możesz bardzo dużo dokonać w Javie przy relatywnie niewielkich ilościach czytelnego, uporządkowanego kodu (w każdym razie to mi bez przerwy powtarzają eksperci). Nie ma wątpliwości, że z tej perspektywy jest to język silniejszy i bardziej przydatny niż PL/SQL.

Hello World, czyli Witaj
Świecie



Zacznijmy od samego początku, który zawsze jest dobrym miejscem, żeby zacząć. PL/SQL jest językiem o strukturze blokowej, ze specyficznymi kluczowymi słowami na początku i na końcu sekcji. W porównaniu do
Cobol’a jest to język lapidarny. W porównaniu do Javy- niesamowicie rozbudowany.

Aby zrozumieć sens tej podstawowej różnicy, spójrzmy na
„konkurencyjne” implementacje programów do wyświetlenia „Hello World” na ekranie. Najpierw zobaczymy jak wygląda to w Javie:


public class Hello {

    public static void main (String[] args) {

       System.out.println („Hello world!”);

    }

}

A teraz rzućmy okiem na PL/SQL:



CREATE OR REPLACE PROCEDURE hello IS

BEGIN

  DBMS_OUTPUT.PUT_LINE (‚Hello world!’);

END;

Żeby być bardziej fair w stosunku do Javy, oto pakietowa implementacja, która ma korespondować z implementacją klasową w Javie:




CREATE OR REPLACE PACKAGE hello

IS

    PROCEDURE world;

END;

/

CREATE OR REPLACE PACKAGE hello

IS

    PROCEDURE world IS BEGIN

       DBMS_OUTPUT.PUT_LINE (‚Hello world!’);

    END;

END hello;

/

Cóż, jak widać osiągnięcie zamierzonego efektu nie wymaga od nas pisania szczególnie długiego kodu ani w Javie, ani w PL/SQL. W Javie tworzę klasę, ponieważ wszystko w Javie jest klasą. Następnie tworzę metodę main (). Jest to szczególny przypadek (a jest tu dużo takich szczególnych przypadków), jeżeli wystąpi główna metoda z taką sygnaturą:




public static void main (String[] args)

Wtedy w efekcie można uruchomić klasę. Żeby wykonać Hello World i zobaczyć wiadomość na przykład na ekranie swojego monitora, najpierw musiałbym skompilować klasę:

javac Hello.java

I potem uruchomić klasę:


java Hello



Uruchomi to „automagicznie” metodę main (). Więcej o konstruowaniu metod będzie jeszcze poniżej.

Każdy z Was, kto śledził moje wcześniejsze zapiski, musi być bardzo
świadomy mojego zdegustowania DBMS_OUTPUT.PUT_LINE. Wraz z pojawianiem się kolejnych, coraz bardziej krytycznych niedociągnięć, pragnę powiedzieć, że zawsze przerażało mnie wklepywanie 20 znaków tylko po to, żeby poprosić PL/SQL, żeby coś pokazał. Dobra wiadomość
– w Javie wystarczy wystukać tylko 18 znaków, to znaczy.:




System.out.println

Tak, to jest to, co ja nazywam postępem! Pod warunkiem, oczywiście, że nie zapomnisz wpisać
"S” dużą literą w słowie "System", inaczej bowiem pojawi się komunikat o błędzie:

Undefined variable, class or package

name: system


Inne różnice (takie jak użycie nawiasów, podwójnego cudzysłowu) pomiędzy PL/SQL i Javą wydają się widoczne w przytoczonym powyżej przykładzie skryptu.

Style Javy


Teraz, nim się zagłębię w następne porównania pomiędzy tymi dwoma językami, proszę pozwolić mi na wtrącenie mojej skromnej opinii w kwestii stylu. Muszę to przyznać
– jestem trochę zazdrosny o Javę i świat developerów Javy. Dzięki nim wszystko to wydaje się takie łatwe i wydają się oni odnosić same sukcesy w przekonywaniu innych do naśladowania tego wyraźnego zestawu standardów dla ich
ślicznie wyglądającego kodu. Zatem przedstawiam tutaj szybkie zestawienie podstaw stylu języka oraz analogie PL/SQL, jeżeli takowe oczywiście występują.

Na początek pisownia, a dokładnie rzecz biorąc użycie dużej i małej litery. Problem ten nie jest tak widoczny w PL/SQL z wyjątkiem wewnętrznego ciągu znaków i niektórych wbudowanych programów, takich jak DBMS_SESSION.SET_ROLE. W Javie natomiast jest on bardzo wyraźny. Wszystkie nazwy są tutaj wrażliwe na wielkość liter. Spójrzmy przykładowo na tę klasę:


public class hello {

   String msg = „Hello world”;

}

Jeżeli będzie to przechowywane w pliku nazwanym hello. java, wtedy poniższa próba skompilowania się nie powiedzie:




javac hello.java
 with this error: 
hello.java:1: Public class Hello must be defined in a file
called „Hello.java”.

Problem ten sprawi dużo kłopotu developerom przyzwyczajonym do PL/SQL. Osobiście muszę przyznać, że tego bardzo nie lubię. Nie lubię systemów operacyjnych, które są na to wrażliwe i nie lubię języków programowania, które przesyłają mi moje potknięcia
– literówki – jako błędy kompilacji z kodu, jak w poniższym przykładzie:


string myName = „Steven Feuerstein”;

if (Myname = „John”)

Dwa problemy w tym kodzie:

  • Zapomniałem napisać klasę String z dużej litery
  • Zadeklarowałem obiekt String nazwany myName, ale potem powołałem się na to jako Myname.

Poczuj się zatem ostrzeżony, drogi developerze PL/SQL – zwracaj uwagę, kiedy używasz słowa pisanego z dużej, a kiedy z małej litery. Jeżeli błędy kompilatora brzmią
"głupio", na przykład „Ale ja zadeklarowałem ten parametr”, ma to najprawdopodobniej coś wspólnego z drobnymi różnicami w wielkości liter.
Jeśli chodzi o tworzenie nazw elementów w Javie, to zasady są tutaj dość odmienne niż ma to miejsce w
środowisku PL/SQL. Cóż, prawdę mówiąc, chociaż większość developerów robi co chce w PL/SQL, to jednak wielu ludzi postępuje zgodnie z regułą:
Duża litera dla nazw wszystkich identyfikatorów, które są częścią języka PL/SQL – takie jak TO_CHAR i INTEGER oraz DBMS_OUTPUT.PUT_LINE, mała litera dla nazw wszystkich identyfikatorów specyficznych dla aplikacji.

W Javie znajdziecie te wszystkie podejścia zestandaryzowane (cytuję za e-mailem otrzymanym od Jonathana Knudsena, specjalisty od Javy i autora w
O’Reilly):

  • Nazwy klas powinny zaczynać się z dużej litery. Duże litery wewnątrz nazwy, która zaczyna nowe słowa
  • Raczej nie używać _ ani innych znaków specjalnych, żeby oddzielać słowa w nazwie. Używać zamiast tego dużej litery
  • Elementy parametrów, podobnie jak elementy funkcji, powinny zaczynać się z małej litery. Ja osobiście wolę (Jonathan) nadawać wszystkim elementom parametrów przedrostek 
    „m” małe
  • Metody „get and set” przy elementach (elementy danych) powinny mieć wyraźne przedrostki
    "get" i "set" przy swoich nazwach, dzięki czemu klasa może być używana jako Java Bean.

Oto przykład klasy, który zademonstruje działanie tych zasad:




class HomeAwayFromHome {

  String mcity;

  Date mdateVisited = new Date ();


  public void setCity (String city) {

   mcity = city;

  }

  public String getCity {

   return mcity;

  }

}

A oto pakiet PL/SQL, który pozwala osiągnąć w przybliżeniu ten sam efekt




CREATE OR REPLACE PACKAGE

home_away_from_home

IS

     PROCEDURE set_city (city_in

     IN VARCHAR2) IS

     FUNCTION city RETURN DATE;

END;

/

CREATE OR REPLACE PACKAGE BODY home_away_from_home

IS

    g_city VARCHAR2 (100);

    g_date_visited DATE := SYSDATE:




   PROCEDURE set_city (city_in

   IN VARCHAR2) IS

   BEGIN

   g_city := city_in;

   END;




   FUNCTION city RETURN DATE IS

  BEGIN

  RETURN g_city;

  END;

END;

/

Porównanie: deklaracje

W PL/SQL wykonasz wszystkie deklaracje w części deklaracyjnej swojego bloku, przy czym w każdej deklaracji można zdefiniować tylko pojedynczy parametr lub strukturę danych.

Java jest tutaj znacznie bardziej elastyczna. Możesz bowiem określić nowe obiekty i pierwotne typy danych w dowolnym miejscu kodu, a także zadeklarować wiele elementów w pojedynczej deklaracji.

Oto przykład deklaracji w PL/SQL i użycia dwóch zmiennych typu
INTEGER:



PROCEDURE two_ints

IS

   my_int INTEGER := 10;

   your_int INTEGER := 20;

   my_name VARCHAR2 (100);

BEGIN

   IF my_int > your_int

   THEN

       my_name := „BIG BOY”;


Tutaj to samo, otrzymane za pomocą Javy:


void twoInts () {

   int myInt = 10, yourInt = 20;

   if (myInt > yourInt)

      String myName = „BIG BOY”;

}

Jak możecie zauważyć, nie muszę nawet deklarować obiektu myName String, dopóki nie jest to potrzebne. Przyznaję, reguły deklaracji w Javie podobają mi się bardziej.

Sprawdźmy teraz niektóre podstawowe elementy języka od symboli komentarza po operatory. Jak niektórzy zapewne mają nadzieję, część z nich się pokrywa. Operatory arytmetyczne określające dodawanie (+), odejmowanie, mnożenie i dzielenie, podobnie jak standardowe operatory relacji (>, <, >=, <=) są takie same. Oto niektóre różnice:

OPIS

PL/SQL

Java

Pojedyncza linia komentarza //
Kilka linii komentarza /* */ /* */
Logiczny koniec zdania ; ;
Operator przypisania := =
Łańcuch tekstu "
Warunkowe AND AND &&
Warunkowe OR (dysjunkcja) OR ||
Powiązanie łańcuchowe + ||
Równy (identyczne wartości) = ==
Różny (różne wartości) != !=
Logiczny (boolean) OR (operator sumy bitów) OR |
Reszta z dzielenia MOD %
Nic nie rób NULL ;

 

Proszę zauważyć różne odwołania dla warunkowego i logicznego OR. Są one identyczne w PL/SQL, natomiast w Javie powinieneś używać operatora OR ||, jeżeli nie chcesz wyznaczać wartości prawego argumentu, gdy lewy argument ma wartość FALSE. Jest to zachowanie określone w PL/SQL. 

Java zawiera wiele innych operatorów, które nie mają swoich odpowiedników w PL/SQL:

OPIS SYMBOL PRZYKŁAD
arytmetyczna pre- lub postinkrementacja  ++ Po co pisać:
newSalary = newSalary + 1;
jak można krócej?
newSalary ++;
Przypuszczam, że niektórzy mogliby się tu kłócić o zwiększenie czytelności zapisu, ale myślę, że jak ktoś jest obeznany z Javą (lub ma doświadczenie z C), ++ i wszystkie inne skróty będą miały dla niego kapitalne znaczenie
arytmetyczna pre-lub postdekrementacja minBalance–;
Trójskładnikowe wyrażenie warunkowe (IF- ELSE) ?: Jest to uproszczone DECODE:
acctStatus =
(minBalance < 10000 ? „TOO LOW” : „JUST FINE");
Innymi słowy, jeżeli minimalna waga jest poniżej $ 10.000, $10,000, ustaw status konta na TOO LOW; inaczej ustaw na JUST FINE. Bardzo pożyteczny operator.
Operacje przypisania *=/=%= Równość:
newSalary = newSalary * 2;
oraz
newSalary *= 2;
Równość:
acctStatus = acctStatus + ” overdue";
oraz
newSalary += ” overdue;
Bitowe operacje >> 
<<
<<<
i wiele innych
Czy robisz dużo zmian na bitach?
Jeżeli tak, to Java jest językiem dla ciebie stworzonym!

Porównanie: Pętle

Java posiada oczywiście pełny komplet wyrażeń do logiki warunkowej, iteracji i wynikowej. Posiada nawet rodzaj wyrażenia CASE, nie posiada jednak wyrażenia GOTO!


Teraz rzućmy okiem na kilka przykładów.




Na początku logika warunkowa PL/SQL:




IF liking_Java AND liking PLSQL

THEN

   do_this;

ELSIF liking_Cobol

   do_that;

   do_that_with_two_digit_years;

END IF;



A teraz logika warunkowa w Javie:



if (liking_Java && liking_PLSQL)

   do_this;

else if (liking_Cobol) {

   do_that;

   do_that_with_two_digit_years;

}

Naprawdę nie występują zbyt duże różnice między tymi dwoma podejściami. Pamiętając, że Java jest wielkim przeciwnikiem gadulstwa, możesz zapomnieć o THEN i END IF. Ale
PL/SQL"owe ELSIF jest wyrazem mniejszej gadatliwości niż 
"else if" w
Javie, więc ocenić musisz sam...
Parę rzeczy, które warto zapamiętać:

  • Musisz zawsze otaczać wyrażenie logiczne klauzulą IF lub ELSE IF nawiasami. Jest to opcjonalne w PL/SQL, ale wymagane w Javie.
  • Jeżeli kod, który chcesz wykonać, zawierający klauzulę IF lub ELSE IF, zawiera więcej niż jedno wyrażenie logiczne (kod zakończony
    średnikiem), musisz zamknąć ten kod pomiędzy nawiasy{}

Teraz zobaczmy, jak wygląda pętla w PL/SQL:

FOR indx IN 1..10

LOOP

  abc;

END LOOP;

A teraz pętla w Javie:

for (int indx = 1; indx <= 10; i++) {

   abc;

}

Pętla w PL/SQL posiada pewne słowa kluczowe (LOOP oraz END
LOOP) definiujące punkt początkowy i końcowy ciała pętli. Java polega na wszechobecnych (ale bardzo konsekwentnych) nawiasach, do zaznaczenia początku i końca ciała pętli.

Jeśli chodzi o pętlę, to trzeba przyznać, że w Javie jest ona znacznie bardziej wyrazista i elastyczna niż w PL/SQL. Obojętnie kiedy definiujesz pętlę, dochodzisz do momentu specyfikacji indeksu z wartością początkową, wyrażenia logicznego, które spowoduje zakończenie pętli oraz kroku, który jest wykonywany przy każdym wywołaniu pętli.

A do tego iteracja nie musi być liczbą całkowitą! Pamiętajmy, że jest to język zorientowany obiektowo, można więc robić pętle między obiektami, co pokazuję poniżej na przykładzie obiektu typu String:


public class temp {

     public static void main (String[] args) {

             
for (String s = args[0]; s.length () < 40; s += "AreOverpaid")

              
{

               
System.out.println (s);

              
}

     }

}

Po uruchomieniu tej klasy zobaczę następujący wynik:



D:Java>java temp CEOs

CEOs

CEOsAreOverpaid

CEOsAreOverpaidAreOverpaid

CEOsAreOverpaidAreOverpaidAreOverpaid

Jeżeli piszesz więc podstawowe liczby całkowite dla pętli, Java będzie wymagać nieco więcej kodu niż PL/SQL. Jeżeli chcesz natomiast zrobić coś bardziej pomysłowo, Java jest przystosowana do tego znacznie lepiej niż PL/SQL.

PL/SQL oferuje specjalną wersję pętli, która automatycznie dokonuje iteracji poprzez każdy identyfikator rekordu, za pomocą instrukcji cursor. Oto przykład:




DECLARE

        CURSOR emp_names IS

               
SELECT ename FROM emp;

BEGIN

        FOR name_rec IN emp_names

        LOOP

                 
DBMS_OUTPUT.PUT_LINE (name_rec.ename);

        END LOOP;

END;

Standardowo Java nie daje możliwości cursor dla pętli. Jak już wspomniałem wyżej, standard dla pętli może być używany z każdym typem obiektu. Dodatkowo można użyć pętli while, aby uzyskać bardzo zbliżony efekt do tego pokazanego w poniższym przykładzie, wziętym z Employee.java, dostarczonego przez Oracle, jako ilustracja kodowania JDBC.


// Example from Oracle jdbc directory

class Employee

{

     public static void main (String args [])

     throws SQLException,

     ClassNotFoundException

     {

             // Load the Oracle JDBC driver

            Class.forName ("oracle.jdbc.driver.OracleDriver");

            DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver ());



           // Connect to the database

          Connection conn = DriverManager.getConnection ("jdbc:oracle:oci8:@beq-local",
'scott', 'tiger');



          // Create a Statement

          Statement stmt = conn.createStatement ();



          // Select the ENAME column from the EMP // table

         ResultSet rset = stmt.executeQuery ("select ENAME from EMP");


          // Iterate through the result and print the

          // employee names

             while (rset.next ())

           System.out.println (rset.getString (1));

     }


}

Niewątpliwie przykład Employee.java zawiera znacznie więcej kodu niż cursor w pętli PL/SQL. Spora część tego nie byłaby potrzebna przy tworzeniu zapamiętanych procedur Javy dla wykonania przez serwer Oracle8i
- połączenie zostałoby wykonane automatycznie. Główną część kodu stanowi pętla while:




while (rset.next ())
System.out.println (rset.getString (1));




A to jest już oczywiście wystarczająco zwięźle!

Java i CASE


W rzeczywistości nazywane jest ono wyrażeniem "przełącznikiem" (switch) - instrukcją wyboru i może być używane tylko z
"pierwotnymi integralnymi typami", na przykład całkowitymi. Innymi słowy nie można go używać w połączeniu z obiektem, np. typu String. Składnia instrukcji
wyboru wygląda następująco:




switch (myint % 2) {

         case 0:// No remainder; myint is an even //number

                  
System.out.println ("Even");

                  
break;

         case 1:// Remainder of 1; myint is odd

                  
System.out.println ("Odd");

                  
break;

        default:// Gee, what else is there?

                  
System.out.println ("VERY odd");

                  
break;

}

W PL/SQL buduje się procedury i funkcje, można je potem grupować w pakiety. W Javie buduje się klasy, a wewnątrz nich definiuje się metody. Można następnie grupować wielowątkowe klasy w pakiety (zobacz następną część poświęconą porównaniu konstruowania pakietów w Javie i PL/SQL).

Jest wiele podobieństw i wiele różnic pomiędzy konstrukcją programu (metody) w PL/SQL i Javie. Przedstawiam porównanie na najwyższym poziomie: 

Czynność PL/SQL Java
Utwórz procedurę lub funkcję Tak Tak
Odosobnienie procedury lub funkcji Tak Nie; metoda jest zawsze zdefiniowana wewnątrz klasy
Rodzaje/tryby parametrów IN, OUT,IN OUT Brak rodzajów/trybów
Dziedziczenie parametrów Określonym zachowaniem jest utworzenie lokalnych kopii (pass by
value), ale może zostać zlekceważone dzięki opcji NOCOPY w Oracle8i.
Zawsze dają obiektowi punkt zaczepienia; kopie obiektów nie są tworzone wewnątrz programów
Domyślne wartości dla parametrów Tak Nie

Funkcja jest programem, który wykonuje serię instrukcji i następnie zwraca wartość. Funkcja, w konsekwencji, ma typ danych z nią powiązanych. W PL/SQL ten typ danych pojawia się w klauzuli RETURN nagłówka:

FUNCTION total_sales (company_id_in IN INTEGER) RETURN NUMBER;

W Javie typ danych zostaje ustalony natychmiast po uwidocznieniu lub sprecyzowaniu dostępu (publiczny, prywatny, chroniony i zaprzyjaźniony). Klauzula RETURN nie występuje dla funkcji Javy, co widać poniżej:




public long TotalSales (int company_id)

Procedura jest programem, który wykonuje serie instrukcji. Oto nagłówek dla publicznie dostępnej (publicly-available) procedury zdefiniowanej w pakiecie:




PACKAGE emp_pkg

IS

   PROCEDURE give_raise (emp_id IN emp.empno%TYPE, raise_in IN NUMBER);

END;

A to jest definicja metody publicznie dostępnej procedury w klasie emp:

public class emp {

   public void GiveRaise (int emp_id, long raise) {

  ... implementation ...

   }

}

Jak można zauważyć, nagłówek procedury różni się od nagłówka funkcji tylko specyfikacją typu danych metody; typ w przypadku procedury jest określany jako void, jeżeli nie zwraca ona wartości. W PL/SQL można zdefiniować
"anonimowe" bloki, zarówno jako odrębne skrypty do wykonania lub jako zagnieżdżone bloki w celach zadeklarowania dodatkowych struktur danych lub zawężenia zakresu obsługiwania wyjątków.

W Javie metoda main () służy przede wszystkim jako odrębny anonimowy blok. To ty
"wykonujesz" klasę, a to uruchamia metodę main (). Ta metoda jest głównie używana do przeprowadzania testów innych metod i funkcyjności w obrębie klasy.

A teraz spójrzmy na zagnieżdżone bloki. W PL/SQL można wstawić instrukcje BEGIN-END wokół jakiegokolwiek zestawu wykonywalnych instrukcji, żeby utworzyć tym samym nowy blok. W poniższym przykładzie wykorzystuję zagnieżdżony blok, żeby wyłapać błąd
"open for append" w UTL_FILE (jeżeli ten plik nie istnieje, UTL_FILE zgłasza błąd przy dołączaniu (Append), co wydaje się dość niemądre):




BEGIN

 DECLARE

   fid UTL_FILE.FILE_TYPE;

 BEGIN

   fid := UTL_FILE.FOPEN ('/tmp', 'notmuch.txt', 'A');

 EXCEPTION

   WHEN OTHERS

  THEN

  fid := UTL_FILE.FOPEN ('/tmp', 'notmuch.txt', 'W');

END;

W świecie Javy, aby zdefiniować zagnieżdżony zakres, potrzebujesz tylko pary nawiasów. Nie mam zamiaru poruszać tych samych zagadnień, co do tego samego otwartego pliku, w Javie, co w PL/SQL, ale możecie sobie wyobrazić taką samą możliwość zwężania zakresu błędu na następującym przykładzie:




try {

     FileInputStream in = new FileInputStream ("/tmp/notmuch.txt");

     fileLength = in.available ();

}

catch (IOException e) {

     return -1;

}

Składnia wywoływania programów Javy jest prawie taka sama jak w PL/SQL. Powinieneś zapamiętać poniższe restrykcje:


  • Musisz wprowadzić wartość dla każdego parametru - nie ma wartości domyślnych.

  • Możesz używać tylko zapisu pozycyjnego do dziedziczonych argumentów - notacja zdefiniowana (składnia => w PL/SQL) nie jest możliwy w Javie

  • Jeżeli wywołujesz metodę, która nie ma żadnych parametrów, musisz wpisać parę pustych nawiasów, jak pokazano poniżej:


class PuterLingo {

   private String mname;

   public PuterLingo (String name) { mname = name; }

      public String name () { return mname; }

   }

class LotsALingos {

   public static void main (String args[]) {

   PuterLingo Java = new PuterLingo ('Java');

   System.out.println (Java.name ());

   }

}


Proszę zauważyć, że przy wywoływaniu metody Java.name dodałem ()

Wbudowana funkcjonalność


Dla takiego biednego, staromodnego proceduralnego developera jak ja, nie wystarczy poprawić swoją znajomość orientacji obiektowej, metod, interfejsów, abstrakcyjnych klas i im podobnych. Nawet kiedy to wszystko przetrawię, ciągle muszę myśleć i obliczać, jak używać tych wszystkich klas, które niesie ze sobą
Java.

Aby pokazać choć odrobinę tego przeraźliwego ćwiczenia -
Java 1.1 klasy podstawowe (są to te klasy, po które każdy developer Javy chętnie sięga każdego dnia)
- wyłączając GUI lub zestaw narzędzi dla okienek, takich jak klasy AWT - zorganizowane w serie pakietów (jak wcześniej zauważyłem różnych od pakietów PL/SQL). Oto lista takich pakietów i przypisany im numer klasy:

Pakiet Klasy
java.io 70+
java.lang 65+
java.net 26
java.text 19
java.util 26
java.util.zip 17
Daleko od wszystkich możliwości… 255 klas!

O mój Boże, muszę wam powiedzieć - przeczytałem całe mnóstwo książek opublikowanych na temat Javy i zastanawiam się jak to możliwe, że te zwyczajne
śmiertelne istoty ludzkie mogły przyswoić taki ogrom technologii w tak krótkim czasie. I wtedy przypominam sobie, że niektóre z nich pracują z Javą przez ponad 5 lat.
Wielu z nich pewnie nawet nie wie tego wszystkiego, po prostu wstawiają przeredagowane fragmenty podstawowej dokumentacji do swoich książek.
Tak, teraz czuję się znacznie lepiej.
Ciągle jednak wzdrygam się, kiedy spoglądam na przeróżne klasy w java. io... Szybko! Proszę mi wyjaśnić różnicę między klasami BufferedInputStream, InputStream, FilterInputStream i InputStreamReader.

Zapisałem to w moim dzienniku PL/SQL (www.revealnet.com/plsql-pipeline): 26.12.98. Szósta po południu
- wiem, że powinienem wszystko robić krok po kroku, a tymczasem ciągle skaczę po różnych książkach o Javie, a potem czuję się tym wszystkim przygnieciony i zastraszony. Java jest skomplikowanym językiem, na tyle, na ile ją znam oczywiście. A teraz pozwolę sobie przedstawić, o co mi dokładnie chodzi. Poniższy fragment jest wzięty z książki
Gosling'a i Arnold'a The Java Programming Language, strony 231-232. Przypominam, że Gosling jest twórcą języka Java:
"Standardowe potoki System.in, System.out oraz System.err istniały przed wymyśleniem potoków charakterystycznych, zatem te potoki są potokami bajtów, mimo że logicznie powinny być potokami charakterystycznymi. Ta sytuacja stwarza pewne anomalie. Jest możliwe na przykład, że System.in zostanie zastąpiony
LineNumberReader, żeby utrzymać odpowiedni numer aktualnej ścieżki standardowych potoków wejściowych. Używając InputStreamReader
- obiektu, który konwertuje potok wejściowy bajtów na charakterystyczny potok wejściowy
- gdy zostanie dołączony do System.in, można utworzyć obiekt LineNumberReader do zachowania numeru aktualnej
ścieżki. Ale System.in jest Input Stream, więc nie można go zastąpić LineNumberReader, który jest typem Reader, a nie Input Stream."

Może to tylko problem ze mną, ale chyba rzeczywiście brzmi to dość skomplikowanie. Czy byłoby możliwe napisanie czegoś takiego o PL/SQL? Pewnie, ale PL/SQL ma tu mniej możliwości (z wyjątkiem, gdy chodzi o dostęp do baz danych)
- i tu możecie zauważyć oczywisty, wynikający z tego kompromis.

Koniec dziennika.


Uczę developerów PL/SQL o różnych wbudowanych pakietach, których w sumie jest może około 50. W ciągu jednego dnia mogę zrobić
- szczerze - może 5 pakietów PL/SQL z Oracle. Ale nie mam zamiaru panikować. Nie mam zamiaru wierzyć, że muszę się nauczyć tej całej nowej technologii w ciągu przyszłego tygodnia. Mam czas. Wszyscy mamy czas. Ale też wszyscy powinniśmy zacząć.

Steven Feuerstein jest znakomitym autorem książek o programowaniu w PL/SQL dla "Oreilly and Associates". Jest także prezesem technologicznym (Chief Technology Officer) w firmie RevealNet, Inc. RevealNet i Oreilly and Associates ogłosiły w pierwszym kwartale 2000 roku wspólną
Oracle/Java Bazę Wiedzy. W celu uzyskania dalszych informacji odwiedź
stronę www.revealnet.com.
Ten artykuł ukazał się po raz pierwszy w wydaniu Oracle Scene Summer 2000, opublikowany przez UK Oracle User Group (www.ukoug.org).
Przedrukowany za zgodą.