기본적인 자바에 대해 부족한 부분을 보충해서 포스팅 해봅니다.
자바 인스턴스와 정적 멤버
클래스에 선언된 필드와 메소드가 모두 객체 내부에 포함되는 것은 아닙니다. 일부는 포함이 되지 않고 클래스에 그대로 남아있는 것도 있습니다. 클래스는 객체의 설계도입니다. 클래스 멤버필드, 메소드는 당연히 객체에도 포함되어야합니다. 그러므로 객체가 여러 개일 경우 클래스 멤버필드와 메소드는 객체의 개수만큼 존재해야 합니다. 하지만 객체의 필드값이 모두 같다면 이 필드를 모든 객체가 가질 필요가 있을까요? 자바는 이런 경우를 위해 클래스 멤버를 인스턴스 멤버와 정적 멤버로 구분해서 선언할 수 있도록 하고 있습니다.
인스턴스 멤버와 this
인스턴스(instance) 멤버란 객체(인스턴스)를 생성한 후 사용할 수 있는 필드와 메소드를 말하는데, 이들을 각각 인스턴스 필드, 인스턴스 메소드라고 부릅니다. 우리가 지금까지 작성한 모든 필드와 메소드는 인스턴스 멤버였습니다. 인스턴스 필드와 메소드는 객체에 소속된 멤버이기 때문에 객체 없이는 사용할 수 없습니다.
인스턴스 멤버 선언
인스턴스 필드와 메소드를 선언하는 방법은 지금까지 선언한 방식입니다. 특별한 것이 없이 그냥 필드와 메소드를 선언한 것입니다. 지금 살펴봐야하는 것은 선언이 아닌 선언후에 사용하는 방법입니다. 인스턴스 멤버는 객체가 생성된 후에야 사용이 가능합니다. 이전에도 설명드렸던 것 처럼 객체는 힙영역에 생성됩니다. 각각의 객체를 생성할 때마다 새로운 힙영역이 할당됩니다. 그래서 그 객체에 인스턴스 멤버가 할당되고 사용할 수 있는 것입니다. 하지만 자바에서는 힙영역과 스택영역외에 메소드 영역이 있습니다. 정적필드/상수, 생성자 코드, 메소드 코드 등을 저장하고 있습니다. 클래스에 선언된 것 중에 반복적으로 사용될 수 있는 것들을 모아놓은 곳이지요. 인스턴스 멤버는 이 영역에 존재하지 않기때문에 객체를 생성할 때 힙영역에 할당받게 됩니다.
this
객체 외부에서 인스턴스 멤버에 접근하기 위해 참조 변수를 사용하는 것과 마찬가지로 객체 내부에서도 인스턴스 멤버에 접근하기 위해 this를 사용할 수 있습니다. 우리가 우리 자신을 ‘나’라고 가리키듯이 객체는 자신을 this라고 합니다. this는 주로 클래스의 메소드나 생성자 내부에서 클래스자신의 멤버와 매개변수인 멤버를 구분지을 때 사용됩니다.
정적 멤버와 static
정적(static)은 ‘고정된’이란 의미입니다. 정적 멤버는 클래스에 고정된 멤버로서 아까 얘기한 메소드 영역에 존재합니다. 그래서 객체를 생성하지 않아도 사용이 가능합니다. 이들을 각각 저적 필드와 정적 메소드라고 부릅니다.
정적 멤버 선언
정적 필드와 정적 메소드를 선언하려면 필드와 메소드 선언 시 static 키워드를 추가적으로 붙이면 됩니다. 정적 필드는 클래스 하나만 존재하기때문에 모든 객체에서 같은 값을 갖게됩니다. 그래서 선언을 할 때 객체마다 값을 가져야 할 필요가 있으면 인스턴스 필드로 선언하고 공통된 값을 가진다면 정적필드로 선언하면 됩니다.
정적 멤버 사용
정적 멤버는 객체와 상관없이 사용하는 멤버이기 때문에 클래스 이름과 함께 도트(.) 연산자로 접근합니다. 그래서 객체를 생성하지 않아도 멤버에 접근이 가능합니다.
위의 프로그램에서는 객체를 전혀 생성하지 않았습니다. 그것은 정적멤버들만 사용했기 때문입니다. 위에서 본 것 처럼 정적 필드와 정적 메소드는 객체를 생성하지 않고서도 사용할 수 있습니다. pi같은 값은 어디서나 같은 값이기 때문에 정적 필드가 가장 적합합니다. plus나 minus 같은 메소드도 인스턴스 멤버를 사용하지 않기때문에 정적 메소드를 사용했습니다.
정적 메소드 선언 시 주의할 점
객체가 없어도 실행된다는 특징 때문에 정적 메소드를 선언할 때는 이들 내부에 인스턴스 필드나 인스턴스 메소드를 사용할 수 없습니다. 또한 객체 자신의 참조인 this 키워드도 사용이 불가능합니다.