static 과 객체지향적 관점

Static

: 클래스의, 공통적인

Static 메서드

  • 인스턴스를 생성하지 않고도 메모리에 할당시켜, 호출이 가능한 static 메서드가 된다.
    static 메서드 내에서는 인스턴스 멤버들을 직접 사용 할 수 없다.

    Static 멤버변수 (클래스변수)
  • 하나의 변수를 모든 인스턴스가 공유한다. (메모리 공간에 하나만 존재)
    때문에 원래 인스턴스 변수는 하나의 클래스로부터 생성되었더라도 각기 다른 값을 갖지만, static 멤버변수는 인스턴스에 관계없이 같은 값을 갖는다.
  • 그러므로, 모든 인스턴스에서 같은 값이 유지되어야 하는 변수는 static을 붙여서 정의 (값을 변경 할 수 있다는 점에서 final과 차이)

static 을 사용하면 여러개의 인스턴스를 생성해서 관리하는 것보다 효율적이지 않을까? 라는 생각이 들 수 있다. 하지만 객체지향적 관점에서 static은 어떨까?

Q. 자바에서 static의 사용을 지양하는 이유는?

메모리 측면

자바 메모리 공간은 크게 static , stack , heap 영역으로 구분된다.
static 영역의 데이터는 프로그램의 시작부터 종료가 될 때까지 메모리에 남아있게 된다.

이때 static 메모리 공간은 전역변수static(정적)멤버변수를 저장하게 되는데,
무분별하게 이 곳에 저장하다보면 메모리를 낭비하여 필요한 변수만 사용할 필요가 있다.
(stack 의 경우는 메소드가 호출될때만 할당되다가 종료되면 메모리가 해제되므로 괜찮다)

객체지향 측면

  • static 은 객체 지향적이지 않다.
    • static 은 전역 변수를 사용할 때 유용하다.
    • 하지만 객체지향 프로그래밍 원칙에 따르면, 한 객체가 지니고 있는 데이터들은 외부에서 함부로 접근하여 수정할 수 없도록 해야한다.
    • 따라서, static 변수는 각 객체의 데이터들이 캡슐화되어야 한다는 객체지향 프로그래밍 원칙에 위반된다.
  • static 변수는 프로그램이 실행되는 동안 계속 살아있다
    • 위의 메모리 측면에서 JVMstatic 영역은 프로그램이 종료할때까지, 메모리에 남아있는다고 언급했다.
    • 결국, static 변수는 프로그램이 실행되고 있는 동안 계속 살아있게 되므로
    • 함수 내에서 인스턴스를 생성하는 것이 함수 호출이 끝난 후 인스턴스가 소멸되면서 객체의 라이프타임에 더욱 적합하다.
  • static 은 재사용성이 떨어진다.
    • static 메서드는 interface 를 구현하는데 사용 될 수 없다.
    • 따라서, 재사용성을 높여주는 객체지향적 설계에 방해될 수 있다.



추가적으로 static 에 대한 개념,

Q. 왜 main() 메서드에는 static 으로 선언되어있을까?

public static void main(String[] args)
  • static 경우
    java 프로그램이 실행하기 전, static 변수,메소드를 첫 단계에 메모리에 올려 프로그램을 실행시킨다. (static이 실행시 1순위)
    자바가상머신JVM에서 객체를 생성하지 않고도 메모리에 호출시켜 할당이 가능하다.
    main함수가 실행되기 위해서는 메모리에 미리 올라가 있어야한다.
    그렇지 않으면 처음에 main이 없어서 실행이 불가능하다.
  • static 아닌 경우
    객체가 생성되는 런타임(Runtime)시에 메모리에 할당되므로, 객체가 new 키워드를 이용하여 생성이 되야 객체가 메모리에 할당되어 접근/호출이 가능하다.
    main함수가 실행되기 위해서는 메모리에 미리 올라가 있어야한다.
    그렇지 않으면 처음에 main이 없어서 실행이 불가능하다.
    ex) 메인클래스 변수 = new 메인클래스 ( ); 변수.main();
  • 결론
    main 메소드는 인스턴스 생성과 관계없이 JVM에 의하여 호출되므로 반드시 static으로 선언 되어야한다.

Q. main() 에서 (static으로 선언된 메서드에서) static이 아닌 메소드를 그냥 호출했을 때 오류가 나는 이유는?

  • main에서 (static으로 선언된 메서드에서) static 이 아닌 메소드를 바로 못 쓰는 이유는
    static 에서 다른 일반 함수를 쓰려면 메모리에 없는 함수를 접근하게 되어서 못하는 것이다. (static은 메모리에 먼저 올라가고 일반 함수는 런타임일때야 올라가는데 미리 올라간 static에서 안올라간 일반 함수를 호출을 하려니 실패하는 것이다.)
    그래서 일반 메소드에 static 을 선언하면 호출이 가능해진다.

  • static 메서드는 객체를 생성하지 않고도 호출이 가능하지만, 인스턴스 메서드는 반드시 객체를 생성해야 호출이 가능하다

그래도 일반 메소드를 호출하고 싶다면?
  • 객체 생성을 통하여 호출하면 가능하다

  • 다만, 원래 인스턴스 메서드에서 다른 인스턴스 메서드를 호출 할 때는 왜 객체 생성을 따로 안하는가?

    • 그건 하나의 인스턴스멤버가 존재한다는 것은 인스턴스가 이미 생성되었다는 의미이므로 다른 인스턴스 멤버들도 존재한다고 보기 때문이다.



미션 피드백 Review



[이전 블로그 글]
https://blog.naver.com/maui2005/222596882203

[참조]
Java의 정석 280p
https://unabated.tistory.com/m/entry/%EC%99%9C-%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C-static%EC%9D%98-%EC%82%AC%EC%9A%A9%EC%9D%84-%EC%A7%80%EC%96%91%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94%EA%B0%80
https://gorakgarak.tistory.com/m/222?category=55954
https://m.blog.naver.com/heartflow89/220954420688

좋은 웹페이지 즐겨찾기