Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[모던 자바 인 액션] 1주차 #3

Open
so3500 opened this issue Jun 30, 2023 · 3 comments
Open

[모던 자바 인 액션] 1주차 #3

so3500 opened this issue Jun 30, 2023 · 3 comments
Assignees
Labels
SummerCoding 땅울림 여름코딩 스터디 모던 자바 인 액션

Comments

@so3500
Copy link
Contributor

so3500 commented Jun 30, 2023

스터디 날짜

2023.06.30 9-10

내용

OT - 진행방식 논의

  • 모임 전 : 해당주차 내용을 5분이내 영상으로 녹화 후 공유한다.
  • 모임 중 : 개인 공부자료를 공유하면서 이야기 나눈다.
  • 모임 후 : 이슈를 생성하여 자료 링크를 공유한다.

챕터1. 자바8, 9, 10, 11
챕터2. 동작 파라미터화 코드 전달하기

공유

최승위

이성온

정민교

@so3500 so3500 added SummerCoding 땅울림 여름코딩 스터디 모던 자바 인 액션 labels Jun 30, 2023
@so3500 so3500 changed the title 1주차 - ch1, ch2 [모던 자바 인 액션] 1주차 - ch1, ch2 Jun 30, 2023
@jeongminkyo
Copy link

동작 파라미터화(Behavior Parameterization)

  • 아직은 어떻게 실행할 것인지 결정하지 않은 코드 블럭을 의미한다.
  • 즉, 코드 블럭의 실행은 나중으로 미뤄진다.
  • 결과적으로 코드 블럭에 따라 메서드의 동작이 파라미터화된다.
public interface ApplePredicate {
      boolean test(Apple apple);
}

public class AppleHeavyWeightPredicate implements ApplePredicate {

  public boolean test(Apple apple) {
    return apple.getWeight() > 150;
  }

}

public class AppleGreenColorPredicate implements ApplePredicate {

  public boolean test(Apple apple) {
    return GREEN.equals(apple.getColor());
  }

}

public class AppleRedAndHeavyPredicate implements ApplePredicate {

  public boolean test(Apple apple){
    return RED.equals(apple.getColor()) && apple.getWeight() > 150;
  }

}

// 프레디케이트 객체로 사과 검사 조건을 캡슐화하기
public static List<Apple> filterApples(List<Apple> inventory, ApplePredicate p) {
  List<Apple> result = new ArrayList<>();
  for(Apple apple: inventory) {
    if(p.test(apple)) {
      result.add(apple);
    }
  }
  return result;
}

// 전달한 ApplePredicate 객체에 의해 fileterApples 메서드의 동작이 결정된다!
List<Apple> redAndHeavyApples = filterApples(inventory, new AppleRedAndHeavyPredicate());

filterApples 메서드가 ApplePredicate 객체를 인수로 받도록 되어 있다. 이렇게 하면 filterApples 메서드 내부에서 컬렉션을 반복하는 로직과 컬렉션의 각 요소에 적용할 동작을 분리할 수 있다는 점에서 큰 이득을 얻게된다.

behavior

익명함수

자바의 지역 클래스(local class)와 비슷한 개념이다. 익명 클래스는 말 그대로 이름이 없는 클래스다. 익명 클래스를 이용하면 클래스 선언과 인스턴스화를 동시에 할 수 있다. 즉, 즉석에서 필요한 구현을 만들어서 사용할 수 있다.

List<Apple> redAndHeavyApples = filterApples(inventory, new ApplePredicate() {
    public boolean test(Apple apple) {
        return RED.equals(apple.getColor());
    }
});

익명 클래스 단점

  • 클래스의 생성과 인스턴스화를 동시에 하는 것이지만 생성을 위해 메서드 내부에 클래스를 정의해야 하므로 여전히 많은 공간을 차지한다.

  • 많은 프로그래머가 익명 클래스의 사용에 익숙하지 않다.

람다 표현식

람다 표현식은 메서드로 전달할 수 있는 익명 함수를 단순화한 것이라고 할 수 있다.

람다의 특징

  • 익명 : 메서드의 이름이 없기 때문에 구현해야 할 코드에 대한 걱정거리가 줄어든다.
  • 함수 : 메서드처럼 파라미터 리스트, 바디, 반환 형식, 가능한 예외 리스트를 포함하지만 클래스에 종속되지 않으므로 함수라고 부른다.
  • 전달 : 메서드 인수로 전달하거나 변수로 저장할 수 있다.
  • 간결성 : 익명 클래스처럼 클래스 이름, 메서드 이름, 파라미터 타입, 반환 타입 등이 없기 때문에 코드가 간결하다.

람다의 구조

  • 파라미터 리스트
    • 파라미터 타입 생략 가능
    • 파라미터가 하나일때 () 생략 가능
  • 화살표
  • 람다 바디
    • 실행 내용이 단일 실행(한 줄)일때 {} 생략 가능. {}이 생략되면 return 키워드와 **;(세미콜론)**도 같이 생략해야 한다.
List<Apple> redAndHeavyApples = filterApples(inventory, (Apple apple) -> RED.equals(apple.getColor()));

@s5646s
Copy link
Contributor

s5646s commented Jun 30, 2023


marp: true
theme: gaia
class: invert
paginate: true

Modern Java in Action

Week 1
발표자: 최승위


#이번 주 범위

  • 1장: Java 8,9,10,11 : 무슨 일이 일어나고 있는가?
  • 2장: 동작 파라미터화 코드 전달하기

90년대에 Java 는 왜 인기가 많았는가?

  • 적절한 High 레벨 언어
  • JVM 기반의 높은 이식성
  • 우수한 객체지향성

그 이후 Java의 새로운 국면

  • 시대가 변했다. 기하급수적으로 덩치가 커지는 데이터셋
  • 그로 인한 병렬 처리의 필요성 UP

JAVA: 나도 함수형 그거 할래!

  • 스트림 처리
  • 동작 파라미터화
  • 가변 공유 상태가 없는 병렬성
  • 메서드와 람다의 일급화
  • NPE를 방지할 Optional의 등장

Java8의 동작 파라미터화

  • 동작 파라미터화는 함수형 프로그래밍의 기본 컨셉!
  • 결정되지 않은 일급함수를 메서드의 파라미터로 '직접' 넣는 것
  • Java8의 람다표현식을 통해 이 과정을 깔끔하게 구현 가능하다.

@so3500
Copy link
Contributor Author

so3500 commented Jun 30, 2023

1주차 - JDK9~17 preview

jdk 버전 별 특징 정리

JDK 9 (2017/09)

Modular System

  • java 9는 Java Platform Module System (JPMS) 이라고 알려진 새로운 추상화를 도입함
  • 종속성(dependency) 개념이 있으며 public API 만 보여주고 세부 구현을 숨기거나 비공개 상태로 유지할 수 있음
  • 모듈 시스템을 만든 이유: 관심사와 분리정보 은닉
  • 자바 9 이전에는 클래스 가시성 제어만을 제공함 public, protected, default, private
  • 하지만 패키지간에 명시된 가시성 제어가 없었음
  • module은 사용하는 모듈, 내보내는 모듈을 명시하여 의존성 관리가 쉽지만, gradle 프로젝트 단위로 1개만 작성 가능

모듈을 선언한 파일

module-info.java 파일을 package root 에 생성

// src/org.astro/module-info.java
module org.astro {
	requires org.greetings; // org.greetings 에 대한 종속성을 가짐을 명시
}

모듈내의 구현 파일

// src/org.astro/org/astro/World.java
package org.astro;

import org.greetings;

public class World {
    public static String name() {
        return "world";
    }
}

Process API

기존에는 process 관련 동작을 수행하려면 직접 커맨드를 수행해야 했다.

Runtime.getRuntime().exec("command ...");

Java9 부터는 Process API 를 이용하여 손쉽게 pid를 가져오거나, process kill 을 할 수 있다.

ProcessHandle self = ProcessHandle.current();
long pid = self.pid();
self.children().forEach(ProcessHandle::destroy);

새 프로세스를 손쉽게 생성할 수 있다.

ProcessBuilder processBuilder = new ProcessBuilder("command ...", "-version");
Process process = processBuilder.inheritIO().start();
ProcessHandle processHandle = process.toHandle();

Immutable Collections

java.util 이하 클래스에서 element 목록을 받아 컬렉션 생성하는 기본기능을 제공한다.

Set<String> strKeySet = Set.of("key1", "key2", "key3");
List<String> strKeySet = List.of("key1", "key2", "key3");

기존에는 guave library 등으로 선언했다. (서드파티 의존성 필요)

// com.google.common.collect.Lists
List<String> strKeys = Lists.newArrayList("key1", "key2", "key3");

Optional to stream

java.util.Optional.stream() optional 에 대한 stream 제공

List<String> filteredList = listOfOptionals.stream()
  .flatMap(Optional::stream)
  .collect(Collectors.toList());

JDK 10 (2018/03)

타입 추론 변수 var (local variable)

  • for문, try-with-resource 시 유용하게 사용할 수 있다.
  • chaining을 끊을때 var를 유용하게 사용할 수 있다.
var countMap = strings.stream()
                     .collect(groupingBy(s -> s, counting()));

var maxEntry = countMap.entrySet()
                       .stream()
                       .max(Map.Entry.comparingByValue());

제약조건

  1. 지역변수에서 사용가능.(클래스에서 x)

  2. 초기화가 필수, null초기화 불가

  3. 배열에 사용불가

    var arr = {1,2,3};

  4. Lambda식 사용 불가 (jdk 11 에서 개선)

  5. (+) 의미를 알기 쉽게 변수명을 지어야 한다.

주의

  1. double, float / int, long 구분 주의

  2. diamond 사용시 object로 생성되므로 주의해야한다.

    // before java10
    PriorityQueue<Integer> itemQueue = new PriorityQueue<>();
    
    // after java10
    // DANGEROUS: infers as PriorityQueue<Object>
    var itemQueue = new PriorityQueue<>();

Optional.orElseThrow()*

기존에는 exceptionSupplier 를 넘겨줘야 했다.

이제 Exception을 지정해주지않아도 NoSuchElementException가 기본으로 throw된다.

 /**
 * If a value is present, returns the value, otherwise throws
 * {@code NoSuchElementException}.
 *
 * @return the non-{@code null} value described by this {@code Optional}
 * @throws NoSuchElementException if no value is present
 * @since 10
 */
public T orElseThrow() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}

public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
	if (value != null) {
		  return value;
	} else {
		  throw exceptionSupplier.get();
	}
}

JDK 11 (2018/09) LTS

New String Methods

string 에 유용한 새로운 method 가 생겼다.

  • isBlank, lines, strip, stripLeading, stripTrailing, reapet
  • 기존에는 다른 라이브러리를 많이 사용했음. org.apache.commons.lang3.StringUtils

Collection to Array

  • collection을 array로 바로 전환할수있는 메서드가 생겼다 toArray
List<String> sampleList = Arrays.asList("Java", "Kotlin");
String[] sampleArray = sampleList.toArray(String[]::new);

assertThat(sampleArray).containsExactly("Java", "Kotlin");

Not Predicate Method

  • predicate에서 not을 반환해주는 메서드가 생겼다.
 ...stream()
 .filter(Predicate.not(String::isBlank))
 ...

Local-Variable Syntax for Lambda

  • 람다에서 자료형을 명시하지않고 var 를 사용할수있게 되었다.
  • 보통 자료형을 생략하지만, 자료형을 기입하면 어노테이션과같은 수식어를 붙일 수 있다.
 // asis
 (String s1, String s2) -> s1 + s2
 (s1,s2) -> s1 + s2

 // tobe
 (@Nonnull var s1, @Nullable var s2) -> s1 + s2

java.net.http.HttpClient

  • HttpClient는 HTTP/1.1 과 HTTP/2를 모두 지원하고, java11 에서 http통신의 기본객체이다.
  • 비동기가 기본이고 CompletableFuture 구현체이다.
  • Apache HttpClient, Jetty, Spring RestTemplate 과 같은 서드파티 의존성없이 기본 제공되어 사용가능하다.
HttpRequest request = HttpRequest.newBuilder()
    .uri(new URI("https://mmm"))
    .headers("Content-Type","text/plain")
    .GET()
    .build();
HttpClient client = HttpClient.newHttpClient();

// sync
HttpResponse<String> response = client.send(request,BodyHandlers.ofString());

// async
ExecutorService exeService = Executors.newFixedThreadPool(2);
CompletableFuture<HttpResponse<String>> asyncResponse = client
    .executor(exeService)
    .sendAsync(request,BodyHandlers.ofString());

assertThat(response.uri()).isEqualTo("https://mmm")

No-Op Garbage Collector

  • garbage Collect를 하지않는 GC 지원
  • XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
  • 일반 어플리케이션에 사용하기보다, 성능테스트나 짧게 돌아가는 자바프로그램에 적합.

JDK 12 (2019/03)

String Class new Methods

indent: 들여쓰기

String text = "hello\nworld";
text.indent(4);

//    hello
//    world

transform: single argument 의 function 을 받아서 string 에 적용

String text = "hello world";
String transformed = text.transform(value ->
    new StringBuilder(value).reverse().toString()
);

// dlrow olleh

Teeing Collector

  • 2개의 collector를 거쳐 마지막 merger function에서 결과가 취합되는방식
Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1,
  Collector<? super T, ?, R2> downstream2, BiFunction<? super R1, ? super R2, R> merger)

@Test
void givenSetOfNumbers_thenCalculateAverage() {
    double mean = Stream.of(1, 2, 3, 4, 5)
      .collect(
        Collectors.teeing(
            Collectors.summingDouble(i -> i),       // 첫번째 collector, 15.0
            Collectors.counting(),                  // 두번째 collector, 5
            (sum, count) -> sum / count));          // 첫번째 collector의 결과 sum, 두번째 collector의 결과 count

    assertEquals(3.0, mean);
}

JDK 13 (2019/09)

ZGC : Uncommit Unused Memory

  • JDK11에서 ZGC도입으로 스탑타임이 10ms를 넘지않게되었는데, ZGC는 미사용하는 힙메모리를 OS에 반환하지 않았다.
  • JDK13부터는 uncommited memory를 OS에 디폴트로 반환한다. Xms 값까지만.
  • 이걸 회피하려면 Xms = Xmx 로 설정하거나 XX:-ZUncommit 사용하면된다.
  • 추가로 max heap size가 4TB -> 16TB로 증가했다.

JDK 14 (2020/03)

NPE message ⭐️

  • NullPointException 의 메지가 어디서 발생한 npe인지 상세하게 나온다.
  • 메서드 체이닝 시에 라인넘버만 가지고는 확인하기 어려웠던 부분인데, 이제 원인을 찾기 쉬워졌다.
# ASIS
Exception in thread "main" java.lang.NullPointerException
at com.baeldung.MyClass.main(MyClass.java:27)

// obj.get(obj2.get(....

# TOBE 
java.lang.NullPointerException: Cannot store to int array because "a" is null

Forein Memory Access API JEP 370

  • mapDB나 memcached 같은 라이브러리에서 이미 제공중인 heap 메모리 이외 영역을 다루는 api를 java에서 제공한다.

JDK 15 (2020/09)

Records type

  • 쉽게 immutable data object를 만들수있는 새로운 java 클래스 타입이다.
  • 기본 포함
    • getter
    • toString (meaningful)
    • all-argument constructor
    • equals
    • hashCode
  • 예전에는 lombok 에서 제공하는 각 어노테이션을 달거나 더 많은 기능을 제공하는 @DaTa 를 사용해야 했음
public record Person(String name, int age){
  // 생성자 validation 가능
  public Person {
    if (age < 0) { throw new Exception("illegal");}
  }
}

sealed class JEP 409

  • 인터페이스에서 어떤 클래스가 상속할수있는지 명시할 수 있는 방식.
public abstract sealed class Person
    permits Employee, Manager {
}

public final class Employee extends Person {}
public non-sealed class Manager extends Person {}
  • sealed 클래스를 상속하는 클래스는 추가 상속을 제한하기 위해 finalnon-sealedsealed 중 명시해야한다.
  • if/else 문에서 instanceof를 체크하는 경우 일부 타입체크가 누락될 수 있는데, sealed 를 사용하면 컴파일러가 타입체크 누락을 warning으로 알려준다. → 그런데 if/else에서는 동작하지 않는듯함 (jdk 17 에서 테스트)
  • 추후 pattern switch 사용시 default case 없이, 누락 없이 sealed 로 명시된 서브클래스 타입체크가 가능하다.
  • pattern switch를 사용할 수 있을때 sealed 클래스의 역할이 유용해질듯. (17까지는 preview)
Shape rotate(Shape shape, double angle) {
    return switch (shape) {   // pattern matching switch
        case Circle c    -> c; 
        case Rectangle r -> shape.rotate(angle);
        case Square s    -> shape.rotate(angle);
        // no default needed!
    }
}

Text Blocks ⭐️

  • 줄내림 등 가독성에 좋은 textblock이 정식 사용가능하다.
  • java 13, 14 에선 preview 기능
String str =  """
            <html>
                <body>
                    <span>example text</span>
                </body>
            </html>""";

JDK 16 (2021/03)

default method를 proxy로 호출가능

Object proxy = Proxy.newProxyInstance(getSystemClassLoader(), new Class<?>[] { HelloWorld.class },
    (prox, method, args) -> {
        if (method.isDefault()) {
            return InvocationHandler.invokeDefault(prox, method, args);
        }
        // ...
    }
);
Method method = proxy.getClass().getMethod("hello");
assertThat(method.invoke(proxy)).isEqualTo("world");

day period

  • 하루중 언제인지 나타내는 포맷이 생김
LocalTime date = LocalTime.parse("15:25:08.690791");
System.out.println(date.format(DateTimeFormatter.ofPattern("h B")));
// 3 오후
// 3 in the afternoon

Stream.toList method

// ASIS
...stream().collect(Collectors.toList())
// TOBE
...stream().toList();

pattern matching for instanceof

// ASIS
if (obj instanceof String) {
    String t = (String) obj;
}

// TOBE
if (obj instanceof String t) {
 t.isEmtpy
}

JDK 17 (2021/09) LTS

psuedo-random number generator (PRNG)

  • 랜덤을 생성하는 인터페이스가 추가되었다.
  • 기존 java.util.Random 등은 deprecated
  • stream 호환성이 좋아졌다.
public IntStream getPseudoInts(String algorithm, int streamSize) {
    // returns an IntStream with size @streamSize of random numbers generated using the @algorithm
    // where the lower bound is 0 and the upper is 100 (exclusive)
    return RandomGeneratorFactory.of(algorithm)
            .create()
            .ints(streamSize, 0,100);
}

Foreign Function & Memory API

Foreign Function : 힙메모리 밖에있는 다른 JDK 내의 function을 사용가능하다.

ex) C라이브러리 코드 사용가능

private static final SymbolLookup libLookup;

static {
    // loads a particular C library
    var path = JEP412.class.getResource("/print_name.so").getPath();
    System.load(path);
    libLookup = SymbolLookup.loaderLookup();
}

4. MacOS/AArch64 port

  • m1같은 arm64 실리콘칩 에서 jdk가 돌아가도록 한다.
  • 기존에는 rosseta 를 통해 돌아가서 성능저하 문제가 있었음. (zulu는 arm 용)

@so3500 so3500 changed the title [모던 자바 인 액션] 1주차 - ch1, ch2 [모던 자바 인 액션] 1주차 Jul 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
SummerCoding 땅울림 여름코딩 스터디 모던 자바 인 액션
Projects
None yet
Development

No branches or pull requests

3 participants