자바 메모리 구조와 static

최주영·2023년 3월 27일
0

자바

목록 보기
19/30

✅ 자바 메모리 구조

자바 처음에 실행시 클래스 정보를 읽음
읽은 정보들을 메서드 영역에 올림

  • 메서드영역 (static 영역) : 프로그램을 실행하는데 필요한 공통 데이터를 관리하며
    이 영역은 프로그램의 모든 영역에서 공유함
    이 영역에는 클래스 정보, static 영역, 상수 풀 영역으로 나뉨
    프로그램 실행 시점에 만들어지고, 프로그램 종료 시점에 제거된다
    ex) 클래스 변수
  1. 클래스 정보 : 클래스의 실행 코드, 필드, 메서드와 생성자 코드 등 모든 실행 코드가 존재
  2. static 영역 : static 변수들을 보관
  3. 상수 풀 : 공통 리터럴 상수 보관
  • 스택 영역 : 실제 프로그램이 실행되는 영역으로 메서드를 실행할 때 마다 하나씩 쌓임
    자바 실행시, 하나의 실행 스택이 생성되며, 각 스택 프레임은 지역변수(매개변수), 중간연산결과, 메서드 호출 정보 등을 포함한다
    ex) 지역변수(매개변수 포함)

  • 힙 영역 : 객체(인스턴스)배열이 생성되는 영역으로 new 명령어를 사용하면 이 영역을 사용
    힙 영역에는 가비지 컬렉션(GC) 이루어지는 주요 영역임
    ex) 인스턴스 변수


static

(1) : 클래스 변수라고 부름
(2) : static 예약어를 사용한 필드는 클래스를 생성(new)하지 않고 사용할 수 있는 공간
(3) : 객체 생성 없이 공용으로 사용하는 공간 = 프로젝트 내에서 공용으로 사용하는 저장공간
(4) : 선언된 클래스명을 이용해서 접근해야함 ex) 클래스이름.필드
(5) : 공용공간이라, 어떤힙, 어떤 스택이든 불러서 사용가능
(6) : 다른클래스는 new로 생성해야 이용할 수 있지만, static 클래스는 프로그램이 시작되면 이용하는 공간
(7) : static으로 선언된 필드, 메소드도 접근제한자의 영향을 받는다

✅ 멤버 변수(필드)의 종류

public class Data{
	public String name;
    public static int count;
    
    public Data(String name){
    	this.name = name;
        count++;
    }
}
  • 인스턴스 변수 : static 이 붙지 않는 멤버 변수 ex) name
    -> static 이 붙지 않는 멤버 변수는 인스턴스를 생성해야 사용할 수 있고, 인스턴스에 소속
    -> 인스턴스를 만들때마다 새로 만들어진다
  • 클래스 변수 : static이 붙은 멤버 변수 ex) count
    -> 클래스 변수, 정적 변수, static 변수 등으로 모두 불림
    -> static이 붙은 멤버변수는 인스턴스와 무관하게 클래스에 바로 접근해서 사용 가능
    -> 클래스 자체에 소속되어 있어서 클래스 변수라 불림
    -> 클래스 변수는 자바 프로그램을 시작할 때 딱 1개가 만들어짐
    -> 인스턴스와 다르게 여러곳에서 공유하는 목적으로 사용됨
	// 메인문에서 클래스 3개 생성
    Data data1 = new Data("A");
    System.out.println(Data.count); // 1 출력
    Data data1 = new Data("B");
    System.out.println(Data.count); // 2 출력
    Data data1 = new Data("C");
    System.out.println(Data.count); // 3 출력

💡 인스턴스를 통한 접근 vs 클래스를 통한 접근

Data data = new Data("데이터");
System.out.println(data.count); // 인스턴스를 통한 접근
System.out.println(Data.count); // 클래스 통한 접근

클래스를 통한 접근을 사용하자!


static 메서드

  • 정적 메서드, 클래스 메서드라고 불림
  • static이 붙은 정적메소드는 객체 생성없이 해당 멤버변수를 호출할 수 있음
  • 클래스명.메소드명 으로 호출 가능
  • 저장공간 클래스 소속임
public class DecoClass{
	public static String decoMethod(String str){ // static 메서드 생성
    	String result = "*" + str + "*";
        return result;
    }
}
String s = "hello";
String deco = DecoClass.decoMethod(s); // static 메서드 호출은 객체 생성없이 바로 호출 가능

💡 인스턴스 메서드 -> static 이 붙지 않은 메서드로, 인스턴스를 생성해야 호출 가능

  • 정적 메서드는 static 이 붙은 정적 메서드나 정적 변수만 사용할 수 있다.
  • 정적 메서드는 인스턴스 변수나, 인스턴스 메서드를 사용할 수 없다.
  • 정적 메서드는 공용 기능이다. 따라서 접근 제어자만 허락한다면 클래스를 통해 모든 곳에서 static 을 호출할 수 있다

  • static이 붙은 메소드는 static 붙은 필드나 메서드만 접근 가능하며, 인스턴스는 접근 불가능
    -> 인스턴스 필드나 메소드가 생기려면 객체를 생성해야함
    -> 그러면 해당 객체의 참조값을 알아야함
    -> 하지만 static 메소드는 객체를 생성하지 않고 클래스명. 으로 접근함
    -> 참조값을 모르기때문에 컴파일 오류 발생
public class DecoData {
   private int instanceValue;
   private static int staticValue;
  
   public static void staticCall() {
       //instanceValue++; //인스턴스 변수 접근, compile error
       //instanceMethod(); //인스턴스 메서드 접근, compile error

       staticValue++; //정적 변수 접근
       staticMethod(); //정적 메서드 접근
       // static은 static만 접근 가능	
   }

   public void instanceCall() {
       instanceValue++; //인스턴스 변수 접근
       instanceMethod(); //인스턴스 메서드 접근
       staticValue++; //정적 변수 접근
       staticMethod(); //정적 메서드 접근
   }

   private void instanceMethod() {
       System.out.println("instanceValue=" + instanceValue);
   }

   private static void staticMethod() {
       System.out.println("staticValue=" + staticValue);
    }
}
  • static 메소드를 접근하려면 인스턴스를 통한 접근보다는 클래스를 통한 접근을 해야한다!
DecoData data = new DecoData();
// 인스턴스를 통한 접근
data.staticCall(); // 오류는 나지 않지만 메서드가 인스턴스 소속인 것 같기때문에 비추천

// 클래스를 통한 접근
DecoData.staticCall(); // static 메서드를 접근할 때에는 클래스를 통해서 접근하는게 좋음

✅ static import 사용

  • 자주 사용하는 static 메소드 또는 정적변수 존재시 사용함
  • import static 패키지명.클래스명.사용할 static 메소드
  • 클래스명을 적지 않고 메소드 사용 가능
// import static 패키지명.클래스명.사용할 static 메소드
// import static static2.DecoData.staticCall;

staticCall(); // 클래스명 생략 가능
profile
우측 상단 햇님모양 클릭하셔서 무조건 야간모드로 봐주세요!!

0개의 댓글