스태틱
스태틱(static)은 객체 지향 프로그래밍(OOP)에서 모든 인스턴스에서 공통적으로 사용할 수 있는 클래스 변수 또는 클래스 메소드에 사용하는 소유제어자이다. ‘스태틱’이라고 읽는다. 영어로 static은 ‘정적인’, ‘정지 상태의’라는 뜻이다.
목차
개요
자바에서 스태틱 키워드를 사용한다는 것은 메모리에 한번 할당되어 프로그램이 종료될 때 해제되는 것을 의미합니다. 이를 정확히 이해하기 위해서는 메모리 영역에 대한 이해가 필요하다. 일반적으로 우리가 만든 클래스는 스태틱 영역에 생성되고, new 연산을 통해 생성한 객체는 Heap영역에 생성된다. 객체의 생성시 할당된 Heap역역의 메모리는 가비지 컨트롤러를 통해 수시로 관리를 받는다. 하지만 스태틱 키워드를 통해 스태틱 영역에 할당된 메모리는 모든 객체가 공유하는 메모리라는 장점을 지니지만, 가비지 컨트롤러의 관리 영역 밖에 존재하므로 스태틱을 자주 사용하면 프로그램의 종료시까지 메모리가 할당된 채 존재하게 된다.[1]
특징
자바에서 스태틱은 메모리에 한번 할당되어 프로그램이 종료될 때 해제되는 것으로로, 메모리에 한번 할당되어 여러 객체가 해당 메모리를 공유한다.
public class Animel { private String name = "Reptiles"; public void printName() { System.out.println(this.name); } }
위와 같은 클래스로 객체를 여러개 생성할 시 Reptiles라는 메모리를 여러개 생성하게 된다. 하지만 이러한 경우에 static을 사용한다면 객체 하나의 메모리를 참조해 메모리 효율을 높일 수 있다.[1]
스태틱 변수(정적 변수)
스태틱 변수는 메모리가 클래스에 귀속되며 각각의 오브젝트에 귀속되지 않는다. 일반 변수는 객체마다 1개 생성되며 n개의 객체가 있을 때는 n번 생성된다. 스태틱 변수는 객체가 n개 있어도 단 한개만 생성된다. 이런 스태틱 변수를 사용하기 위해서는 <클래스 이름>.<스태틱 변수 이름>으로 사용이 가능하다. 클래스에 속해있으므로 오브젝트를 따로 생성하지 않아도 바로 사용이 가능하다.[2]
public class 클래스 { static int 스태틱변수 = 1234; int 일반변수 = 123; } public class 메인 { public static void main(String[] args) { System.out.println(클래스.스태틱변수); 클래스 클래스1 = new 클래스; 클래스 클래스2 = new 클래스; } }
위에서 보는 것과 같이 스태틱 변수는 클래스에 귀속되어 있기 때문에 객체를 생성하지 않아도 사용이 가능하며 클래스를 이용해 새로운 객체를 생성하더라도 스태틱 변수는 계속 생성되지 않고 하나만 생성되어 사용된다.
스태틱 메소드(정적 메소드)
스태틱 메소드는 객체의 생성없이 호출이 가능하며, 객체에서는 호출이 불가능하다. 대체로 유틸 관련 함수들이 여러번 사용되므로 스태틱 메소드로 구현된다. 그렇기 때문에 전역으로 자주 사용할 메소드를 스태틱 메소드로 만들어서 사용한다. 프로젝트 내에서 공통적으로 사용해야할 메소드가 있으면 스태틱 메소드로 생성해 불필요한 코드 수를 줄이게 된다. main 메소드 또한 static이 붙는다. 클래스를 로딩하면서 메인 메소드가 메모리에 저장되고 자바는 메인 메소드를 보고 가장 먼저 불러들이는 것이다. 메인 메소드 또한 다른 스태틱 변수와 메소드와 다름이 없으나 public static void main(String[] args)의 형식을 가진 메소드를 가장 먼저 실행시킨다는 특징을 가지고 있을 뿐이다.[2]
스태틱 클래스(정적 클래스)
스태틱 클래스는 모든 멤버가 정적 변수 혹은 정적 메소드로 이루어진 것이며 객체를 생성할 수 없다. 그리고 class 키워드 앞에 static이라는 키워드를 선언해야한다. 정적 클래스의 모든 멤버는 static으로 선언되어야하며 생성자를 포함할 수 없다. 정적 클래스는 객체들이 처음 호출될 때 전역적으로 접근해야 하는 유틸리티 클래스를 만들 때 정적 클래스로 만들어 유용하게 사용이 가능하며 객체들이 처음 호출될 때 생성되고 프로그래밍 종료될 때 해제되기 때문에 정적 클래스는 어디서든 접근이 가능하다.[3]
유의 사항[4]
//표현 오류 error: illegal start of expression //클래스, 인터페이스 또는 열거타입 error: class, interface, or enum expected
- 스태틱 메소드 내에서는 객체 생성 없이 static 자원을 호출 가능하다. 해당 자원에 클래스 이름이 생략이 된다.
- 지역변수에는 스태틱이 붙을 수 없다. 오직 멤버변수만이 소유의 대상이 된다.
- 다른 클래스에서 static 자원을 호출할 때에는 클래스 이름을 생략할 수 없다.
<스태틱 메소드 클래스> public class Static1 { static int i = 1; public Static1() { static String name = "asadal" } public static void test() { System.out.println("메소드 내용"); } } <Client 클래스(메인)> public class Client { public static void main(String[] args) { System.out.println("i:"+ Static1.i); // 클래스.변수로 호출할 때 클래스이름도 같이 선언해준다. Static1.test() } }
- 스태틱 자원은 메모리에 오직 1개만 생성된다. 해당 클래스의 모든 객체에서 공유되어진다.
- 스태틱 메소드에서는 this와 super을 사용할 수 없다.
//스태틱 구문에서는 non-static 변수를 참조할 수 없다는 에러 error: non-static variable super cannot be referenced from a static context
활용
스태틱은 전역 변수와 전역 메소드를만들 때 활용된다. 캡슐화의 원칙으로 자바에서는 어떤 변수나 함수도 클래스 밖에 존재할 수 없으며 클래스의 멤버로 존재해야한다. 하지만 응용프로그램을 작성할 때 모든 클래스에서 공유하는 전역 변수나 모든 클래스에서 언제든 호출이 가능한 전역 메소드를 만들어 사용할 필요가 있다. 이 때 스태틱(static)을 사용하면 객체를 생성하지 않고 바로 호출할 수 있다.
제약 조건
스태틱 메소드는 객체가 생성되지 않는 상황에서도 사용이 가능하므로 객체에 속한 인스턴스 메소드, 인스턴스 변수 등을 사용할 수 없으며 static 멤버들만 사용이 가능하다. 그리고 스태틱 메소드는 this 키워드를 사용할 수 없다. this의 경우 호출 당시 실행중인 객체를 가리키는 레퍼런스이다. 즉, 객체가 생성되지 않은 상황에서도 클래스 이름을 이용하여 호출이 가능한 스태틱 메소드는 this 키워드를 사용할 수 없다.[5]
싱글톤패턴
각주
- ↑ 1.0 1.1 망나니개발자, <static변수와 static 메소드>, 《개인블로그》,2019-02-04
- ↑ 2.0 2.1 삐멜 소프트웨어 엔지니어, <9.static변수 static 메소드>, 《개인블로그》,2019-04-03
- ↑ 싸비, <정적(Static) 클래스(Class), 메소드(Method), 필드(Field)>, 《개인블로그》,2019-11-28
- ↑ CIVIC, <자바 ② 소유 제한자 ( static )>, <<개인 블로그>>, 2018-02-14
- ↑ heejeong Kwon, <java static 멤버와 static 메서드>, 《개인블로그》
참고자료
- 망나니개발자, <static변수와 static 메소드>, 《개인블로그》,2019-02-04
- 삐멜 소프트웨어 엔지니어, <9.static변수 static 메소드>, 《개인블로그》,2019-04-03
- 싸비, <정적(Static) 클래스(Class), 메소드(Method), 필드(Field)>, 《개인블로그》,2019-11-28
- CIVIC, <자바 ② 소유 제한자 ( static )>, <<개인 블로그>>, 2018-02-14
- heejeong Kwon, <java static 멤버와 static 메서드>, 《개인블로그》
같이 보기