본문 바로가기

Dev.BackEnd/JAVA

[JAVA] 3. 자바에서 변수와 메소드에 대하여 / 클래스 메소드, 클래스 변수




Chapter 3. 변수와 메소드

자바에서는 변수의 종류가 세 가지로 나뉘어 지고 각각 올라가게 되는 메모리가 다르다.

메소드 또한 클래스 메소드인지 인스턴스 메소드인지에 따라 다르다.

JVM 메모리 구조와 함께 각 변수와 메소드에 대해 알아본다.


클래스 변수(static 변수)
멤버 변수라고도 한다.
모든 인스턴스에서 똑같이 사용하면 되는 변수가 존재할 때,
이 똑같은 정보를 한 번에 정의해주면 좋지 않을까라는 생각으로 등장하게 되었다.
모든 인스턴스에게 적용될 수 있는 변수이며,
모든 인스턴스가 공유하는 변수이다.
클래스에 소속되어 있는 변수에 접근하여 사용할 수 있다는 것이다.

인스턴스 변수를 정의할 때 앞에 static을 추가로 정의한다.
static 으로 선언된 변수는 메모리 공간 하나에만 존재하며
어디서나 접근이 가능한 변수이다

단 어디서나 접근이 가능하려면 static 변수도 public 으로 선언이 되어야 한다.
어디서나라는 말은, 패키지를 넘어서도 접근을 가능하게 할 것인지,
클래스를 넘어서도 접근을 가능하게 할 것인지에 대한 접근제어자에 관련된 부분이다.

static 변수는 인스턴스가 생성되기 전에 메모리 공간에 할당되어 초기화까지 완료가 된다.
int 타입의 변수는 0으로 초기화가 되고 String 변수의 경우 null로 초기화가 된다.
좀더 구체적으로는 JVM에 의해서 클래스가 메모리 공간에 올라가는 순간이다.

인스턴스 간에 데이터 공유가 필요한 상황에서는 static 변수를 선언한다.
추가로 참조의 용도로만 선언되는 변수는 static final 로 선언하는 것이 적절하다.
cf) 변수 선언 시 static, final, public(접근제어 지시자)까지도 이어서 선언이 가능하며 그 순서는 상관이 없다.

하지만 static 변수에는 무거운 즉, 용량이 큰 변수를 선언해서는 메모리의 비효율을 발생시킨다.
프로그램이 실행되면서 static area(=method area)에 변수가 생성되기 때문이다.
이 영역에 생성되는 변수는 프로그램이 종료될 때까지 할당된 메모리를 점유하고 있게 된다.


인스턴스 변수(Instance variable)
인스턴스마다 다른 값을 갖는 변수로,
클래스 변수와 마찬가지로 클래스 내부에 선언이 된다.
하지만 이 변수는 인스턴스가 new를 통해 생성되어야만 생성된다.
즉, 인스턴스가 생성되었을 때 접근할 수 있다는 것이다.
그렇기 때문에 자바 메모리 구조 중 Heap 영역에 생성된다.
따로 삭제를 해주지 않아도, Garbage collector가 내부적인 알고리즘을 통해 삭제해준다.

지역변수(local variable)
메서드 내에서 선언되고, 메서드 내에서만 사용 가능하다.
메서드가 종료되면 소멸되어 사용할 수 없게 된다.
지역 변수는 따로 프로그래머가 초기화해줘야 한다.

class TestClass2 {
  int iv; //인스턴스 변수
  static int cv; // 클래스 변수

  void instanceMethod(){ //인스턴스 메소드
    System.out.println(iv); //인스턴스 변수를 사용할 수 있다.
    System.out.println(cv); //클래스 변수를 사용할 수 있다.
  }

  static void staticMethod(){ //static 메소드
    System.out.println(iv); //Error! 인스턴스 변수를 사용할 수 없다.
    System.out.println(cv); //클래스 변수는 당연히 사용가능하다.
  }
}



클래스 메소드(static 메소드)
static 메소드가 삽입된 클래스의 모든 인스턴스로부터 접근이(호출이) 가능하다.
인스턴스를 생성하지 않아도 즉, new 연산자 없이 메소드에 직접 접근하여 호출할 수 있다.
효율적으로 메모리와 시간을 컨트롤할 수 있다.
인스턴수 변수에 저장된 값을 변경하거나 참고하는 일이 없는 경우에는
메소드에 static을 선언하여 별도의 인스턴스 생성을 피하는 방향으로 설계해준다,

main메소드는 인스턴스 생성과는 관계없이 JVM에 의해 호출된다.
그러므로 아무 클래스에서나 정의되면 된다.
하지만 반드시 static으로 선언을 해야 한다.

"
각종 기본서에서는 다른 class들과 동일한 class파일에 main메소드를 작성하는데,
이는 일반적이지 않다.
웹 상에서의 Java는 보통 main메소드는 존재하지 않는다.
구동되는 것은 서버에서 구동되고 자바는 서블릿 클래스만 제공하기 때문이다.
즉, main 메소드는 작성한 클래스들이 작동하는 공간인 것이다.
"

이러한 특징들로 미루어봤을 때, 별도의 클래스에 main 메소드를 작성하는 것이,
유지 보수에도 좋고 가독성도 좋고 더욱 구조적이다.
기본서들이 작성해둔 code그대로를 작성하지 말자.


 클래스 메소드는 인스턴스 멤버에 접근할 수 없다.
: 당연하다. 클래스는 메소드보다 먼저 존재하게 된다. 클래스라는 설계도는 컴파일 과정에서 이미 메모리에 올라가게 된다.
그리고 그 클래스를 기반으로 인스턴스를 생성하게 된다.
클래스 메소드는 인스턴스 생성과는 관계없이 접근할 수 있는 메소드이다.
따라서 클래스 메소드가 인스턴스 생성과 관계없이 접근하려면
클래스 메소드에는 인스턴스 멤버에 대한 내용이 존재할 수 없다. 


메서드 내에서 인스턴스 변수를 사용하지 않는다면, static 을 붙이는 것을 고려해볼만 하다.

메서드 호출시간이 짧아지므로 성능이 향상된다.



자바 가상 머신 JVM에 대해서





Chapter 3. The End