나를 기록하다
article thumbnail
반응형

private static 메서드

우아한테크코스 1주차 프리코스 과제인 숫자 야구 게임이 끝나고 코드 리뷰를 하면서 private static 메서드를 발견했다.

접근 제한자부터 static과 메모리 구조까지 기초 개념들을 다시 확실하게 정리하고자 여러 블로그와 자료를 참고하여 정리한다.

참고한 자료들은 하단 참고자료란에 모두 기재해두었다.


접근 제한자

우선 접근 제한자의 종류는 다음과 같다.

접근 제한자 적용 대상 접근 가능 대상
public 클래스 / 필드 / 생성자 / 메서드 모든 대상
protected 필드 / 생성자 / 메서드 같은 패키지 또는 자식 클래스
default 클래스 / 필드 / 생성자 / 메서드 같은 패키지에 소속된 클래스
private 필드 / 생성자 / 메서드 클래스 내부

Static 키워드

사전적 정의

정적인, 고정된


자바에서의 Static

Static 키워드를 사용한다는 것은 메모리에 한 번 할당되어 프로그램이 종료될 때 해제되는 것을 의미한다.

Static 메모리

참고: 망나니 개발자님의 블로그

  • 일반적으로 생성한 Class - Static 영역에 생성
  • new 연산을 통해 생성한 객체 - Heap 영역에 생성

객체 생성 시 할당된 Heap 영역의 메모리는?

GC(Garbage Collector)를 통해 수시로 관리받는다.

Static 키워드를 통해 Static 영역에 할당된 메모리는?

  • 장점 - 모든 객체가 공유하는 메모리
  • 단점 - GC의 관리 영역 밖에 존재 → 프로그램을 종료할 때까지 메모리가 할당된 채로 존재 → 자주 사용 시 시스템의 성능에 악영향

Static 변수의 특징

  • Static 변수는 클래스 변수이다.
  • 객체를 생성하지 않고도 Static 자원에 접근 가능

Static 변수와 static 메서드는 Static 메모리 영역에 존재하므로 객체가 생성되기 이전에 이미 할당되어 있다. 따라서 객체의 생성없이 바로 접근하여 사용할 수 있다.

public Class Calculator {
    public static String calculatorName = "PraoCalculator";

    public static int plus(int x, int y) {
        return x + y;
    }

    public int minus(int x, int y) {
        return x - y;
    }
}

Calculator.plus(5, 4); // static 메서드이므로 객체 생성없이 사용 가능
Calculator.minus(3, 2); // 에러. static 메서드가 아니므로 객체 생성 후 사용 가능

Calculator praoCal = new Calculator(); // 객체 생성
praoCal.plus(7, 6); // 가능. but 권장되지 않음
praoCal.minus(5, 4); // 객체를 생성하였으므로 사용 가능

Static 변수(정적 변수)

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

Java에서 Static 변수란?

  • 메모리에 한 번 할당되어 프로그램이 종료될 때 해제되는 변수
  • 메모리에 한 번 할당되므로 여러 객체가 해당 메모리를 공유

[예시] 세상의 모든 자동차의 이름이 Ferrari라고 가정

public class Car {
    private String name = "Ferrari";

    public void printName() {
        System.out.println(this.name);
    }
}

위 코드의 문제점은?

  • 10000개의 Car 객체를 생성하면, "Ferrari"라는 같은 값을 갖는 메모리가 10000개 중복해서 생성
    → 이러한 경우 static을 사용해서 여러 객체가 하나의 메모리를 참조하도록 하면 메모리 효율이 높아진다.
  • "Ferrari"라는 이름은 결코 변하지 않는 값 → final 키워드를 붙여준다.
  • 일반적으로 Static은 상수의 값을 갖는 경우가 많다 → public을 선언하여 사용한다.

위와 같은 이유로 일반적으로 static 변수는 publicfinal과 함께 사용되어 public static final(상수)로 활용된다.


Static 메서드(정적 메서드)

특징

  • Static method는 객체의 생성없이 호출 가능
  • 객체에서는 호출이 가능은 하지만 지양할 것
  • 유틸리티 관련 함수들은 여러 번 사용된다 → static 메서드로 구현하는 것이 적합
  • Util Class의 대표적인 예시 - java.util.Math

[예시] java.util.Math

public class MathTest {
    private String name1 = "Prao";
    private static String name2 = "Prao";

    public static void printMaxValue(int x, int y) {
        System.out.println(Math.max(x, y));
    }

    public static void printName() {
        //  System.out.println(name1); // 에러 발생. 불가능한 호출
        System.out.println(name2);
    }
}
  • 두 수의 최댓값을 구하는 경우 Math 클래스의 static 메서드로 선언된 max 함수를 초기화 없이 사용
    → 하지만 static 메서드에서는 static이 선언되지 않은 변수에 접근이 불가능하다
    메모리 할당과 연관지어 생각하면 당연

static 메서드에서 static이 선언되지 않은 변수에 접근하지 못하는 이유

  1. MathTest.printName()을 사용하려 할 때 name1new 연산을 통해 객체가 생성된 후에 메모리가 할당된다.
  2. 하지만 static 메서드는 객체의 생성없이 접근하는 함수이다.
  3. 따라서 할당되지 않은 메모리 영역에 접근을 하므로 여기서 문제가 발생한다.
static 메서드에 접근하기 위한 변수는 반드시 static 변수로 선언되어야 한다.

실제 Static 변수와 Static 메서드의 활용

Static 변수

  • 일반적으로 상수들만 모아서 사용
  • 상수의 변수명은 알파벳 대문자_를 조합해서 사용
  • 상속을 방지하기 위해 final class로 선언

[예시] 숫자 야구 게임에서 재시작 또는 종료에 해당하는 상수 값 클래스

public final class GameCommand {
    public static final String RETRY_GAME = "1";
    public static final String EXIT_GAME = "2";
}

Static 메서드

  • 상속을 방지하기 위해 final class로 선언
  • 유틸 관련 함수들을 모아둔다

[예시] 숫자 야구 게임에서 정수형 숫자를 정수형 배열로 변환 역할을 수행하는 컨버터

public class Converter {
    private static final String INT_SEPARATOR = "";

    private Converter() {}

    public static List<Integer> convertIntToList(int number) {
        return Arrays.stream(String.valueOf(number).split(INT_SEPARATOR))
                .map(Integer::parseInt)
                .toList();
    }
}

그래서 언제 private static이 필요할까?

[예시] 학생 클래스

public class Student {
    String name;

    public Student(String name) {
        this.name = name;
    }

    public void study() {
        // TODO 수학 공부
        // TODO 국어 공부
    }

    private void studyMath() {
        // TODO 수학 문제집을 펼친다
        // TODO 수학 문제를 푼다
        // TODO 수학 책을 접는다
    }

    private void studyKorean() {
        // TODO 국어 책을 편다
        // TODO 국어 지문을 읽는다
        // TODO 국어 책을 접는다
    }
}

분석

  • study()public 접근자를 가진다 → 다른 클래스 파일에서도 사용이 가능하다
  • study() 구현부의 수학 공부와 국어 공부 → Student 클래스 내에서만 사용이 가능하다
    private method로 선언한다

private static은?

  • study()static 함수라면 studyMath()studyKorean()static이어야 한다 → private static을 사용하는 것 뿐이다.
public class Student {
    String name;

    public Student(String name) {
        this.name = name;
    }

    public static void study() {
        // TODO 수학 공부
        // TODO 국어 공부
    }

    private static void studyMath() {
        // TODO 수학 문제집을 펼친다
        // TODO 수학 문제를 푼다
        // TODO 수학 책을 접는다
    }

    private static void studyKorean() {
        // TODO 국어 책을 편다
        // TODO 국어 지문을 읽는다
        // TODO 국어 책을 접는다
    }
}

 

결론
하위 private를 포함하는 상위 메서드가 static으로 선언되었다면,
static 메서드에서 호출하는 하위 메서드 또한 static으로 선언되어야 한다.

참고자료

https://wooooooak.github.io/java/2019/01/06/private_static%EC%9D%B4_%ED%95%84%EC%9A%94%ED%95%9C_%EA%B2%BD%EC%9A%B0/

 

private static이 필요한 경우 · 쾌락코딩

private static이 필요한 경우 06 Jan 2019 | basic java scope 자바를 공부하다 보면 가끔 private static을 볼 수 있다. 공부 초창기를 떠올려보면 접근 제한자인 public, protected, private들도 헷갈렸는데 static까지

wooooooak.github.io

https://wikidocs.net/228

 

07-03 스태틱

스태틱(static)은 클래스에서 공유되는 변수나 메서드를 정의할 때 사용된다. 이번 절에서는 스태틱에 대해서 자세히 알아보자. [TOC] ## static 변수 다음과 …

wikidocs.net

https://coding-factory.tistory.com/524

 

[Java] 자바 static의 의미와 사용법

정적(Static)이란? 정적(static)은 고정된이란 의미를 가지고 있습니다. Static이라는 키워드를 사용하여 Static변수와 Static메소드를 만들 수 있는데 다른말로 정적필드와 정적 메소드라고도 하며 이

coding-factory.tistory.com

https://mangkyu.tistory.com/47

 

[Java] static변수와 static 메소드

1. Static 정리 Java에서 Static 키워드를 사용한다는 것은 메모리에 한번 할당되어 프로그램이 종료될 때 해제되는 것을 의미합니다. 이를 정확히 이해하기 위해서는 메모리 영역에 대한 이해가 필

mangkyu.tistory.com

 

반응형
profile

나를 기록하다

@prao

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...