Home - rlip/java GitHub Wiki

Skróty


ctrl + alt + l - formatowanie

Zmiana na raz:
alt + shift + mouseclick lub ctrl + ctrl + up/down lub przytrzymanie środkowego klawisza myszy 
ctrl + alt + shift + j - zaznaczenie i edycja wszystkich wystąpień w aktualnym pliku

ctrl strzałka - przeskakiwanie całego wyrazu
alt + f1 - select in
ctrl + shit + z - powtórz
ctrl + shift + j - join - jedna linia
2x shift i builder w actions
ctrl + y - delete line
ctrl + f12 - struktura pliku

/////// Przeszukiwanie
ctrl + f - włączenie
enter (lub f3) - następne znalezione
shift + f3 - poprzednie znalezione

/////// Przejścia
ctrl + b (albo f4) - przejście do deklaracji klasy/interfejsu
ctrl - alt + b - przejście do implementacji klasy / interfejsu

/////// Błędy
F2 - następny błąd
ctrl + f1 - dokumentacja błędu
alt + enter - poprawa błędu

/////// Wydzielanie
ctrl + o - wybór metody klas wyższych do nadpisania
ctrl + alt + v - wydzielenie do zmiennej
ctrl + alt + m - wydzielenie do metody
ctrl + alt + c - wydzielenie stałej
ctrl + alf + f - wydzielenie do zmiennej
ctrl + alt + p - zmienna jako parametr

/////// Zmienianie
shift + f6 zmienia wszędzie w kodzie!
/////// Auto uzupełnianie
ctrl + shift + enter - dopełnia nawiasy np. w for czy if, też po wpisaniu warunku przenosi do wpisywania treści
ctrl + alt + t - dodawanie try/catch, if, etc...

/////// Podpowiedzi:
ctrl + space - wyświetlanie podpowiedzi, można też zmienić stałą - wybranie przez tab podmienia tekst, a nie dopisuje
ctrl + shift + space - wyświetlanie podpowiedzi - tylko odpowiednie dla danego kontekstu
2x (ctrl + shift + space) - podpowiedź przy return
ctrl + p - sygnatura metody
ctrl + q - dokumentacja metody
ctrl + shift + i - definicja w popup

/////// Zaznaczanie:
alt + j - zaznacza te same symbole
alt + shift + j - odznacza te same symbole
ctrl + alt + shift + j - zaznacza te same symbole w całym pliku
ctrl + shift + f7 - podświetla wszystkie użycia w aktualnym pliku
ctrl + w - zaznaczenie bloku - zwiększanie
shift + ctrl + w - zaznaczenie bloku - zmniejszenie

/////// Zwijanie:
ctrl + NumPad -/+ - zwiniecie/rozwinięcie aktualnego bloku
ctrl + shift + NumPad -/+  - zwiniecie/rozwinięcie wszystkich bloków

/////// Przenoszenie:
alt + shift + góra/dół - przenoszenie 1 linii
ctrl + shift + góra/dół - przenoszenie metody

Komendy

ustawienie wersji: mvn versions:set -DnewVersion=x.y+1.0-SNAPSHOT

C:\apache-maven-3.6.0-bin\apache-maven-3.6.0\bin\mvn package spring-boot:repackage

-Djava.net.preferIPv4Stack=true

Biblioteki

### Lombok
@Accessors(chain=true) // chain - setery zwracają this || fluent - getery i setery bez get i set || prefix  - usuwa prefix 
https://projectlombok.org/features/experimental/Accessors


Guava - duuużo rzeczy
Apache commons

Logowanie

Tak można zmienic path i poziom logowania

logging:
   path: /var/logs/
   file: TacoCloud.log
   level:
     root: WARN
     org:
       springframework:
         security: DEBUG

Cache

https://www.baeldung.com/spring-cache-tutorial, trzeba wączyc potem

@Cacheable({"addresses", "directory"}) - jak jest coś w cachu to bierze z cacha, jak nie to dodaje

@CacheEvict(value="addresses", allEntries=true) - usuwa z cachu

@CachePut(value="addresses") - zawsze dodaje i uaktualnia
------------

@Caching(evict = { 
  @CacheEvict("addresses"), 
  @CacheEvict(value="directory", key="#customer.name") })

------------

With the @CacheConfig annotation, you can streamline some of the cache configuration into a single placeat the class levelso that you don't have to declare things multiple times:

@CacheConfig(cacheNames={"addresses"})
public class CustomerDataService {
 
    @Cacheable
    public String getAddress(Customer customer) {...}

można jeszcze użyć warunków: condition, unless

Kolekcje

  • Listy:
ArrayList<String>(); // tylko jeśli będziemy co najwyżej usuwać elementy z końca
LinkedList<String>();
  • Sety - nie mogą mieć duplikatów
HashSet - szybki, ale bez kolejności
LinkedHashSet - zapamiętuje kolejność
TreeSet - w kolejności naturalnej  (interfejs Comparable)
  • Mapy - mapa 2 parametrów
HashMap- bez gwarancji kolejności
WeakHashMap - j.w. - z tym, że jak obiektowi dodanemu do mapy ustawimy wartość null to grabage collector może go usunąć 
LinkedHashMap - zapamiętuje kolejność
TreeMap - kolejność naturalna

Wątki

Callable, albo Runnable.

Executors.newFixedThreadPool() // ExecutorService mające 2 wątki
Executors.newScheduledThreadPool(2) // ScheduledExecutorService mające 2 wątki
executorService.schedule(worker1, 5, TimeUnit.SECONDS); //odpali się po 5 sekundach
executorService.scheduleAtFixedRate(worker3, 0, 6, TimeUnit.SECONDS); // będzie odpalał się co 6 sekund

executorService.submit(worker1);
executorService.shutdown();

 Callable<Integer> answerToEverything = () -> { // może coś zwrócić
 Future<Integer> result = executorService.submit(answerToEverything); // tak możemy przejąc to co zwraca -- taki javascriptowy promise
 result.isDone() // czy już jest wynik
 Integer integer = result.get(); // to zablokuje aplikację do momentu aż future będzie miało wartość
 result.get(4, TimeUnit.SECONDS) // poczeka 4 sekundy, jak nie będzie wyniku to timeoutException
 
List<Future<Integer>> futures = executorService.invokeAll(callableList); // czeka na wszystkie wyniki i je zwraca
Integer integer = executorService.invokeAny(callableList); // zwraca 1 wynik uzyskany wynik

cfuture1.thenCombine(cfuture2, new BiFunction<Long, Long, Object>() { // przyjmuje 2 cfuture, wywołuje je i zwraca wynik
synchronized public void increase() // dostęp do tej funkcji ma tylko 1 wątek na raz, można też tak jako blok w jakieś fukcji synchronized { ...
i można też użyć zmiennych atomic

volatile - nie zapewnia wzajemnego wykluczenia, ale gwarantuje, że każdy wątek odczytujący to pole będzie "widział" ostatnio zapisaną wartość


Metody, zawierające zmienne dostępne do wielu wątków trzeba albo synchronizować (zapis i odczyt):

public class StopThread {
    private sytatic boolean stopRequested;
    private static synchroznized void requestStop() {
        stopRequest = true;
    }
    private static synchronized boolean stopRequested(){
        return stopRequested;
    }
}
/////////////// tak można używać java.util.concurre.atomic

private static final AtomicLong nextSerialNum = new AtomicLong();
public static long generateSerialNumber() {
     return nextSerialNum.getAndInclement();
}

Moduły

Tworzymy pliki module-info.java w katalogu java. To co nie wyexportujemy jest prywatne. Eksport głównego pakietu nie eksportuje podrzędnych pakietów, ale Eksport podrzednych eksportuje też główny pakiet. (Może też trzeba dać nadrzędny) Można też dać require lombok, czy sprigframework

Może będzie potrzebny Maven 2 integration plugin. Przy migracji można użyć programu z bin - jdebs, który wypisze zależne moduły W każdym module w src trzeba utworzyć module-info.java:

module pl.clockworkjava.MainModule {
    requires java.logging;  // co używany
    requires pl.clockworkjava.AccountingModule; // jakieś inne nasze moduły
    requires pl.clockworkjava.SupplyModule;
} 

module pl.clockworkjava.AccountingModule {
    requires java.logging;
    exports pl.clockworkjava.accounting; // to trzeba napisać, żeby wystawić na zewnątrz publiczne metody klas, osobno dla każdej package
    // zawsze trzeba dodawać pełną paczkę (nie wystarczy rodzic)
}

Jeśli używamy serwisu z innego modułu

module pl.clockworkjava.AccountingModule {
    requires pl.clockworkjava.PayrollService; // tu jest sam interfejs serwisu
    requires pl.clockworkjava.PolishPayroll; // tu jedna z implementacji
    exports pl.clockworkjava.accounting; // to że jest paczka accounting tego modułu jest widoczna na zewnątrz accounting

    uses pl.clockworkjava.payroll.PayrollService; // to że używa tego serwisu
}

Potem tak w kodzie mozna dostać się do niego dostać:
         ServiceLoader<PayrollService> services = ServiceLoader.load(PayrollService.class);
         services.findFirst().ifPresent(PayrollService::getCurrency);

// a to implementacja takiego serwisu:
module pl.clockworkjava.PolishPayroll {
    requires pl.clockworkjava.PayrollService;
    provides pl.clockworkjava.payroll.PayrollService with pl.clockworkjava.polishpayroll.PayrollServiceImpl;
    //ten moduł dostarcza implementacji do tego serwisu
}

Można tez lepiej, czyli w interfejsie serwisu dodajemy statyczną metodę

    static PayrollService getInstance(){
        ServiceLoader<PayrollService> services = ServiceLoader.load(PayrollService.class);
        Optional<PayrollService> first = services.findFirst();
        return first.orElseThrow(() -> new RuntimeException("Missing PayrollService implementation"));
    }
    I w module-info oznaczamy że sam siebie używa
    uses pl.clockworkjava.payroll.PayrollService; 

Wersje

Java SE 12 = 56 (0x38 hex)
Java SE 11 = 55 (0x37 hex)
Java SE 10 = 54
Java SE 9 = 53
Java SE 8 = 52
Java SE 7 = 51
Java SE 6.0 = 50
Java SE 5.0 = 49
JDK 1.4 = 48
JDK 1.3 = 47
JDK 1.2 = 46
JDK 1.1 = 45

Szablony

uwagi
FreeMarker spring-boot-starter-freemarker
Groovy Templates spring-boot-starter-groovy-templates
JavaServer Pages (JSP) Brak (dostarczana przez Tomcat lub Jetty) uwaga - nie można użyć z jar
Mustache spring-boot-starter-mustache
Thymeleaf spring-boot-starter-thymeleaf

Normalnie trzeba wyłączyc cache szablonów, chyba że używamy DevTools - wtedy to robi to za nas

Thymeleaf

<dependency>   
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-thymeleaf</artifactId> 
</dependency>

dana z atrybutu żądania

<p th:text="${message}">Miejsce zarezerwowane dla wiadomości.</p>

pętle

<div th:each="ingredient : ${wrap}">   
            <input name="ingredients" type="checkbox" th:value="${ingredient.id}" />   
            <span th:text="${ingredient.name}">SKŁADNIK</span><br/> 
</div>

Projektowanie i dokumentowanie klas przeznaczonych do dziedziczenia

Konstruktory nie mogą wywoływać metod, które można przesłaniać, bo konstruktor klasy nadrzędnej jest wywoływany przed konstruktorem podklasy. Bezpieczne jest wywoływanie metod prywatnych, metod oznaczonych jako final i metod statycznych z poziomu konstruktora, bo żadnej z nich nie można przesłonić. Podobnie metody clone i readObject jak implementujemy Cloneable i Serializable. Na koniec, jeżeli decydujesz się implementować interfejs Serializable w klasie podlegającej dziedziczeniu, a klasa posiada metodę readResolve lub writeReplace, musisz zadeklarować metody readResolve lub writeReplace jako zabezpieczone, a nie jako prywatne. Jeżeli metody te będą prywatne, zostaną bez żadnego ostrzeżenia zignorowane w klasach pochodnych.

Equals, hashCode, Cloneable, Comparable

Equals

Używa się w obiektach do porównywania wartośći

x.equals(x) musi zwracać true, x.equals(null) musi zwracać false, jak x.equals(y) to y.equals(x) jak x.equals(y) i y.equals(z) to x.equals(z) Trzeba uważać z dziedziczeniem. Zamiast tego można stosować kompozycję - czyli w klasie zapisać obiekt, który miałby być dziedziczony. Czyli porównać czy jest ten sam obiekt (Float.compare(float, float) dla float, Double.compare(double, double), == dla pozostałych prostych, equals dla obiektów

hashCode

Funkcja, która zwraca int. Dobrze żeby był możliwie unikalny i na postawie wartości. Musi być taka zasada, że jeśli X.equals(Y) == true, to X.hashCode() == Y.hashCode(), ale jeśli mają te same hash code to nie muszą być equals = true, ale jest to zalecane. HashCode musi być stały. Używa się go w kolekcjach, np. przy sprawdzeniu czy dany element jest w zbiorze.

Cloneable

Jak już jakaś klasa go implementuje to trzeba pamiętać, żeby wywołać super.clone na parencie i skopiować wszystkie jej pola (uważać na referencje). Ale lepiej udostępnić konstruktor kopiujący lub fabrykę kopiującą. Tablice można kopiować przez clone.

Comparable

Implementować, jeśli obiekty klasy mają jakiś naturalny porządek

private static final Comparator<PhoneNumber> COMPARATOR =
        comparingInt((PhoneNumber pn) -> pn.areaCode)
           .thenComparingInt(pn -> pn.prefix)
           .thenComparingInt(pn -> pn.lineNum);
public int compareTo(PhoneNumber pn) {
   return COMPARATOR.compare(this, pn);
}

Ficzery

  • można importować statycznie, a potem używać np. stałych statycznych bez nazwy klasy: import static com.effectivejava.science.PhysicalConstants.*;
  • można używać podkreślnika w długich liczbach, dla lepszej widoczności

Adotacje

@SuppressWarnings("unchecked") - bez ostrzeżenia rzutowania @SafeVarargs - stosować jeśli używamy zmienną liczbę parametrów, ale musi ona być bezpieczna. Lepiej zrobić tak:

static <T> List<T> flatten(List<List<? extends T>> lists) {
List<T> result = new ArrayList<>();
   for (List<? extends T> list : lists)
      result.addAll(list);
   return result;
-----
audience = flatten(List.of(friends, romans, countrymen));

Typy zmiennych

  • Nie używać typów surowych np. List, zawsze lepiej zparametryzowane List, żeby była kontrola co wchodzi do listy.

Tablice są kowiarancyjne: Jeśli Sub jest typem podrzędnym względem Super, to tablica typu Sub[] jest typem podrzędnym względem Super[]

Typy ogólne z kolei są niezmiennicze — dla dwóch różnych typów Typ1 i Typ2, List<Typ1> nie jest ani typem podrzędnym, ani nadrzędnym dla List<Typ2>.

Dodatkowo Typy ogólne są zacierane - po kompilacji nie ma już informacji o type z nawiasów

Lista parametrów typu, która deklaruje typ parametru, znajduje się pomiędzy modyfikatorami metody a zwracanym typem. W tym przykładzie listą parametrów typu jest <E>, a zwracanym typem jest Set<E>. Konwencja nazewnictwa dla parametrów typu jest dla metod ogólnych taka sama jak dla typów ogólnych (tematy 29. i 68.):

public static <E> Set<E> union(Set<E> s1, Set<E> s2) {
    Set<E> result = new HashSet<>(s1);
    result.addAll(s2);
    return result;
}

producer--extends, consumer-super

Jeżeli typ parametryzowany reprezentuje producenta T, to należy użyć <? extends T>; jeżeli T jest konsumentem, należy użyć <? super T>. W naszym przykładzie klasy Stack, parametr src metody pushAll produkuje obiekty E do wykorzystania przez Stack, więc odpowiednim typem dla src jest Iterable<? extends E>; parametr dst metody popAll konsumuje obiekty E z Stack, więc odpowiednim typem dla dst jest Collection<? super E>.

-----------------------------
public class Stack<E> {
    private E[] elements;

   // Szablon typu dla parametru służącego jako producent E
   public void pushAll(Iterable<? extends E> src) {  //<? extends E> - tu wymaga dowolny podtyp E jak i sam typ E
      for (E e : src)
         push(e);
   }
   // Typ szablonowy dla parametru służącego jako konsument E
   public void popAll(Collection<? super E> dst) { // tu wymagana jest kolekcja typu bazowego do E, gdzie typ bazowy jest 
   //tak zdefiniowany, że E jest typem bazowym dla samego siebie
      while (!isEmpty())
         dst.add(pop());
   }
}

Kontener heterogeniczny

można robić mapy o dowolnym type

public static void main(String[] args) {
   Favorites f = new Favorites();
   f.putFavorite(String.class, "Java");
   f.putFavorite(Integer.class, 0xcafebabe);
   f.putFavorite(Class.class, Favorites.class);
   String favoriteString = f.getFavorite(String.class);
   int favoriteInteger = f.getFavorite(Integer.class);
   Class<?> favoriteClass = f.getFavorite(Class.class);
   System.out.printf("%s %x %s%n", favoriteString,
   favoriteInteger, favoriteClass.getName());
}
------------
public class Favorites {
   private Map<Class<?>, Object> favorites = new HashMap<>();
   public <T> void putFavorite(Class<T> type, T instance) {
      favorites.put(Objects.requireNonNull(type), instance);
   }
   public <T> T getFavorite(Class<T> type) {
      return type.cast(favorites.get(type));
   }
}

Zadanie

        BufferedReader reader =
                new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Podaj 3 słowa:");
        List<String> words = new ArrayList<>();
        words.add(reader.readLine());
        words.add(reader.readLine());
        words.add(reader.readLine());
        System.out.println(words);
        words.sort(Comparator.comparing(String::toString));
        System.out.println(words);
        words.stream().sorted(Comparator.comparing(String::length).reversed()).forEach(System.out::println);
        words.sort(Comparator.comparing(String::length).reversed());
        System.out.println(words);

FAQ

final

final to modyfikator, którego możemy użyć przy polach, metodach lub klasach. W zależności od tego, gdzie zostanie zastosowany, oznacza on odpowiednio, że do danego pola nie można przypisać innego obiektu w przyszłości, danej metody nie można przysłonić poprzez dziedziczenie lub danej klasy nie można rozszerzyć. Można tez jako argument funkcji - wtedy nie można go zmienić.

finally

finally to elementy bloku try-catch-finally, w którym możemy umieścić kod, który wykona się niezależnie od powodzenia operacji wewnątrz try — jest to dobre miejsce, aby pozamykać otwarte zasoby i ‘wyczyścić’ pamięć.

finalize

finalize() to metoda klasy Object, która jest wywoływana dokładnie raz, zanim obiekt zostanie usunięty z pamięci przez garbage collector (może się jednak zdarzyć, że nie zostanie ona wywołana, ponieważ obiekt nie jest usuwany); ogólnie nie jest najlepszą praktyką polegać na tej metodzie, lepszym rozwiązaniem jest samodzielne zarządzanie cyklem życia obiektu

Pola interfejsu

Pola interfejsu są jednocześnie publiczne, statyczne i finalne — trzeba im przypisać wartości już w momencie ich deklaracji. Deklaracja pola interfejsu nie różni się od deklaracji pola klasy. Zgodnie z konwencją przyjmuje się, że nazwy takich pól pisze się wielkimi literami, a poszczególne człony nazwy oddziela się znakiem podkreślenia

Autoboxing

Autoboxing to mechanizm języka Java, który pozwala na automatyczną konwersję pomiędzy prymitywami a obiektami odpowiadających typów.

Servlet

Servlet to specjalny obiekt, który implementuje interfejs javax.servlet.Servlet — jego zadaniem jest obsługa zapytań HTTP i generowanie odpowiedzi na nie. Wiele frameworków dostarcza już gotową implementację — np. DispatcherServlet w przypadku Spring MVC.

TDD

TDD - pisanie oprogramowania stymulowane przez testy.

SPRING

Jak działa Spring (a dokładniej jego kontener IoC)?

W momencie uruchomienia aplikacji Spring tworzy tzw. kontekst. W uproszczeniu można powiedzieć, że jest to kolekcja beanów i związanych z nią konfiguracji. Wewnątrz takiego kontekstu beany ‘widzą się’, ale nie widzą obiektów poza nim.

Początkowo znajdują się tam tylko springowe obiekty — w tym sam kontekst. W zależności od konfiguracji w pierwszym kroku inicjowane są kolejne beany — czyli po prostu tworzone są nowe obiekty i rejestrowane w kontekście (można o nim myśleć także jak o swoistej mapie — kontekst bowiem mapuje nazwy (id) na właściwe obiekty). Ten etap realizuje implementacja interfejsu BeanFactory, która często jest samym kontekstem (np. ClasspathXmlApplicationContext).

Po zakończeniu tego kroku do ‘pracy’ wkraczają implementacje BeanPostProcessor — są one odpowiedzialne za ‘automagię’ springa, czyli np nadawanie wartości polom z adnotacją @Autowired (za to odpowiedzialny jest akurat AutowiredAnnotationBeanPostProcessor). Jest to także sposób, w jaki możemy modyfikować domyślne zachowanie Springa wg własnych potrzeb. W międzyczasie, po wykonaniu pracy przez wszystkie znane kontekstowi implementacje tego interfejsu, wywoływana jest metoda init() beanów (jeśli istnieje), po czym obiekty te mogą wykonać dodatkowe zadania (większość tego nie robi).

W tym momencie inicjowanie jest uznane za zakończone, a aplikacja za uruchomioną.

Typy numeryczne

Jakie typy numeryczne są dostępne w Javie i do jakich zastosowań je używamy?

W Javie mamy dostępnych kilka typów numerycznych — w tym prymitywy oraz obiekty. Ponieważ prymitywy posiadają odpowiedniki w obiektach, omówimy tylko te drugie.

Podstawowym interfejsem, które implementują wszystkie typy numeryczne jest java.lang.Number — zawiera on metody pozwalające pobierać wartość jako prymityw int, byte, short itp. Dokładniej o typach liczbowych przeczytacie w tym tygodniu w kolejnym wpisie z cyklu Niezbędnik Juniora, a póki co ograniczymy się do wypisania dostępnych opcji. Do liczb całkowitych możemy użyć Byte, Short, Character, Integer, Long oraz BigInteger, z kolei do reprezentacji liczb zmiennoprzecinkowych służą klasy Float, Double oraz BigDecimal.

Uogólnienia (generyki, generic type)

Można uogólniać klasę - zwyczajowo dodaje się literki od T dalej. Można też uogólniać metody

public class Opakowanie<T, v>{
    public T val1;
    public T val1;
}
------------------
public static<U> void show(U val){
      System.out.println(val.toString());
}

taki przykład klasy zwracającej losowy element z przekazanej tablicy

public class Chooser<T> {
   private final List<T> choiceList;
   public Chooser(Collection<T> choices) {
      choiceList = new ArrayList<>(choices);
   }
   public T choose() {
      Random rnd = ThreadLocalRandom.current();
      return choiceList.get(rnd.nextInt(choiceList.size()));
   }
}

List> is somewhat analogous to List extends Object>. So the difference between List and List> is like the difference between List and List<? extends Number>

Różnica między == a equals

Operator == sprawdza tylko czy są to dokładnie te same obiekty, a to nie jest prawda. Stąd metoda equals — jako mechanizm w Javie do porównania, czy obiekty ‘znaczą to samo’ bardziej niż ‘są tym samym obiektem’.

Wyjątki

                   +-----------+
           | Throwable |
                   +-----------+
                    /         \
           /           \
          +-------+          +-----------+
          | Error |          | Exception |
          +-------+          +-----------+
       /  |  \           / |        \
         \________/      \______/         \
                            +------------------+
    unchecked     checked    | RuntimeException |
                    +------------------+
                      /   |    |      \
                     \_________________/
                       
                       unchecked

checked

Ma w swojej hierarchii dziedziczenia ma Exception i nie ma RuntimeException. Musi zostać obzłużony, bo inaczej będzie błąd kompilacji. Stosuje się, jeśli może zostać naprawiony.

unchecked

Dziedziczy po Error albo RuntimeException. Nie musi zostać obsłużony, ale wywyali program

continous deployment - continuous delivery

deployment - z wrganiem na serwer, deliwery - tylko dostarczenie, wgranie na przycisk

⚠️ **GitHub.com Fallback** ⚠️