Static에 대해 알아보자

안녕하세요 델리만쥬입니다~!

프로그래밍을 할수록, 기본이 얼마나 중요한지 느끼고 있습니다.
static에 대한 예약어를 보다가 순간 static이 정확히 뭐였지? 라는 생각이 들어서 
정리해보자 합니다.

프로그래밍은 정말 기본이 탄탄해야 한다고 느끼는 요즘입니다^^..

Static의 특징
  • 프로그램이 종료되지 않는 한 메모리가 소멸되지 않는다.
  • 특별히 초기값을을 지정하지 않아도 자동으로 0을 가진다
  • 초기화는 딱 한번만 수행된다
  • static은 변수나 메소드에 예약어로 사용
  • static을 사용한 변수나 메소드는 클래스가 메모리에 로딩될때 자동으로 생성
  • 객체의 생성없이 바로 사용이 가능 -> 편리하고 속도가 빠르다
static 키워드를 사용하는 이유는 무엇일까요?
  • 공통적으로 쓰여지는 변수 또는 메소드에 대해 매번 메모리에 로딩하는 것보다
    전역변수처럼 쓰여지게 하여 효율성을 높인다
  • 객체의 생성없이 바로 사용가능하여 프로그램내에서 공통으로 사용되는 데이터들을 관리할때 이용할수 있다

공통으로 사용되는 변수에 대해 예제 코드를 보겠습니다

public class CommonStatic {
    static String carName = "람보르기니";
    
    public static void main(String[] args) {
        CommonStatic user1 = new CommonStatic();
        CommonStatic user2 = new CommonStatic();
        
        System.out.println("user1의 소유 차 : "+user1.carName);
        System.out.println("user2의 소유 차 : "+user1.carName);
        
        user1.carName = "벤틀리"// user1의 소유 차종을 변경
        
        System.out.println("user1의 소유 차 : "+user1.carName);
        System.out.println("user2의 소유 차 : "+user1.carName);
        
    }
}
cs

출력

user1의 소유 차 : 람보르기니
user2의 소유 차 : 람보르기니
user1의 소유 차 : 벤틀리
user2의 소유 차 : 벤틀리

위의 코드에서 CommonStatic 클래스의 carName 변수를 람보르기니로 설정했습니다.

그후 user1, user2라는 객체를 생성하였습니다.

1,2번째 print() 함수를 통해 user1, user2의 차종은 '람보르기니'가 정상적으로 나온것을 확인할수 있습니다.

user1의 차종을 변경하고 싶어서 user1.carName으로 user1의 소유차종을 '벤틀리'로 변경했습니다.

그 후, 3,4번째 print()함수를 통해 결과를 보니 user2의 소유차종까지 '벤틀리'로 변경되었습니다.


user2의 차종까지 변경된 이유는 carName 변수를 static으로 정의해서 user1, user2이 같은 carName 변수를 공유하고 있던 것입니다.

위의 예제를 통해서 확인할 수 있는건 공통적인 데이터가 유지되어야 하는 변수에 대해서만
static을 사용해야 한다는 것을 확인할 수 있습니다.

아래 예제를 통해 static 변수와 instance 변수의 차이를 살펴보겠습니다.

public class CommonStatic {
    public static void main(String[] args) {
        
        CarInfo user1 = new CarInfo();
        user1.carName = "람보르기니";
        
        CarInfo user2 = new CarInfo();
        user2.carName = "벤틀리";
        
        System.out.println("user1의 소유 차 정보");
        System.out.println(user1.carName +" / "+user1.price + " / "+user1.totalKilo);
        System.out.println("user2의 소유 차 정보");
        System.out.println(user2.carName +" / "+user2.price + " / "+user2.totalKilo);
        
        //user1의 소유차종에 대한 정보를 변경
        user1.carName = "페라리";
        user1.price = 2000000;
        user1.totalKilo = 1211;
        
        System.out.println("user1의 소유 차 정보");
        System.out.println(user1.carName +" / "+user1.price + " / "+user1.totalKilo);
        System.out.println("user2의 소유 차 정보");
        System.out.println(user2.carName +" / "+user2.price + " / "+user2.totalKilo);
    }    
}
class CarInfo{
    String carName;
    static long price = 1000000;
    static long totalKilo = 2333;
}
cs

출력

user1의 소유 차 정보
람보르기니 / 1000000 / 2333
user2의 소유 차 정보
벤틀리 / 1000000 / 2333
user1의 소유 차 정보
페라리 / 2000000 / 1211
user2의 소유 차 정보
벤틀리 / 2000000 / 1211

위의 예문을 보면 static 변수가 아닌 carName은 메모리에 별도의 영역이 생겨서 
두 객체에 영향을 미치지 않는다는 것을 확인할 수 있습니다.

이번엔 아래 예제를 통해서 static 함수와 instance 함수의 차이를 살펴보겠습니다.


public class CommonStatic {
    public static void main(String[] args) {
        
        CarInfo user1 = new CarInfo();
        user1.carName = "람보르기니";
        
        System.out.println("instance 함수");
        System.out.println("user1.priceWithDisc() : "+ user1.priceWithDisc());
        
        System.out.println("static 함수");
        System.out.println("user1.staticPriceWithDisc() : "+ user1.staticPriceWithDisc());

System.out.println("static 함수 - argument");
        System.out.println("user1.staticPriceWithDisc() : "+ user1.staticPriceWithDisc(100000, 0.2));
    }    
}
class CarInfo{
    String carName;
    long price = 1000000;
    long totalKilo = 2333;
    double discPer = 0.2;
    
    public double priceWithDisc() {    
        return price * (1-discPer);
    }
    
    public static double staticPriceWithDisc() {    
        return price * (1-discPer);
    }
    public static double staticPriceWithDisc(long price, double discPer) {    
        return price * (1-discPer);
    }
}
cs

출력

instance 함수
user1.priceWithDisc() : 800000.0
static 함수
Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
Cannot make a static reference to the non-static field price
Cannot make a static reference to the non-static field discPer

at CarInfo.staticPriceWithDisc(CommonStatic.java:28)
at CommonStatic.main(CommonStatic.java:13)


CarInfo 클래스에서 인스턴스 변수 price와 discPer을 가지고 
static 함수와 객체를 생성하였습니다.

static이 붙은 함수 staticPriceWithDisc()는 메모리에 이미 생성되어 있습니다.
호출시에 차이를 볼수 있습니다.

instance 함수는 new 예약어를 통해 객체를 생성한 후 함수를 호출할 수 있으나,
static 함수는 클래스 이름만으로도 호출이 가능합니다.

출력 결과에서 에러가 나타내는 것은,
static 함수에서 static 변수가 아닌 것들을 사용해서 나타나는 에러입니다.
아직 객체의 생성이 이루어지지 않아 instance 변수들이 메모리를 할당 받지 못한 상태입니다.

그래서 static함수에서 값을 할당하려면 
public static double staticPriceWithDisc(long price, double discPer) {    
   return price * (1-discPer);
}
cs
위와 같이 argument들을 넘겨주는 형태로 호출되어야 합니다.


위의 예제 코드들을 통해 이번 포스팅에서 static에 대해 알아보았습니다.

1. static이 붙은 변수는 객체(인스턴스)를 생성하지 않아도 사용할 수 있다.

2. static이 붙은 함수는 instance 변수를 사용할수 없다.

3. instance 변수를 필요하지 않는다면, static 변수의 사용을 고려해본다
  • 함수의 호출 시간이 짧아지고 효율성이 높아진다
4. static 변수는 공통된 값을 유지해야할 경우 사용한다.




댓글

  1. 객체지향 관점에서 static은 "클래스 변수"를 만드는 키워드입니다. 위의 특징들을 한마디로 말하면? 클래스 변수인거죠.
    인스턴스 변수는 인스턴스가 가지고 있는 변수이고, 클래수 변수는 클래스가 가지고 있는 변수이기 때문에 해당 포스트의 설명과 같이 전역변수처럼 쓸 수 있습니다. 그리고 클래스 변수라는 용어를 강조드리고 싶은 이유는 모델링 관점에서 인스턴스의 속성이 아닌 클래스의 속성이 무엇인지 고민할 수 있게 해주기 때문입니다. "사람"이라는 클래스를 생각해 봅시다. '이름'은 인스턴스 변수 겠죠. "사람"의 클래스 변수는 어떤게 있을까요?

    답글삭제

댓글 쓰기

주간 인기글

[정보] 인스타그램은 당신의 소리를 '듣고' 있을 수도 있습니다

[Angular] 모델, 값이 바뀌었는데 화면 template 이 업데이트 되지 않을 때 조치 팁

AWS Lambda - API Gateway로 S3 파일 업로드 API 만들기 #3 - API Gateway - Lambda 연결 및 테스트

[AWS] Lambda + API GateWay를 이용해 간단한 RESTful API 만들기 #1

[AWS] Lambda + API GateWay를 이용해 간단한 RESTful API 만들기 #2