1. 클레스 변수 (static 변수)
인스턴스 변수는 인스턴스가 생성되었을 때, 생선된 인스턴스 안에 존재 하는 변수이다.
그러나 클래스 변수는 인스턴스의 생성과 상관없이 존재하는 변수이다.
클래스 안에서 선언된 변수 앞에 static 선언을 붙이면 이는 클래스 변수가 된다.
위 코드와 같이 생성자에서 클래스 변수의 값을 1씩 증가시킨 후 출력하는 코드를 생성한 후 main 함수에서 인스턴스 생성을 3차례 하였다.
결과는 클래스 변수가 1씩 증가함을 볼 수 있는데, 이를 통해서 다음의 결과를 알수 있다.
-static 으로 선언된 변수는 변수가 선언된 클래스의 모든 인스턴스가 공유하는 변수이다.
이러한 클래스 변수는 메모리 공간에 존재하는 변수로 해당 변수가 선언된 클래스의 인스턴스들은 이 변수에 바로 접근할 수 있는 권한이 있다.
클래스 변수에 접근하는 방법은 크게 두가지로 나뉜다.
- 클래스 내부 접근 변수의 이름을 통해 직접 접근
- 클래스 외부 접근 클래스 또는 인스턴스의 이름을 통해 접근
위의 코드에서 새로운 class 를 추가하여 다른 클래스에서 클래스 변수의 접근을 표현하였다.
새로운 UseNum 이라는 클래스에서 ClassVariable 에서 선언된 클래스 변수를 접근하는 2가지 방식있다.
cv1.num 인스턴스 이름을 통한 접근
ClassVariable.num 클래스 이름을 통한 접근
또한 클래스 변수는 인스턴스 생성 이전에 메모리 공간에 할당 됨을 유의하여야 한다.
클래스 정보가 가상 머신에 의해 읽히는 순간 할당 및 초기화가 진행 되므로 생성자에서 초기화를 진행하지 않도록 유의해야 한다.
클래스 변수는 인스턴스 간에 데이터 공유가 필요한 상황에서 사용한다.
2. 클래스 메소드 (static 메소드)
클레스 내에 정의된 메소드에 static 선언을 하면 클래스 메소드가 된다.
클래스 메소드의 성격은 클래스 변수와 유사하다.
접근 방법과 인스턴스 생성 이전 호출 가능하다는 점, 어느 인스턴스에도 속하지 않는 메소드 라는 점이다.
다음 코드와 같이 Methods 내에 클래스 메소드를 선언하였다.
선언된 클래스 메소드는 클래스의 이름을 통해서 호출(line8) 할 수도 있고 인스턴스 이름을 통해 호출(line12)
할 수도 있다.
메소드들이 외부 기능을 제공하기 위한 목적이고 인스턴스 변수의 값을 참조하거나 수정하지 않는다면, 설계시에 클래스 메소드로 만드는 것이 좋다.
클레스 메소드에서 인스턴스 변수에 접근이 불가능 하다는 점도 유의 하여야 한다.
위에 코드에서 보듯이 이는 에러가 발생하는데
인스턴스 변수는 인스턴스에 속하고 인스턴스가 생성되어야 메모리 공간에 할당되고, 클래스 메소드는 인스턴스 생성 이전부터 호출이 가능하므로 그렇다.
- 클래스 메소드는 인스턴스에 속하지 않으므로 인스턴스 변수에 접근이 불가능하다.
- 같은 이유로 클래스 메소드는 인스턴스 메소드의 호출도 불가능하다.
3. 다른 용도의 static
이 static을 통해 기존에 사용하였던 부분을 이해할 수 있다.
출력을 위해 사용하였던 system.out.println() 의 경우 원래는 자바에서 제공하는 클레스내에 있는 java.lang 이라는 패키지 내에 위치하고 있으므로 원칙적으로 보면
java.lang.system.out.println();
으로 호출 하여야 한다.
그러나 이는 컴파일러가
import java.lang 을 알아서 삽입해 주고 있으며, 이를 통해 java.lang 이라는 패키지 내에 static 으로 선언 되어있음을 알 수 있다.
이 내용은 다소 복잡하지만 다음과 같이 정리됨을 알아두자
'system 에 위치한 클래스 변수 out 이 참조하는 인스턴스의 println 메소드를 호출하는 문장'
이제 main 에 관하여 살펴보도록 하자.
지금 까지 main 메소드는 이클립스에서 자동으로 만들어 주었고 그 형식은 다음과 같았다.
public static void main(String[] args) {}
main 메소드는 클래스 외부에서 호출이 이루어 지며 이에 따라 public 으로 선언한다.
또한 main 메소드는 인스턴스가 생성되기 이전에 호출되므로 static 으로 선언하여야 한다.
static 초기화 블록(static initialization block) 이라는 것도 있는데 이는 클래스 변수와 마찬가지로 가상먼신이 클래스의 정보를 읽어들일 때 단 한번 실행되며, 클래스 변수를 선언과 동시에 초기화 하는 용도로 사용할 수 있다.
사용법은 static {} 로 클래스 내에 위치하면 된다.
static import 라는 기능도 있는데 이는 import java.lang 내에 있는 Math.PI 라는 클래스 변수를 사용한다고 하면
import java.lang.Math.PI 를 선언하여 Math 를 생략하여 PI 를 그대로 사용할 수도있다.
또한 import java.lang.Math.* 로 선언하여 Math 내의 모든 클래스 변수를 사용 할 수도 있다.
'JAVA' 카테고리의 다른 글
[JAVA] string 클래스 (자바 독학하기13) (0) | 2021.06.26 |
---|---|
[JAVA] 메소드 오버로딩 (Method Overloading) (자바 독학하기12) (0) | 2021.06.26 |
[JAVA] 접근 수준 지시자(Acess-level-Modifiers) (자바 독학하기10) (0) | 2021.06.22 |
[JAVA] 패키지 (Package) (자바 독학하기9) (0) | 2021.06.21 |
[JAVA] 클래스와 인스턴스 ( Class & Instance) (자바 독학하기 8) (0) | 2021.06.08 |