아무거나 개발공부 27

람다에서 지역변수 값을 변경하지 못하는 이유 Variable used in lambda expression should be final or effectively final

개요 JAVA에서 람다식을 사용하다보면, 가끔 인텔리제이에서 Variable used in lambda expression should be final or effectively final 해당 내용의 컴파일 에러가 나온다. 대강 구글링하여 지역변수를 사용하면 안된다는 건 알고있었는데 정확한 이유는 알지 못하고, 나중에 리서치하고 정리해야지 하고 넘어갔다. 람다와 지역변수, 전역변수 더 나아가 멀티쓰레드, 메모리할당 구조까지 폭넓은 범위를 다루고 있었고, 이에 대해 정리하였다. 쓰레드 메모리 할당 구조 위 그림은 멀티 쓰레드의 메모리 할당 구조이다. CODE, DATA(Method Area), HEAP 부분은 공유하고, Stack 영역만 각각 사용하는 걸 볼 수 있다. JAVA에서 지역변수는 Stack ..

JAVA - 리플렉션의 모든 것

아래 코드는 스프링을 사용한 BookService 코드이다. @Service public class BookService { @Autowired BookRepository bookRepository; } 질문 bookRepository 인스턴스는 어떻게 null이 아닌걸까? 스프링은 어떻게 BookService 인스턴스에 BookRepository 인스턴스를 넣어준 것일까? 리플렉션 API - 클래스 정보 조회 리플렉션의 시작은 Class 이다. Class에 접근하는 방법 모든 클래스를 로딩 한 다음 Class의 인스턴스가 생긴다. “타입.class”로 접근할 수 있다. 모든 인스턴스는 getClass() 메소드를 가지고 있다. “인스턴스.getClass()”로 접근할 수 있다. 클래스를 문자열로 읽어오..

스프링 부트 2.x 에서 3.x 로 버전 업 시 발생하는 이슈

개요 스프링 부트 2.x 에서 3.x 로 마이그레이션하면서, 여러 이슈가 있었는데, 그 중org.apache.httpcomponents.client5 의존성은 개인적으로 까다롭고, 바뀐 버전에 대해 정확히 알아보고 사용해야 할 것 같아 정리한다. pom.xml 수정 BEFORE org.apache.httpcomponents httpclient 4.5.13 AFTER org.apache.httpcomponents.client5 httpclient5 5.2.1 RestTemplate 버전 업 이후, RestTemplate설정 부분에서 에러가 발생하였다. 원인은 Spring Framework 6(스프링 부트 3.x)에서 HttpClient 4 라이브러리가 삭제되었기 때문이다. 아래 스프링 공식문서 참고 Dep..

JVM & 클래스 로더란?

JVM (Java Virtual Machine) 자바 가상 머신으로 자바 바이트 코드(.class 파일)를 OS에 특화된 코드로 변환(인터프리터와 JIT 컴파일러)하여 실행한다. JRE (Java Runtime Environment): JVM + 라이브러리 자바 애플리케이션을 실행할 수 있도록 구성된 배포판. JVM과 핵심 라이브러리 및 자바 런타임 환경에서 사용하는 프로퍼티 세팅이나 리소스 파일을 가지고 있다. 개발 관련 도구는 포함하지 않는다. (그건 JDK에서 제공) JDK (Java Development Kit): JRE + 개발 툴 JRE + 개발에 필요할 툴 소스 코드를 작성할 때 사용하는 자바 언어는 플랫폼에 독립적. 오라클은 자바 11부터는 JDK만 제공하며 JRE를 따로 제공하지 않는다...

직렬화 매개변수로 ArrayList는 되고, List는 안되는 이유

개요 프로젝트를 진행하면서, 직렬화 된 객체를 매개변수로 받는 메서드를 만들었다. public void putData(String key, Serializable data) { data.put(key, data); } 해당 메서드를 사용하는데, List 타입으로 직렬화 변수를 넣으면 컴파일 에러가 발생하였고, ArrayList 타입을 넣었을 때는 정상적으로 동작한다. // 정상동작 ArrayList newData = new ArrayList(); newData.putData(key, newData); // Type 컴파일 에러 발생 List newData = new ArrayList(); newData.putData(key, newData); 선언은 다르지만 어쨋든 new ArrayList()을 할당 했..

JAVA - UnsupportedOperationException 발생 해결

List로 변환 가능한 메소드 자바에서는 list로 변환하는 3가지 메소드가 있다. Arrays.asList() Collection.singletonList() List.of() 3가지에 대한 자세한 설명은 아래 링크에 있다. https://code-killer.tistory.com/148 이 3가지 메소드의 가장 큰 특징 중 하나는 List의 길이를 바꿀 수 없다는 점이다. 즉 List의 메소드 중 길이를 바꾸는 add , remove 등의 기능을 사용할 수 없다. 발생 상황 List cardList; List tempCardList = new ArrayList(); .... 중략 (cardList에 Card가 add) ..... //Collection.singletonList()을 활용하여 2차원 L..

스프링 핵심 원리이해 - 빈 Life Cycle 콜백

스프링 빈은 아래와 같은 life cycle을 가진다. “객체생성 → 의존관계 주입?” 의존관계 주입까지 마쳐야 스프링 빈을 사용할 준비가 완료 된 것이다. 따라서 초기화 작업도 의존관계 주입이 끝난 이후에 진행해야 하는데, 이를 개발자가 어떻게 알 수 있을까? 스프링은 의존관계 주입이 완료되면 스프링 빈에게 콜백 메서드를 통해서 초기화 시점을 알려주는 다양한 기능을 제공한다. 또한, 스프링은 스프링 컨테이너가 종료되기 직전에 스프링 빈에게 소멸 콜백을 준다. “스프링 이벤트 Life Cycle” 스프링 컨테이너 생성 → 스프링 빈 생성 → 의존관계 주입 → 초기화 콜백 → 사용 → 소멸 전 콜백 → 스프링 종료 스프링은 크게 3가지 방법으로 빈 Life Cycle 콜백을 지원한다. 인터페이스(bean ..

JAVA - Void와 void의 차이?

개요 요즘 회사에서 신규 게임 개발하는데에 모든 시간을 쏟고 있다. 그러다 Void을 사용하는 메소드를 보았고, 이에 대해 void와의 차이를 알아보았다. 자바에서 Void와 void는 둘 다 키워드이지만 약간 다른 의미를 가진다. 이번 글에서는 이 두 키워드의 차이점을 자세히 살펴보자 Void vs void Void는 자바에서 기본 데이터 타입 중 하나인 void를 래핑한 래퍼 클래스이다. 이 클래스는 반환값이 없는 메서드를 나타내는 데 사용된다. 자바에서는 메서드의 반환 유형(return type)을 지정해줘야 한다. 반환 유형은 메서드가 반환하는 값의 데이터 타입을 나타낸다. 예를 들어, 정수형 값을 반환하는 메서드는 반환 유형으로 "int"를 지정한다. 하지만 반환값이 없는 메서드를 정의할 때는 ..

스프링 핵심 원리이해 - 객체 지향 설계 (1)

컴공에 입문하거나, 혹은 프로그래밍을 한다면 객체 지향 설계에 대해 안들어 볼 수가 없다. 또, 현재 대한민국은 자바공화국이라 불릴만큼 자바를 많이 사용하고, 스프링 프레임워크를 같이 사용하고 있다. 스프링의 핵심 스프링은 자바 언어 기반의 프레임 워크 자바는 객체 지향 언어 스프링은 객체 지향 언어가 가장 강력한 특징을 살려내는 프레임워크 스프링은 좋은 객체 지향 애플리케이션을 개발 할 수 있게 도와주는 프레임워크 -> 그렇다면 좋은 객체 지향이란 무엇일까? 좋은 객체 지향 객체 지향 프로그래밍은 유연하고 변경이 용이(다형성) 하게 만들기 때문에 대규모 SW개발에 많이 사용된다. SRP 단일 책임 원칙 한 클래스는 하나의 책임만 가져야 한다. 중요한 기준은 변경이다. 변경이 있을 때 파급 효과가 적으면..

스프링 핵심 원리이해 - 객체 지향 설계 (2)

새로운 정책 개발 다형성 활용을 잘한 코드라면 새로운 정책을 추가하는데 아무 문제 없음 하지만 새로운 정책 적용에 문제가 있음 클라이언트 코드인 주문 서비스 구현체도 함께 변경필요 클라이언트가 인터페이스뿐만아니라 구현체도 함께 의존 → DIP 위반 관심사의 분리 AppConfig는 구현 객체를 생성하고 연결하는 책임 AppConfig의 등장으로 기존의 클라이언트 코드에서 구현체를 생성할 필요가 없어짐 결과적으로 클라이언트 객체는 자신의 역할을 실행하는 것만 집중, 권한이 줄어듬(책임이 명확해짐) AppConfig 리팩토링 구성 정보에서 역할과 구현을 명확하게 분리 역할이 잘 들어남 중복 제거 기존코드 public class OrderServiceImpl implements OrderService { //..

728x90