본문 바로가기
Programming/Java

Static

by lucid_07 2023. 10. 17.
반응형

 

코드를 작성하다 (바보같이) 간과하고 넘어갔던 부분에 대해 궁금증이 생겨서 조금씩 공부해보기로 했다.

 

of 메서드를 static으로 사용하는 이유는?

둘 다 비슷한 용도로 사용하는데, toEntity 메서드와 달리 of 메서드는 static으로 되어 있다.

@Getter @Builder
@ToString
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor
public class RoadmapViewportDto {
    private BigDecimal x;
    private BigDecimal y;
    private BigDecimal zoom;
    
    public RoadmapViewport toEntity() {
        return RoadmapViewport.builder()
                .x(this.x)
                .y(this.y)
                .zoom(this.zoom)
                .build();
    }
    
    public static RoadmapViewportDto of(RoadmapViewport roadmapViewport) {
        return RoadmapViewportDto.builder()
                .x(roadmapViewport.getX())
                .y(roadmapViewport.getY())
                .zoom(roadmapViewport.getZoom())
                .build();
    }
}

of 메서드를 static으로 사용하는 이유는 다음과 같습니다:

  1. 객체의 독립성 보장: static 메서드는 클래스에서 생성된 객체의 데이터에 영향을 받지 않고 동일하게 동작합니다. 따라서, of 메서드를 static으로 선언하면, 모든 객체가 클래스에 정의된 방법대로만 사용하게 됩니다1.
  2. 인스턴스 생성 없이 호출 가능: static 메서드는 인스턴스 생성 없이 클래스로 호출할 수 있습니다. 이는 메서드 호출을 더욱 간편하게 만듭니다2.
  3. 메모리 효율성: static으로 선언된 메서드는 자바가 컴파일되는 시점에 메모리에 로드되며, 프로그램이 종료될 때까지 유지됩니다. 이로 인해 메모리 사용이 효율적입니다3.

위의 코드에서 of 메서드는 RoadmapViewport 객체를 입력으로 받아, 해당 객체의 데이터를 바탕으로 새로운 RoadmapViewportDto 객체를 생성하고 반환합니다. 이렇게 static으로 선언된 of 메서드를 통해, 우리는 인스턴스 생성 없이도 쉽게 RoadmapViewportDto 객체를 생성할 수 있습니다.

- Generated By Bing AI, 2023/10/17


 

그럼 자바에서 static에 대해 좀 더 알아봅시다

 

Static : 메모리 영역에서

출처: Mangkyu님 블로그

메모리에서 static은, 메모리에 할당되어 프로그램이 종료될 때 해제된다. 이전에 살펴보았듯이, 메모리 영역에 데이터를 저장할 때에는 stack과 heap, static 등 으로 나누어 데이터를 저장한다.

Java에서는 Class를 static 영역에, new 연산을 통해 생성한 객체는 heap 영역에 생성된다. Heap 영역의 메모리는 GC가 관리해 주지만, static영역에 할당한 class의 경우 모든 객체가 공유하지만 프로그램이 종료될 때까지 static 메모리에 할당된 채 있으므로 자주 사용하면 퍼포먼스에 악영향을 준다.

Static 메서드와 변수는 인스턴스가 생성되기 전에 이미 메모리에 할당되어 있으므로 객체 생성 없이 바로 사용할 수 있다는 특징이 있다.

상속을 방지하기 위해 메서드, 필드 모두 final 로 선언해 주는 경우가 많다.

 

Static 변수

메모리에 고정적으로 할당되어 프로그램이 종료될 때 해제되는 변수

 

Static 메서드

클래스와 인스턴스가 공유하는 메서드. Static 변수와 마찬가지로 인스턴스가 생성되기 전에 메모리에 할당되어 있다.

 

※ static 메서드 내에서는 인스턴스 변수를 사용할 수 없다. Static 메서드는 객체 생성없이 프로그램이 시작될 때 메모리에 로드되는데, name1 변수는 new 연산을 통해 객체가 생성되므로 할당되지 않은 영역에 접근할 수 없기 때문이다.

public class Test {
    private String name1 = "abc";
    private static String name2 = "abc";
 
    public static void printMax(int x, int y) {
        System.out.println(Math.max(x, y));
    }
         
    public static void printName(){
       // System.out.println(name1); 불가능한 호출
       System.out.println(name2);
    }
}

 

예시 코드

import java.text.SimpleDateFormat;
import java.util.Date;
import android.util.Patterns;
 
public final class CommonUtils {
 
    public static String getCurrentDate() {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd");
        return dateFormat.format(date);
    }
     
    public static boolean isEmailValid(String email) {
        return Patterns.EMAIL_ADDRESS.matcher(email).matches();
    }
     
}

메서드는 프로그램이 실행될 때 메모리에 이미 로드되어 있지만, 그 안의 필드 객체들은 getCurrentDate() 메서드가 실행될 때에만  heap에 생성된다.

 

Static을 사용하는 이유와 주의사항

 

static을 사용하면

  1. 객체를 사용하지 않아 메모리와 처리 시간을 단축할 수 있다.
  2. 다른 클래스에서 접근 가능: 코드 모듈성과 유연성을 늘릴 수 있다.
  3. 인스턴스 상태에 의존하지 않고 독립적임을 짐작할 수 있다: 인스턴스 변수를 사용할 수 없고 매개변수만 사용하므로.

 

하지만

  1. 오버라이딩이 불가하여 상속 관계 사용시 사용이 불가할 수 있다.
  2. 메모리 소비: 프로그램이 실행되는 동안에는 계속 메모리에 상주하기 때문에 과도한 사용은 메모리 소모를 증가시킨다.
  3. 멀티 스레딩: 데이터 일관성 문제가 발생할 수 있어 동기화 기능이 꼭 필요하다.
  4. 객체 지향 설계 방해: 객체 간 상호작용보다 클래스간 상호작용이 많아지면 코드의 유지보수가 어려워진다.
  5. 모든 인스턴스에서 공유되므로 하나의 테스트케이스에서 변경된 static값이 다른 테스트케이스에 영향을 줄 수 있어 테스트가 까다로워진다.

 

참조

https://mangkyu.tistory.com/47

JVM Memory Structure | devkuma

남궁성의 자바

반응형

'Programming > Java' 카테고리의 다른 글

반복문의 라벨  (0) 2023.11.22
Java의 Switch: 14 이후 추가된 기능  (2) 2023.11.22
Java의 char  (2) 2023.11.21
01 | 기본 문법 | 변수와 리터럴  (0) 2023.10.04
00 | Java의 동작: Hello.java  (0) 2023.10.04