메서드나 멤버변수에 static이라는 예약어를 정의하면 해당 멤버변수나 메서드들의 객체가 생성될 때 static 영역이라는 곳에 유일하게 생성되어지면서 모든 객체들이 공유하여 사용하게 된다.
[접근제한] static [반환형] 메서드명(){}
[접근제한] static [자료형] 변수명;
다음과 같이 사용한다.
static으로 선언되었다면 객체를 생상하지 않고 사용할 수 잇으며 아무리 많은 객체를 생성한다고 해도 static 변수는 오직 하나만 만들어지며 그것은 모든 객체가 공유한다. 예를들어 은행에서 0.1% 금리를 주고 있었다고 가정해보자 근데 이 금리가 상승하여 0.2%의 금리를 적용해야하는 상황인데 은행을 이용하는 고객들의 모든 통장이 각각 하나의 객체라면 모든 통장을 일일히 0.2%로 수정해야한다. 하지만 static 변수로 선언되어 있다면 고객 하나의 통장을 0.2%로 수정하면 하나의 변수를 모두 공유하고 있기 때문에 한번에 수정이 가능하다.
public class Bank{
private String bankName;
static float investing = 0.1f;
public Bank(String bankName){
this.bankName = bankName;
}
public void printBank(){
System.out.println("은행 : "+ bankName);
System.out.println("금리 : "+ investing);
}
}
public class BankMain{
public static void main(String[] args){
Bank bank = new Bank("카카오뱅크");
Bank.investing = 0.2f;
bank.printBank();
}
}
다음과 같은 결과를 얻을 수 있다. 혹시라도 나와 같이 class에 내부에서 작성해서 테스트 해보시는 분들은 파일 이름과 다른 class의 public을 제거해서 사용하고 아니라면 파일 2개를 각각 만들어서 테스트하면 된다.
그리고 이 코드에서 확인할 수 있는 점은 static 변수는 객체를 생성하여 호출되어지지 않고 class에서 직접 호출하여 사용한다는 점이다.
Bank.investing = 0.2f;
static method 또한 static 변수와 마찬가지로 공유 개념으로 사용되며 한가지 주의해야할 점은 static 메서드 안에서 static이 아닌 변수들을 참조해서 사용할 수 없다.
class StaticTest{
String s1 = "none static";
static String s2 = "static";
public static String getString(){
return s2;
//return s1은 오류가 발생
}
}
static 메서드나 static 변수들은 정적인 영역(=static 영역)에 존재하므로 위 예제처럼 객체를 생성하지 않고도 접근할 수 있다는 장점이 있다. 하지만 static 변수가 아닌 instance 변수는 사용할 수 없다는 점에 주의해야한다. 하지만 객체를 생성하여 얻어진 참조변수를 통한 멤버변수는 접근이 가능하다.
class StaticTest2{
int c;
static int count;
public StaticTest2(){
c++;
count++;
}
}
class StaticTest3{
public static void main(String[] args){
StaticTest2 s1 = new StaticTest2();
System.out.println("s1의 c = "+s1.c+", s1의 count = "+s1.count);
StaticTest2 s2 = new StaticTest2();
System.out.println("s2의 c = "+s2.c+", s2의 count = "+s2.count);
StaticTest2 s3 = new StaticTest2();
System.out.println("s3의 c = "+s3.c+", s3의 count = "+s3.count);
}
}
다음과 같은 결과를 확인할 수 있고 새로운 객체를 생성하여 새로운 값이 증가된 c는 계속 1로 출력되는 것을 확인할 수 있고 모든 객체가 값을 공유하는 count는 계속해서 증가됨을 확인할 수 있었다.
static 초기화란
static {
수행문
}
다음과 같은 구조의 static 사용법이다. 잘 사용되어지지 않는다고 하는데 이는 main을 실행하기 전에 static 초기화로 미리 정의하는 방법으로 사용되어진다.
class StaticTest4{
int a = 100;
static int b = 200;
static{
b=5000;
c=10000;
}
public static void main(String[] args){
System.out.println("c = "+c);
}
static int c;
}
위 코드에서 c가 맨 아래에 선언되어 있어 이질감을 느낄 수 있다. 왜냐면 c를 선언하고 그 아래에서 값을 초기화 해야하는데 c의 값을 먼저 초기화하고 아래에서 사용하기 때문이다. 하지만 static으로 선언된 변수를 static으로 초기화한다면 문제가 없다. 이런 방법이 있다는 것을 알고 간단하게 넘어가자.