자바의 메모리 구조는 크게 3가지로 나눌 수 있다.
: 자바가 실행되면 가장 먼저 실행되고, 자바 종료까지 계속 유지된다. (해당 클래스가 JVM에 로딩 되는 순간 생성됨)
-> 프로그램의 모든 영역에서 공유하게 된다.
: 자바를 실행하면 하나의 실행 스택 프레임 생성 / 메서드를 호출할 때마다 하나의 스택 프레임이 쌓이고, 메서드가 종료되면 그 스택 프레임이 없어진다.
-지역 변수, 중간 연산 결과, 메서드 호출 정보 등을 포함함.
➡️ 프로그램 실행 & 메서드 호출
: 객체(인스턴스)의 배열이 생성되는 구역
+가비지 컬랙션이 이루어지기도 한다!
static은 주로 멤버변수/메소드 에 쓰인다.
간단한 수를 증가시키는 예제를 통해서 왜 static 변수가 필요한지 알아보자!
//Data
public class Data {
public int count;
public Data1(String name){
count++;
}
}
//DataMain
public class DataMain{
Data data1 = new Data();
System.out.println(data1.count);
Data data2 = new Data();
System.out.println(data2.count);
}
실행하면 아마도 1, 2가 출력될거라고 생각할 것이다.
하지만 결과는 1, 1이다!
객체를 생성(
new Data())할때마다 Data 인스턴스는 새로 만들어지기때문이다!!
→ 이때 인스턴스에 포함된 count 변수도 새로 만들어진다.
만약 이 count 변수를 객체를 생성할때마다 갱신하는게 아니라, 계속해서 유지하고 싶다면 어떻게 해야할까?
=> 특정한 클래스에 공용으로 사용할 수 있는 변수를 만들면 된다! => static
아까 Data 클래스를 static을 활용해서 조금 바꿔보자
//Data
public class Data {
public static int count;
public Data1(String name){
count++;
}
}
int 앞에 static을 붙여주었다.
이렇게 멤버 변수에 static을 붙이면 이는 static변수 (=정적 변수, 클래스변수)라고 한다.
그럼 위의 DataMain 클래스도 바꿔보자.
//DataMain
public class DataMain{
Data data1 = new Data();
System.out.println(Data.count);
Data data2 = new Data();
System.out.println(Data.count);
}
실행결과 : 1, 2
count변수에 접근할 때, 클래스명(Data)에 .을 찍어서 클래스에 접근하는 것처럼 보인다.
이렇게하면 공용변수를 사용하게 되는 것이다.
static 변수는 클래스인 붕어빵틀!이 직접 관리해주는 변수이다.
붕어빵은 여러개지만, 이를 찍어내는 틀은 1개니까 클래스 변수도 딱 하나만 존재할 수 있기 때문!
정적(static) 함수로 활용해보자.
원래 클래스에 있는 메서드를 가져오려면 아래처럼 정의해준 후 가져와서 쓸 수 있었는데
ClassMethod class1 = new ClassMethod();
class1.methodName();
정적 함수를 사용하면 객체를 생성하지 않고, 클래스의 메서드를 바로 호출해버릴수있는 장점이 있다!
ClassMethod.methodName();
static메서드는static이 붙은 메서드나 변수만 사용할 수 있다.- 다른 모든 곳에서는
static을 호출할 수 있다.
아래 코드로 한 번 보자
public class UseStatic {
private int instanceValue;
private static int staticValue;
public static void staticCall(){
//static 메서드는 인스턴스 변수, 메서드는 접근 불가능
// instanceValue++;
// instanceMethod();
//static 메서드는 static 변수, static 메소드만 접근 가능
staticValue++;
staticMethod();
}
//인스턴스 메서드에서는 다 불러오기 SSAP 가능
public void instanceCall() {
instanceValue++;
instanceMethod();
staticValue++; //static변수는 어디서든 접근 가능
staticMethod();
}
//인스턴스 메서드
private void instanceMethod(){
System.out.println("instance Value : "+instanceValue);
}
//staitc 메서드
private static void staticMethod(){
System.out.println("static value : "+ staticValue);
}
}
여러 번 같은 method를 쓰려고 클래스이름.정적메소드이름 이렇게 쓰기 귀찮을 수 있다.
이럴 때 사용할 수 있는 방법이 바로 import이다.
//1. 원하는 메서드만 미리 불러와놓기
import static static.클래스이름.메서드이름;
//2. 해당 클래스의 모든 static 메서드 다 가져오기
import static static.클래스이름.*;
이렇게하면 클래스이름을 굳이 써줄 필요 없이, 바로 메서드 이름만 써서 활용 가능하다.
className.staticMethod() → staticMethod()