Miesięczne archiwum: Grudzień 2011

Pierwsze urodziny Java Blog

Dokładnie rok temu na łamach naszego bloga pojawiła się notka powitalna. Od tego czasu dodaliśmy 80 wpisów, przygotowaliśmy 6 filmów (do obejrzenia na naszym kanale), zdaliśmy relacje z Confitury oraz TechCamp’a i uruchomiliśmy jeden z niewielu darmowych kursów przygotowujących do certyfikatu Oracle Certified Professional Java Programmer.

Szczerze wierzymy, że kolejny rok będzie jeszcze lepszy i uda nam się zrealizować wszystkie założone cele. Pracujemy nad kolejnymi artykułami i prezentacjami wideo. Będziemy na największych konferencjach w Polsce (np. na zbliżającym się 33rd Degree – Conference for Java Masters) oraz uruchomimy kolejny kurs. Zrobimy także coś o czym od zawsze marzyliśmy – już na przełomie lutego oraz marca ruszą w Krakowie barcampowe spotkania dla programistów pod patronatem najlepszych krakowskich firm oraz naszego bloga. Możemy zapewnić, że będziemy się starać stworzyć niepowtarzalną atmosferę i umożliwić swobodną wymianę wiedzy pomiędzy uczestnikami. Więcej informacji pojawi się już w najbliższych dniach.

Naszym celem jest także integracja społeczności programistów. Zachęcamy do polubienia naszego profilu na Facebooku lub Google+. Wśród osób, które polubią nasz profil na pierwszym barcampowym spotkaniu wylosujemy ciekawy gadżet :)

Jako, że domena .eu zobowiązuje, postaramy się również publikować nasze wpisy w dwóch wersjach językowych.

Dziękujemy naszym wszystkim Czytelnikom i zachęcamy do częstego śledzenia naszej strony. Będzie się działo!

Zdaj OCPJP – pytanie 28

Jaki będzie efekt uruchomienia poniższego programu:

public class SimpleTest {
    public static void main(String[] args) {
        List<Integer> list1 = new ArrayList<Integer>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        
        List<Number> list2 = new ArrayList<Number>();
        list2.add(1);
        list2.add(2);
        list2.add(3);
        
        SimpleTest test = new SimpleTest();
        test.add(list1);
        test.add(list2);    
    }
    
    public void add(List<Integer> listOfNumbers) {
        System.out.println("List<Integer>");
    }
    
    public void add(List<Number> listOfNumbers) {
        System.out.println("List<Number>");
    }
}

 

  1. Dwukrotnie wydrukowane zostanie List<Integer>.
  2. Dwukrotnie wydrukowane zostanie List<Number>.
  3. Wydrukowane zostanie List<Integer> List<Number>.
  4. Zostanie rzucony wyjątek w linii 8.
  5. Kod nie skompiluje się.

 

Pokaż odpowiedź »

Poprawna odpowiedź: 5.
Kod nie skompiluje się ponieważ obie metody add mają identyczną deklarację: public void add(List listOfNumbers). Kompilator nie jest w stanie stwierdzić, którą metodę należy wykorzystać. Pamiętajmy, że typy ogólne wykorzystywane są jedynie na etapie kompilacji w celu sprawdzenia zgodności typów obiektów. Ich obecność w metodach w żaden sposób nie zmienia ich bazowych deklaracji.

Zdaj OCPJP – pytanie 27

Poniższy kod zostaje skompilowany i uruchomiony. Jaki jest tego efekt, przy założeniu, że nie wystąpią żadne problemy z zapisem i odczytem pliku, a wszystkie potrzebne importy są obecne?

class A
{
    public A()
    {
        System.out.println("A");
    }
}

class B extends A implements Serializable
{
    public B()
    {
        System.out.println("B");
    }
}

public class Sample
{
    public static void main(String[] args) throws Exception
    {
        File f = new File("D:/object.ser");
        FileOutputStream fout = new FileOutputStream(f);
        ObjectOutputStream out = new ObjectOutputStream(fout);

        B b = new B();
        out.writeObject(b);
        out.close();

        FileInputStream fin = new FileInputStream(f);
        ObjectInputStream in = new ObjectInputStream(fin);

        in.readObject();
        in.close();
    }
}

 

  1. Wydrukowane zostanie odpowiednio A B A B.
  2. Wydrukowane zostanie odpowiednio A B.
  3. Wydrukowane zostanie odpowiednio A B A.
  4. Wydrukowane zostanie odpowiednio A B B.
  5. Kod nie skompiluje się.
  6. W trakcie działania aplikacji rzucony zostanie wyjątek.

 

Pokaż odpowiedź »

Poprawną jest odpowiedź nr 3.

Należy pamiętać o tym, że jeśli którakolwiek z nadklas typu deserializowanego obiektu nie implementuje interfejsu Serializable, konstruktor tej klasy, jak i wszystkich znajdujących się powyżej, zostanie wywołany. W powyższym przykładzie klasa A nie implementuje wspomnianego interfejsu, więc jej konstruktor będzie wykonany w procesie deserializacji.

Zdaj OCPJP – pytanie 26

Co zostanie wyświetlone na ekran po uruchomieniu poniższego kodu?

public class SplitTest {
    
    public static void main(String[] args) {
        String test = ";;;;;";
        String[] afterSplitting = test.split(";");
        for(int i = 0; i < afterSplitting.length; i++)
            System.out.print(afterSplitting[i] + " ");
    }
}

 

  1. Zostaną wyświetlone 4 spacje.
  2. Zostanie wyświetlonych 5 spacji.
  3. Nic nie zostanie wyświetlone.
  4. Program nie zakończy swojego działania.

 

Pokaż odpowiedź »

Poprawna jest odpowiedź 3.
Nawiązując do dokumentacji klasy String, metoda split() nie umieszcza w tablicy wynikowej pustych łańcuchów tekstowych jeżeli są one jej ostatnimi elementami. W przypadku przykładowego kodu wszystkie wartości będące wynikiem operacji rozdzielania są pustymi łańcuchami więc żaden z nich nie zostanie umieszczony w tablicy wynikowej. Jeżeli kod wyglądałby następująco:

public class SplitTest {
    
    public static void main(String[] args) {
        String test = ";;;;;1";
        String[] afterSplit = test.split(";");
        for(int i = 0; i < afterSplit.length; i++)
            System.out.print(afterSplit[i] + " ");
    }
}

to na ekranie pojawiłoby się 5 spacji oraz cyfra 1.

TechCamp – relacja wideo

Na stronie TechCampu znalazły się filmy z pierwszego spotkania poświęconego Cloud Computingowi. Zapraszamy również do zapoznania się z naszą relacją. Jeżeli ominął Cię pierwszy TechCamp to już 19 stycznia odbędzie się kolejne spotkanie. Tym razem pod lupę ekspertów trafią użyteczne interfejsy graficzne. Przypominamy, że Organizatorem cyklu wydarzeń Techcamp jest Akademia Empathy.

Zdaj OCPJP – pytanie 25

Jaki będzie efekt skompilowania i uruchomienia poniższego kodu?


public class Sample
{
    public static long main(String[] args)
    {
        System.out.println("IN MAIN");
        return 2L;
    }
}

 

  1. Kod nie skompiluje się.
  2. Wydrukowane zostanie IN MAIN.
  3. Nic nie zostanie wydrukowane.
  4. Rzucony zostanie obiekt typu Throwable.

 

Pokaż odpowiedź »

Poprawna jest odpowiedź 4.

Maszyna wirtualna będzie usiłowała zlokalizować publiczną, statyczną metodę main, która przyjmuje tablicę obiektów typu String, i nic nie zwraca. W powyższym przykładzie zwracany typ to long – dlatego też przy próbie uruchomienia programu wystąpi NoSuchMethodError.

Zdaj OCPJP – pytanie 24

Co należy wstawić w oznaczone miejsce poniższego kodu, aby po skompilowaniu i uruchomieniu go wydrukowane zostały litery bcde?

public class Sample
{
    public static void main(String[] args)
    {
        String string = "12abcdefgh";
        // tutaj wstaw kod

        System.out.println(substring);
    }
}

 

  1. String substring = string.substring(4, 7);
  2. String substring = string.substring(3, 6);
  3. String substring = string.substring(4, 6);
  4. String substring = string.substring(3, 7);

 

Pokaż odpowiedź »

Poprawna jest ostatnia odpowiedź – nr 4.

Metoda substring klasy String jest o tyle podchwytliwa, że znak o indeksie przekazanym w pierwszym jej argumencie znajdzie się w wynikowym łańcuchu, natomiast znak o indeksie podanym jako końcowy już nie. Warto o tym pamiętać, gdyż pytania o to zagadnienie są dość częste.

Zdaj OCPJP – pytanie 23

Jaki będzie efekt uruchomienia poniższego kodu?

public class GenericTest {
    
    public static void main(String[] args) {
        GenericClass<Integer> obj1 = new GenericClass<Integer>(12);
        GenericClass<String> obj2 = new GenericClass<String>("null");
        GenericClass.checkType(obj1.getTest());
        GenericClass.checkType(obj2.getTest());        
    }
}

class GenericClass<T> {
    private T test;
    
    public GenericClass(T test) {
        this.test = test;
    }
    
    public static void checkType(T object) {
        if(object instanceof Integer)
            System.out.println("Integer");
        else if(object instanceof String)
            System.out.println("String");
    }

    public T getTest() {
        return test;
    }

    public void setTest(T test) {
        this.test = test;
    }
}

 

  1. Zostanie wyświetlone: Integer String
  2. Zostanie wyświetlone: String
  3. Zostanie wyświetlone: Integer null
  4. RuntimeException w linii 4
  5. RuntimeException w linii 5
  6. Błąd kompilacji

 

Pokaż odpowiedź »

Poprawna odpowiedź: 6
Nie możemy wykorzystywać typów generycznych klasy w definicji statycznych metod i pól, które są współdzielone przez wszystkie obiekty danej klasy. Typy ogólne klasy odnoszą się natomiast do konkretnej instancji. Możemy jednak skorzystać z następującej konstrukcji:

class GenericClass<T> {
    private T test;
    
    public GenericClass(T test) {
        this.test = test;
    }
    
    public static <K extends GenericClass> void checkType(K object) {
        if(object.getTest() instanceof Integer)
            System.out.println("Integer");
        else if(object.getTest() instanceof String)
            System.out.println("String");
    }

    public T getTest() {
        return test;
    }

    public void setTest(T test) {
        this.test = test;
    }
}

Ant vs Maven

Zdrowa konkurencja pomiędzy rozwiązaniami dedykowanymi do podobnych zadań jest czymś zupełnie normalnym i pożądanym. Nieprzerwane spory o wyższości jednego frameworku webowego nad innymi, EJB kontra Spring czy też poszukiwanie idealnego serwera aplikacyjnego są spotykane w Javovym ekosystemie. Na blogu Dublin’s Tech Blog pojawił się ciekawy filmik porównujący Ant z Maven. Wyróżnia się on ciekawą formą i nie wskazuje zwycięzcy.

Osobiście uważam, że wybór odpowiedniego narzędzia zależy od osobistych preferencji i charakterystyki konkretnego projektu. Niemniej jednak temat jest ciekawy i wart poruszenia.

Zdaj OCPJP – pytanie 22

Jaki będzie efekt skompilowania i uruchomienia poniższego kodu?

public class Sample
{
    private static int a = 0;

    public static int getFirst()
    {
        throw new IllegalStateException();
    }

    public static int getSecond()
    {
        return ++a;
    }

    public static void main(String[] args)
    {
        String array[][] = {{"a", "b"}, {"c", "d"}};

        try
        {
            System.out.println(array[getFirst()][getSecond()]);
        }
        catch(Exception e)
        {
            System.out.println(a);
        }
    }
}

 

  1. Wydrukowana zostanie liczba 1.
  2. Wydrukowana zostanie litera a.
  3. Program nie skompiluje się.
  4. Wydrukowana zostanie liczba 0.
  5. Wydrukowana zostanie litera b.

 

Pokaż odpowiedź »

Prawidłowa jest odpowiedź numer 4.

Przy tym pytaniu należy pamiętać o jednej rzeczy: jeśli obliczanie wyrażenia stanowiącego jeden z wymiarów tablicy zostanie przerwane przez rzucenie wyjątku, żaden z wymiarów na prawo od niego nie zostanie wyliczony. Dlatego też wartość zmiennej a nie zwiększa się, a powyższy program drukuje liczbę 0.