Java의 static 키워드란?
Java에서 static 키워드는 효율적인 메모리 관리를 위해 사용됩니다. 변수나 메서드가 static으로 선언되면 JVM은 해당 멤버에 대해 메모리를 단 한 번만 할당합니다. 일반적으로 static 변수는 클래스의 공통 속성을 선언할 때 사용되며, 예를 들어 "기관 이름"처럼 모든 인스턴스가 공유하는 값이 대표적입니다. 아래 예제를 통해 static 키워드의 사용 방법을 살펴보겠습니다.
Java에서 static 사용 예제
Java에서 static이 어떻게 동작하는지 확인하기 위해 Test 클래스를 생성하고, 그 안에 static 변수와 static 메서드를 선언한 뒤, 클래스 객체를 생성하지 않고 두 멤버에 모두 접근해 보겠습니다.
public class Test
{
static int myStaticVariable = 10;
// static method
static void staticMethod()
{
System.out.println("www.tutorialspoint.com");
}
public static void main(String[] args)
{
// Test 클래스의 객체를 생성하지 않고
// static 메서드와 변수에 접근
staticMethod();
System.out.println("Accessing Static variable-"+myStaticVariable);
}
}
실행 결과
코드를 실행하면 다음과 같은 출력이 생성됩니다.
$javac Test.java
$java -Xmx128M -Xms16M Test
www.tutorialspoint.com
Accessing Static variable-10
Kotlin에서 Java static 메서드의 대체 방법
Kotlin에는 static 키워드가 존재하지 않습니다. 하지만 Kotlin 라이브러리에서 제공하는 다른 문법을 활용하면 동일한 메모리 관리 효과를 얻을 수 있습니다. 즉, 메모리가 한 번만 할당되고, 그 값이 애플리케이션의 다른 영역에서 임의로 변경되지 않도록 만드는 것이 목표입니다.
Kotlin에서 static 기능을 구현하는 방법은 크게 두 가지입니다.
companion object(동반 객체) 사용
object 클래스와 @JvmStatic 어노테이션 사용
각각의 방법을 자세히 살펴보겠습니다.
방법 1: companion object 사용하기
객체에 companion 키워드를 추가하면 Kotlin에서도 static과 유사한 기능을 구현할 수 있습니다. companion object는 해당 클래스와 같은 파일에 저장되기 때문에 클래스 내부의 모든 private 메서드와 변수에 접근할 수 있으며, 클래스가 초기화되는 시점에 함께 초기화됩니다.
예제
companion object를 직접 구현하면서 Kotlin에서 메모리를 얼마나 효율적으로 관리할 수 있는지 확인해 보겠습니다.
fun main(args: Array<String>) {
// 객체를 생성하지 않고
// 클래스의 변수와 메서드에 접근
println("Hello!"+'\n' + "This an example of accessing class variable without creating object." + MyClass.staticField+'\n')
println("Hello!"+'\n' + "This an example of accessing class Method without creating an object." + MyClass.getStaticFunction()+'\n');
}
class MyClass{
companion object {
val staticField = "This is a Static Variable."
fun getStaticFunction(): String {
return "This is a static Method."
}
}
}실행 결과
코드를 실행하면 다음과 같은 출력이 생성됩니다.
Hello!
This an example of accessing class variable without creating
object. This is a Static Variable.
Hello!
This an example of accessing class Method without creating an
object. This is a static Method.
위 샘플 코드에서 static 변수의 값을 변경하려고 시도하면 Kotlin 컴파일러가 오류를 발생시키는 것을 확인할 수 있습니다.
예제
fun main(args: Array) {
// static 변수 변경 시도
MyClass.staticField="Hello Students";
println("Hello!"+'\n'+"This an example of accessing class variable with out creating object-"+MyClass.staticField+'\n')
}
class MyClass{
companion object {
val staticField = "This is an Static Variable"
fun getStaticFunction(): String {
return "This is a static Method"
}
}
}실행 결과
위 코드는 다음과 같은 컴파일 오류를 발생시킵니다.
$kotlinc -nowarn main.kt -include-runtime -d main.jar
main.kt:5:5: error: val cannot be reassigned
MyClass.staticField="Hello Students";
^
companion object 내부에서 val로 선언된 변수는 불변(immutable)이므로 재할당이 불가능합니다. 만약 값을 변경할 수 있어야 한다면 var로 선언하면 되지만, static의 불변성 특성을 유지하려면 val을 사용하는 것이 권장됩니다.
방법 2: object 클래스와 @JvmStatic 어노테이션 사용하기
Kotlin 공식 문서에 따르면, 변수나 메서드에 @JvmStatic 어노테이션을 적용하면 해당 멤버가 마치 클래스의 static 멤버인 것처럼 동작합니다. 이 방식은 특히 Java 코드와의 상호 운용성(interoperability)이 필요한 프로젝트에서 유용합니다.
예제
다음 예제에서는 object 클래스를 생성하고, 그 안에서 변수와 메서드를 @JvmStatic 어노테이션과 함께 선언하여 Kotlin 환경에서 static 기능을 구현해 보겠습니다.
fun main(args: Array) {
// 객체를 생성하지 않고
// 클래스의 변수와 메서드에 접근
println("Hello!"+'\n' + "This an example of accessing a class variable without creating an object." +MyClass.staticField+'\n')
println("Hello!"+'\n' + "This an example of accessing a class Method without creating an object. " +MyClass.getStaticFunction()+'\n');
}
object MyClass{
@JvmStatic
val staticField = "This is a Static Variable."
@JvmStatic
fun getStaticFunction(): String {
return "This is a Static Method."
}
}실행 결과
코드를 실행하면 다음과 같은 출력이 생성됩니다.
Hello!
This an example of accessing a class variable without creating an
object. This is a Static Variable.
Hello!
This an example of accessing a class Method without creating an
object. This is a Static Method.
정리
Kotlin은 static 키워드를 제공하지 않지만, companion object와 object 클래스 + @JvmStatic 어노테이션이라는 두 가지 방법으로 Java의 static과 동일한 효과를 낼 수 있습니다. 클래스 내부에 정적 멤버가 필요하다면 companion object를, 독립적인 싱글턴 객체와 Java 호환성이 필요하다면 object 클래스와 @JvmStatic 조합을 사용하는 것이 좋습니다.