ThreadLocal과 InheritableThreadLocal에 대해 많이 들어보신 분도 계시겠지만 생소하신 분도 계실 것 같습니다. 두 클래스는 Java 1.2에 등장한 클래스이며 ThreadLocal과 InheritableThreadLocal에 대해 한번 알아보겠습니다. ThreadLocal 쓰레드 로컬 변수를 제공하며 이 로컬 변수는 get 또는 set 메서드를 통해 액세스 하거나 변경할 수 있으며 쓰레드 마다 독립적으로 갖고있는 변수를 말합니다. ThreadLocal의 설명을 해석하자면 위와 같습니다. 즉, ThreadLocal에 할당된 변수는 각 쓰레드마다 고유하게 할당되므로 멀티쓰레드 간 쓰레드 세이프 하게 프로그램을 작성할 수 있습니다. 예제코드를 함께 살펴보겠습니다. ThreadLocal..
Java의 Functional Interface란 단 1개의 추상메서드를 가진 인터페이스를 얘기합니다. 이번 글에서는 Functional Interface에 대해 새롭게 알게 된 내용을 공유하고자 합니다. 예제 위 소스를 보시면 반환 타입이 int인 1개의 추상메서드가 있고 @FunctionalInterface가 선언되어 있습니다. @FunctionalInterface를 선언하면 컴파일러에게 이 인터페이스는 단 1개의 추상메서드만 허용하는 Functional Interface라는걸 알립니다. 만약에 추상메서드를 2개 이상 작성할 경우 위와 같은 컴파일 에러를 내뱉게 됩니다. 이번에는 num2() 라는 추상메서드를 지우고 또 다른 추상메서드를 추가해보도록 하겠습니다. 이번엔 아까처럼 컴파일 에러가 발생하지..
웹 애플리케이션 개발을 하다보면 피해갈 수 없는 문제 중 하나가 바로 타임존(Timezone) 이다. 데이터베이스를 통해 받아온 날짜형식의 데이터를 원하는 Timezone에 맞춰서 보여줘야 하는데 제대로 동작이 안되는 경우를 한번쯤은 겪어봤을 것이다. 지금부터 필자와 함께 어떻게 설정을 해줘야 하는지 코드를 통해 알아보자. 환경 Spring Boot 2.6.8 Java 17 (Timezone = Asia/Seoul) MySQL 8.0.27 (Timezone = UTC) MySQL Connector/J 8.0.29 예제코드 현재 Timezone이 UTC인 MySQL 서버를 띄웠고 Java 애플리케이션에서 JDBC API를 통해 Connection을 맺은 후 현재시간을 조회해오는 SQL을 작성 후 결과값을 ..
최근에 회사 서비스에 AWS X-RAY를 적용하면서 요청 파라미터에 대한 정보를 트레이스 하려고 Reflection을 이용해서 파라미터의 변수이름과 값을 조회했는데 파라미터 값은 잘 나왔는데 변수이름이 'arg0', 'arg1' 이런식으로 나왔었다. 스프링 부트 환경의 서비스에서는 파라미터 이름이 정상적으로 나왔는데 스프링 부트가 아닌 XML 기반설정의 스프링 환경에서 저렇게 나왔었다. 문제원인은 해당 애플리케이션을 빌드할 때 컴파일 옵션을 추가해야하는데 추가가 안되있어서 발생된 것이다. 코드를 한번 살펴보자 예제 helloWorld 메서드의 첫번째 매개변수엔 String 타입의 message라는 이름의 매개변수가 있는데 이 message라는 이름을 출력하고 싶어서 다음과 같이 코드를 작성했는데 결과는 ..
Java 애플리케이션을 AWS EC2에 배포하고나면 자주 발생되는 문제중 하나가 바로 타임존문제다. 타임존 문제는 쉽게 얘기해서 현재 시간과 서버의 시간이 맞지않아 현재날짜를 출력했을 때 이전 또는 이후의 시간이 출력되는건데 EC2 같은경우는 타임존이 UTC이고 한국은 타임존이 KST이다 KST는 UTC보다 9시간이 빠르기 때문에 Java 애플리케이션을 EC2에 배포하고 현재시간을 확인해보면 -9시간된 시간이 출력된다. 이 부분은 EC2에 배포할 때 간단하게 해결할 수 있다. 현재시간 출력 로컬에서 현재시간을 출력하는 애플리케이션을 개발하여 EC2에 배포해보자. JVM 파라미터 추가 EC2에 배포후 해당 Jar파일을 실행하면 현재시간보다 -9시간이 되서 나오지만 JVM 파라미터 중 user.timezon..
오늘 회사에서 운영하는 서비스에 장애가 발생되었는데 로그를 확인해보니 NullPointerException이 발생되었다. 그래서 해당 예외가 발생된 코드를 확인해봤는데 null값을 참조하여 코드를 작성한건 아니었다. 하지만 NullPointerException은 null값이 참조된 인스턴스의 필드 or 메서드를 호출한 경우 외에 다른상황에서도 발생될 수 있는데 그 케이스에 대해 알아보자. NullPointerException (1) str이라는 String 타입의 변수에 null을 할당하고 charAt() 메서드를 호출한 결과 NullPointerException이 발생되었다. str이라는 변수에 null이 할당됨으로써 객체의 주소값이 메모리상에서 제거되어 참조할 수 없는 값이 할당되었기 때문에 Null..
JAVA로 Thread 관련 프로그래밍을 학습하다보면 start() 메서드와 run() 메서드를 보게되는데 두 메서드를 실행하게되면 Thread의 run() 메서드를 실행하게 된다. 다만 이 두 메서드의 동작방식을 제대로 이해하지 못하고 사용하면 프로그램이 원치않게 실행 될 수 있다. 이 두 메서드의 동작방식의 차이를 한번 살펴보자. Thread.start() main 메서드에 현재 실행된 Thread 이름을 출력하고 Thread 인스턴스를 5개 생성한다. 인스턴스 생성시 생성자로 Runnable 타입을 주입해준 후 start() 메서드를 실행하였다. 출력결과로 main Thread와 Thread 인스턴스 5개가 출력된 걸 확인할 수 있다. Thread.run() 이번에는 run() 메서드를 실행해보았다..
Java에서 메서드를 호출할 때 인자를 넘기는 방법은 Call By Value와 Call By Reference두가지가 있다. Call By Value는 값에 의한 호출이며 메서드로 인자값을 넘길 때 그 값을 복사해서 넘긴다. 이 방식으로 호출하면 호출한 메서드 내부에서 해당 값을 사용할 때 해당값에 데이터가 변경되도 호출한쪽에서 넘긴 값은 변경되지 않는다. Call By Reference는 참조에 의한 호출이며 메서드로 인자값을 넘길 때 해당 객체를 참조하는 주소를 넘겨준다. 이 방식으로 호출하면 호출한 메서드 내부에서 해당 값을 사용할 때 해당값에 데이터가 변경되면호출한쪽에서 넘긴 값도 변경된다. Call By Value main 메서드에서 정수형 데이터 10과 20이 저장된 변수 두개를 swap 메..
JAVA에서 HTTP 통신을 하기위한 대표적인 라이브러리가 HttpUrlConnection이 있는데 이걸로 API를 개발했을때는 소스코드도 굉장히 길어지고 가독성도 좋지않으며 Type Safety하지않아 JSON으로 받은데이터를 GSON으로 일일이 Convert 해줘야했다. 그런와중에 Retrofit이란걸 알게되었는데 Retrofit을 처음봤을때 코드가 간결하고 가독성이 있고 사용하기도 편해서 이번장에서 정리해보려고 한다. JAVA는 11버전으로 한다. 라이브러리 추가 JAVA에서 Retrofit API를 사용하기위해선 총 6가지의 라이브러리가 필요하다. com.squareup.retrofit2 converter-gson 2.5.0 com.google.code.gson gson 2.8.8 org.jetb..
GSON이란 JSON포맷으로 되있는 문자열 데이터를 JAVA의 오브젝트로 직렬화 및 역직렬화 해주는 라이브러리이다. 예제코드와 함께 사용법을 알아보자. 라이브러리 다운 JSON https://mvnrepository.com/artifact/org.json/json/20201115 GSON https://mvnrepository.com/artifact/com.google.code.gson/gson/2.8.6 두개의 라이브러리를 다운받고 프로젝트 마우스 우클릭 > Build Path > Configure Build Path > Libraries 탭 > Add External JARs 클릭후 다운받은 jar파일을 추가한다. JAVA Class 생성 public class Student { private Str..
JAVA로 개발하다보면 제일많이 쓰이는 클래스가 String 클래스인것같다. 이번장에서는 String에 대해 알아보자 String이란? String 클래스는 문자열을 다루는 클래스이며 immutable 하다는 특징이 있다. immutable은 한국어로 해석하면 불변이라는 단어인데 String 객체에 값이 초기에 할당되면 그 값은 변경되지 않는다. String 객체 생성방법 String 객체는 생성하기위해 2가지방식이 있다. 리터럴을 이용한 방법과 new연산자를 이용한 방법이 있다. 리터털로 생성하게되면 String 객체는 String Constant Pool이란 공간에 저장이되며 new연산자를 이용해 생성하면 Heap영역에 생성된다. 그리고 각 변수 a1, a2는 Stack 메모리에 올라가며 String..
우연히 어느 개발커뮤니티 사이트에 올라온 글을 보다 VO를 Map으로 변환해야 하는 질문글이 올라왔는데 그 방법이 궁금해서 이참에 Reflection을 이용하여 양방향으로 원하는 타입에 맞게 변환하는 코드를 작성해 보았습니다. VO Map HTML 삽입 미리보기할 수 없는 소스 결과 HTML 삽입 미리보기할 수 없는 소스 List List HTML 삽입 미리보기할 수 없는 소스 결과 HTML 삽입 미리보기할 수 없는 소스 참고로 Map에서 VO로 변환할 때 두번째 인자에 들어가는 Class 타입엔 해당 Class의 기본 생성자가 있어야한다.
이번장에서는 JAVA의 static에 대해 정리해보고자 한다. static(정적)이란 '고정된' 의미를 말하는데 static 키워드는 필드와 메서드에 올 수 있다. 이때 이 필드와 메서드를 클래스변수, 클래스메서드라고 부른다. 그리고 static 키워드를 붙히게 되면 ClassLoader가 class파일을 메모리에 적재할때 static 영역에 생성되기 때문에 인스턴스를 생성하지 않아도 접근할 수 있다. 예제코드1 위 예제코드를 작성함으로 JVM은 다음과 같은 행위를 하게된다 (1) Main.java를 Main.class로 컴파일을 하게된다. (2) Line 8에서 Main이란 이름을 가진 생성자를 찾아 그 생성자를 가진 class를 인스턴스화 하여 Heap영역에 적재한다 (3) 인스턴스화된걸 main 이..
이번장에는 JAVA 8 부터 제공해주는 스트림과 함수형 인터페이스에 대해 알아보자. 스트림 JAVA 8부터 추가되었으며 Collection의 저장요소를 순회하면서 각 요소들에 대한 필터, 연산, 그룹핑 등의 작업을 해주는 기능이며 람다표현식으로도 처리를 할 수 있다. 스트림이 나오기 전에는 Collection객체를 처리할때 코드가 많아지고 가독성이 좋지않았다. 아래 예제코드를 한번보자 스트림 이전코드 스트림 없이 List를 순회하면서 문자열 'A'가 존재하는 요소들만 따로 List로 얻고싶다면 직접 for문을 돌려서 요소들 하나씩 체크하여 또다른 List에 담아주었다. 가독성도 별로이고 코드길이만 괜히 길어질 뿐이다. 이제 이 방식을 스트림의 기능중 '필터'를 이용해서 처리해보도록 하자. 스트림 이후코드..
2장에서는 JAVA에서 JSON 데이터로 HTTP 통신을 해보는 시간을 가졌는데 이번에는 직접 JSON 데이터를 다뤄보는 시간을 가져보자 JSON 데이터를 다루기 위한 라이브러리와 HTTP통신하는 예제는 아래링크에 첨부해두었다. https://kim-jong-hyun.tistory.com/29 JSONObject 생성 8 Line에 있는 코드가 외부에서 응답받은 JSON 데이터라 가정해보자. String타입의 JSON포맷데이터이다. 이 값을 JSONObject 생성자 호출시 인자로 전달해주면 JSONObject 객체가 생성되며 get(String key) 메서드로 해당 key에 맞는 value를 꺼내온다. 이때 value엔 어떤타입이 담겨있는지 모르니 해당 값에 맞게 casting을 해주면 된다. JSO..
JAVA에서 List를 만들때 ArrayList나 LinkedList와 같은 List 인터페이스를 구현한 구현체의 객체를 생성할 수 있는데 이번글에는 Arrays.asList()와 List.of() 메소드로도 생성할 수 있습니다. 오늘은 이 2개의 차이에 대해 한번 알아보겠습니다. List 생성하기 Arrays.asList()와 List.of()로 각각 List를 생성하였습니다. Arrays.asList() Arrays.asList()의 리턴값은 java.util.ArrayList이 아닌 Arrays 클래스의 내부클래스 ArrayList입니다. asList() 메서드 시그니처를 확인해보면 가변인자를 받게끔 되있고 4323 Line을 확인해보면 ArraysList(Arrays 내부) 클래스의 구조는 배열로..
이번장에는 JAVA에서 HTTP 통신으로 외부 API를 호출하여 JSON 데이터를 주고받는법을 알아보자. Spring을 이용한 API 개발을 할때 Jackson 라이브러리가 있어서 JSON 요청데이터 파싱 및 응답을 Spring이 컨버팅 해줘서 편하지만 Spring 환경이 아닌 순수 JAVA에선 어떻게 해야하는지 예제코드와 함께 알아보자. JSON 라이브러리 등록 JSON 데이터를 JAVA에서 다루기위해선 JSON 관련 라이브러리를 등록해야한다. 아래링크에 들어가서 jar파일을 다운받고 Build Path에 추가하자. Spring이라면 maven이나 gradle에 해당 의존성을 추가해주면 된다. https://mvnrepository.com/artifact/org.json/json/20201115 jar..
JAVA 첫장을 다루는 시간이다. Spring으로 개발을 해오면서 필드 및 메소드 상단에 Annotaion을 선언함으로써 런타임시 스프링에서 직접 객체를 생성하여 주입해주는데 이는 모두 Reflection에 의해 생성이 된다. Reflection이란 객체를 통해 필드, 메소드, 생성자 정보를 얻을 수 있으며 클래스안에 존재하는 변수의 값도 조작할 수 있고 메소드를 호출할 수 있다. Reflection에 대해 들어보기만 하고 상세히 알아보는 시간이 없었는데 간단한 예제를 통해 알아보자. 클래스 및 필드, 메소드 생성 Reflection 이라는 클래스를 생성하여 필드와 메소드를 생성하였다. 필드 및 메소드에 주입할 어노테이션 생성 필드와 메소드에 값을 주입시키기 위해 어노테이션을 생성하였다. 코드 11라인을..