[Java] static키워드
1️⃣ static이란?
- 정적이라는 뜻으로 C언어에서 전역변수나 함수와 같이 사용할 수 있습니다. (Java에서는 접근제어자를 이용하여 접근범위를 추가적으로 제어할 수 있습니다)
- static키워드는 대부분의 언어에 있는 키워드이지만 언어마다 약간의 차이가 있습니다. (C언어에서
static
키워드는정의된 파일 내에서만 전역적으로 사용이 가능함 ) - 사실 객체지향의 성격과는 거리가 먼 기능이고 이러한 이유로 static기능을 Java에서 없애야 한다는 의견도 있었습니다. (static을 대체하기 위해 싱글턴이라는 디자인패턴이 만들어지기도함) 하지만 static은 Java에 없어서는 안될 기능이라고 생각합니다. Java에서 무조건적으로 객체지향을 따르기 보다는 상황에 따라서 함수형 혹은 절차지향을 쓸줄 알아야 한다고 생각합니다.
2️⃣ static의 쓰임
(1) 새로운 클래스 인스턴스(객체)를 만들 필요없다.
- 단순히 클래스에 내장된 메소드를 이용하고 싶은데 클래스 인스턴스를
new
를 이용하여 생성하는 것은 메모리적으로 비효율적 입니다. - 다음과 같이 객체를 생성할 필요없이 클래스를 이용하여 메소드를 호출할 수 있습니다.
/* MyMath클래스 */
public calss MyMath {
static public int add(int a, int b) {
return (a + b);
}
}
/* Main */
public class Main {
public static void main(String[] args) {
int sum;
sum = MyMath.add(3, 4); // 바로 사용가능
}
}
- 물론 다음과 같이 객체를 생성하여 사용할 수 있습니다.
public class Main {
public static void main(String[] args) {
int sum;
MyMath temp = new MyMath();
sum = temp.add(3, 4);
}
}
- 위와같이 객체의 생성을 막고싶다면 다음과 같이 private키워드를 이용하여 생성자를 만들어 주면 됩니다.
/* MyMath클래스 */
public calss MyMath {
private MyMath() {
}
static public int add(int a, int b) {
return (a + b);
}
}
- 흔히 표준출력함수로 사용하는
System.out.prinln()
메소드 역시 내부적으로static
키워드를 사용한 메소드 입니다.
(2)클래스 멤버변수에 사용
- 동일한 클래스의 인스턴스로 생성된객체들끼리 공유하는 변수를 만들 수 있습니다.
- 즉,
static
으로 선언하면 객체의 변수가 아닌클래스 변수 가 됩니다. - 예를들면 생성한 객체의 수를 기록하는 변수를 클래스 내부에 만들 수 있습니다.
/* SampleClass 클래스 */
public class SampleClass {
static private int classCount; // 멤버변수에 static키워드 사용
public SampleClass() {
classCount++; // 생성할 때마다 증가
}
public static void printCount() {
System.out.println("생성된 객체 수: " + classCount);
}
}
/* Main */
public class Main {
public static void main(String[] args) {
SampleClass temp = new SampleClass();
SampleClass temp2 = new SampleClass();
SampleClass.printCount();
SampleClass temp3 = new SampleClass();
SampleClass temp4 = new SampleClass();
SampleClass.printCount();
}
}
생성된 객체 수: 2
생성된 객체 수: 4
3️⃣ static접근 방향
(1)비정적 --> 정적(static) 접근이 가능하다
- 같은 클래스로 생성한 객체들은 정적(static) 메소드나 변수에 접근이 가능합니다.
/* SampleClass */
public class SampleClass {
static public String className = "SampleClass"; // 정적변수
public static void printHello() { // 정적메소드
System.out.println("Hello");
}
public static void printName() { // 비정적메소드
System.out.println(className);
printHello();
}
}
/* Main */
public class Main {
public static void main(String[] args) {
SampleClass temp = new SampleClass();
temp.printName(); // 정상적으로 출력
}
}
(2)정적(static) --> 비정적 접근이 불가능하다
- 정적 메소드는 모든 객체가 공통으로 공유하지만 비정적변수나 메소드는 각각의 객체가 독립적으로 존재합니다. 때문에 정적 메소드에서 비정적변수나 메소드를 호출하면
어떤 객체의 변수나 메소드를 호출해야하는지 알 수 없습니다. 그렇기 때문에 정적(static)메소드에서 비정적변수나 메소드에 접근이 불가능합니다.
public class SampleClass {
public String className;
public SampleClass(String className) {
this.className = className;
}
public void printHello() {
System.out.println("Hello");
}
public static void printName() {
System.out.println(className); // 컴파일 오류
printHello(); // 컴파일 오류
}
}
java: non-static variable className cannot be referenced from a static context