728x90
SMALL

프로젝트 중 상사가 리팩토링한 코드 중에서 immutableMap 을 사용한 부분이 있었다. 

몇가지 지정된 객체들을 특정 메소드에 파라미터로 보내는 과정에서 해당 맵을 사용했는데 

처음 보는 맵의 종류라 정리하게 되었다. 


ImmutableMap 이란?

Map 의 종류이지만 이 맵은 한 번 만들어지면 그 안의 키와 값이 변경될 수 없는 특징이 있다.

즉, 이미 지정해둔 키와 값의 쌍을 수정하거나 삭제할 수 없으며, 새로운 키-값 쌍을 추가할 수도 없다.


⭐예제

/**첫번째 방법*/
ImmutableMap<String, Object> map = ImmutableMap.of("bean", _bean, "regDt", _bean.getRegDt());
         
/**두번째 방법*/        
ImmutableMap<String, Object> map2 = ImmutableMap.<String,Object>builder()
                                    .put("bean", _bean)
                                    .put("regDt", _bean.getRegDt())
                                    .build();

ImmutableMap 도 map 의 종류이기에 선언이나 사용법은 비슷하나, 위에 두가지로 가장 많이 쓰인다. 

1. 첫번째 방법 : 최대 10쌍의 값을 정의할 수 있어 간단하게 정의할 경우 쓰인가.

2. 두번째 방법 : 더 많은 쌍의 값을 정의할때 더 유연하고 가독성이 좋기에 많은 쌍을 정의할 때 쓰인다. 


⭐일반 Map 과의 차이점

 

  • 수정 불가: ImmutableMap는 한 번 생성되면 수정할 수 없다. put, remove 등의 메서드 사용 불가능
  • 생성 시점: ImmutableMap는 생성할 때 모든 키-값 쌍을 정의해야함.

 

/**맵 정의*/
ImmutableMap<String, Object> map = ImmutableMap.of("bean", _bean, "regDt", _bean.getRegDt());

/**수정 및 삭제 불가 */
// map.put("regDt", "2025-01-01"); // 컴파일 에러
// map.remove("bean"); // 컴파일 에러

⭐ImmutableMap 사용이유 

 

  • 안전성: 불변이기 때문에 데이터가 변경될 염려가 없다. 특히 여러 군데에서 같은 데이터를 참조할 때 유용하다.
  • 성능: 동기화가 필요 없기 때문에, 여러 스레드가 동시에 읽을 때 성능이 향상된다.
  • 예측 가능성: 데이터가 변경되지 않기 때문에 항상 같은 값을 유지한다. 

중요한 점

  • 맵 자체는 변경 불가: ImmutableMap에 추가, 수정, 삭제할 수 없습니다.
  • 내부 객체는 변경 가능: ImmutableMap에 저장된 객체가 가변 객체라면, 그 객체의 내부 상태는 변경될 수 있습니다.

 

 

728x90
반응형
LIST
728x90
SMALL

프로젝트에서 코드를 리팩토링 하는 과정에서 

같은 연산을 하지만은 상속받는 bean 이 다른 두개의 메소드가 있었다. 

물론 다른 패키지 내부의 dao 에서 연산을 하는 것이라 별다른 리팩토링 필요성을 못느꼈는데 

같은 연산을 두 패키지 뿐만 아니라 다른 곳에서도 쓰일 가능성을 보고 Util로 옮기며 intanceof 연산자를 사용하게 되었다. 


intanceof 연산자란? 

사용하는 이유 : 개체가 어떤 클래스인지, 어떤 클래스를 상속받았는지, 즉 인스턴스의 실제 타입을 알아보기 위해 사용

결과 : boolean (true 또는 false) 

⭐문법

object instanceOf type

object 가 내가 확인하고 싶은 객체이고 type이 비교 대상이다. 

object == type 또는 type을 상속받는 다면 true, 아닐경우 false 를 반환한다. 


⭐예제

class Parent{}

class Child extends Parent{}

public class intanceOfExample {
    public static void main(String[] args){
        Parent parent = new Parent();
        Child child = new Child();

        System.out.println( parent instanceof Parent );  // true
        System.out.println( child instanceof Parent );   // true
        System.out.println( parent instanceof Child );   // false
        System.out.println( child instanceof Child );   // true
    }
}

child 는 부모님 parent 를 상속받기에 true 이지만, parent는 child를 상속받지 않기에 false 가 나온다. 

물론 child끼리 parent 끼리 instanceof 연산자로 확인할 경우에는 같은 클래스이기에 true 가 나온다. 


이 처럼 한 메소드에서 혹 특정 bean 을 특정지어서 분기처리를 해야한다면 유용하게 쓰일 수 있는 연산자같다. 

728x90
반응형
LIST
728x90
SMALL

리눅스 서버에서 

java.lang.NoClassDefFoundError: Could not initialize class java.awt.GraphicsEnvironment$LocalGE

이러한 에러가 났다. 

 

찾다보니 JAVA_OPTS에 설정값이 누락되어서 일어난 에러였다. 

설정값은 두가지 방법으로 추가할 수 있다. 

 

1. 자바 코드에서 추가하는 경우 

서버 기동시 실행되는 클래스에 추가하는 방법

System.setProperty("java.awt.headless", "true")

(기동될때 실행되는 클래스들은 web.xml 에서 listener, filter 등 등록되어있는 class 들에 해당) 

 

2. 서버(tomcat)에 직접 추가하는 경우 

보통 ssh 에서 apache-tomcat-8.5.9/bin (tomcat 경로는 설정마다 다름) 에 catalina.sh 가 실행되면서 tomcat 이 올라가는 건데 보통 옵션들은 catalina.sh 에 추가해도 무방하지만 setenv.sh 에 추가하는 것이 났다. 

기본적으로 catalina.sh 에는 setenv.sh 파일을 읽을 수 있도록 설정되어 있기 때문에 만약 bin 폴더 안에 setenv.sh 가 없다면 만들고 그 안에 아래와 같은 옵션값을 추가하면 된다.

export JAVA_OPTS="-Djava.awt.headless=true"

 

 


<참고>

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=rutee9&logNo=130109088347

https://recordsoflife.tistory.com/1266

—JVM 옵션 관련

https://nesoy.github.io/articles/2019-08/JVM-Options

728x90
반응형
LIST

+ Recent posts