[아시나요?]static만이 가능한 몇가지 특징
☞클래스 이름만으로 접근 가능
static 변수나 메소드는 객체를 생성하지않아도 사용할 수 있다는 사실을 알고 있을 것이다. 보통 레퍼런스 변수를 사용하여 메소드나 변수를 호출하지만 사실상 static변수를 호출하는 다른 방법은 레퍼런스 변수를 사용할 필요 없이 클래스 이름을 통해 바로 메소드나 변수를 호출할 수 있다.
클래스_이름.static_변수
클래스_이름.static_메소드
class Static{
public static int value = 9;
public static int getValue(){
return value;
}
}
즉 클래스 앞에서 선언한 클래스의 변수와 메소드를 사용하기 위해서는 다음과 같이 클래스 이름만 사용하면 된다는 뜻이다.
int i = Static.value;
int d = Static.getValue();
예를 보면 알겠지만, static은 레퍼런스 변수를 선언하지 않고도 사용이 가능하기 때문에 문법이 매우 단순하고 사용하기 편하다. 그래서 자바의 기본 라이브러리에서도 static 을 많이 사용하고 있는데. 그 대표적인 클래스가 바로 Math 클래스이다. Math.sin() , Math()abs() 등이 모두 static 메소드로 만들어져 있음을 알 수 있을 것이다.
☞상수
final 을 사용하면 변수를 상수와 같이 이용할 수 있다. 이전까지의 방법으로 상수를 만들려면 꼭 객체를 생성해야만 하는 불편함을 가지고 있었다. 그런데 static을 사용하면 이런 번거로운 작업을 거치지 않고 모든 클래스에서 사용이 가능한 진정한 의미의 상수를 만들 수 있다. 다음 예제의 USERINFO 클래스가 바로 이런 static의 특징을 이용한 상수의 사용 예를 잘 보여주고 있다.
class UserInfo{
public static final String NAME = "홍길동";
public static final String ID = "mr.hong";
public static final int AGE = 20;
}
public class StaticCon{
public static void main(String [] args){
System.out.println("이름 : "+UserInfo.NAME);
System.out.println("ID : "+UserInfo.ID);
System.out.println("나이 : "+UserInfo.AGE);
}
}
객체 생성하는 과정이 필요없기 때문에 어떤클래스에서든 간편하게 사용할 수 있다. 이런식으로 사용하는 상수는 자바의 기본 클래스에서도 자주 볼 수 있는데, 이 상수 역시 변수와 마찬가지로 필드라는 이름을 사용한다.
☞클래스에 하나의 요소만 존재
클래스를 가지고 객체를 생성하는 방법을 알고 있다. 클래스는 붕어빵의 틀과 같아서 언제나 같은 모형의 객체를 원하는 수만큼 생성할 수 있다. 물론 클래스에 포함되어 있는 각종 메소드와 변수도 생성된 샛체의 수만큼 생성될 것이다. 그런데 재미있는 사실은 static 변수나 메소드는 객체의 생성과 함께 생성되지 않는다는 것이다. 그런데 static 은 객체가 생성되기 전에 이미 만들어져 메모리에 상주하게 되는데, 그 복사본은 만들지 않는다. 즉 처음 생성된 static 하나만이 메모리에 상주한다는 말이다.
이말의 의미를 좀더 쉽게 풀어본다면 하나의 클래스에 대한 객체가 여러 개 존재하더라도 그 안에 포함되어 있는 static 변수나 메소드는 오직하나만 존재하며 여러 객체에서 이들을 공통으로 사용하게 된다는 말이다. 공통으로 사용한다는 말의 의미가 잘 와닿지 않을 것 같아서 간단한 예제를 준비했다. TestClass에는 두 개의 변수가 선언되어 있는데, 하나는 일반 변수이고 또 하나는 static 변수이다. 이들은 TestClass가 생성될 때마다 즉 TestClass의 생성자가 호출될 때마다 자신의 값을 1씩 증가시키는 동작을 한다.
class TestClass{
private int gNumber =0; //일반변수
private static int sNumber =0;//static변수public TestClass(){
gNumber++;
sNumber++;
}
public void printVar(){
System.out.println("일반변수 : "+gNumber);
System.out.println("static변수 : "+sNumber);
System.out.println("");
}
}
class UniqueStatic{
public static void main(String [] args){
TestClass tc1 = new TestClass(); //첫번째 객체 생성
tc1.printVar();
TestClass tc2 = new TestClass(); //두번째 객체 생성
tc2.printVar();
TestClass tc3 = new TestClass(); //세번째 객체 생성
tc3.printVar();
}
}
예제는 매우 간단한 동작을 수행한다. TestClass는 생성자가 호출될 때마다 가지고 있는 변수 gNumber 와 sNumber 의 값을 1만큼씩 증가시킨다. gNumber는 일반 변수이기 때문에 객체가 생성될 때 마다 새롭게 만들어진다. 그래서 결과는 늘 1을 출력하게 된다. 그러나 sNumber는 static 변수이기 때문에 처음에 한번 생성된 것을 여러객체에서 공유하여 사용한다. 초기화도 처음 만들어질 당시에만 수행하기 때문에 생성자를 호출할 때마다 sNumber는 자신의 값을 1씩증가시킬 수 있는 것이다. 출력결과를 통해서 이 사실을 확인할 수 있다.
☞static 블록
이것은 static이 객채를 생성하기 전에 만들어진다는 사실을 이용한 것이다. 생성자가 호출되기 이전에 어떤 일을 해주어야 한다면 이 static 블록을 유용하게 사용할 수 있을 것이다. static 블록은 언제나 생성자 이전에 호출된다는 것을 보장 받을 수 있다.
static {
//해야할 일
}
다음예제를 통해서 static 블록이 생성자보다 먼저 호출됨을 확인할 수 있다.
class Block{
static{ //static 블록
System.out.println("static 블록 호출");
}
public Block(){
System.out.println("생성자 호출");
}
}
public class StaticBlock{
public static void main(String [] args){
Block b = new Block();
}}