자바의 정적 키워드 가이드

1. 소개

이 기사에서는 Java 언어 의 static 키워드에 대해 자세히 살펴 보겠습니다. 변수, 메서드, 블록, 중첩 클래스에 정적 키워드를 적용하는 방법 과 그 차이가 무엇인지 알아 봅니다.

2. 정적 키워드 의 구조

Java 프로그래밍 언어에서 static 키워드 는 특정 멤버가 해당 유형의 인스턴스가 아닌 유형 자체에 속함을 나타냅니다 .

즉, 클래스의 모든 인스턴스에서 공유되는 해당 정적 멤버의 인스턴스가 하나만 생성됩니다.

키워드는 변수, 메서드, 블록 및 중첩 클래스에 적용 할 수 있습니다.

3. 정적 필드 (또는 클래스 변수)

Java에서 필드가 static 으로 선언되면 해당 필드의 정확히 단일 복사본이 생성되고 해당 클래스의 모든 인스턴스간에 공유 됩니다. 클래스를 초기화하는 횟수는 중요하지 않습니다. 항상 그것에 속하는 정적 필드의 복사본이 하나만 있습니다. 이 정적 필드 의 값은 다른 클래스의 동일한 모든 객체에서 공유됩니다.

메모리 관점에서 정적 변수는 Metaspace라는 JVM 메모리의 특정 풀로 이동합니다 (Java 8 이전에는이 ​​풀을 Permanent Generation 또는 PermGen이라고했으며 완전히 제거되고 Metaspace로 대체되었습니다).

3.1. 정적 필드의 예

여러 속성 (인스턴스 변수) 이있는 Car 클래스 가 있다고 가정 합니다. Car 블루 프린트 에서 새 오브젝트가 초기화 될 때마다 각각의 새 오브젝트는 이러한 인스턴스 변수의 고유 한 복사본을 갖게됩니다.

그러나 초기화되고 모든 인스턴스에서 공유되는 Car 객체 의 수를 포함하는 변수를 찾고 있다고 가정 해보면 초기화시 액세스하고 증가시킬 수 있습니다.

이것이 정적 변수가 들어오는 곳 입니다.

public class Car { private String name; private String engine; public static int numberOfCars; public Car(String name, String engine) { this.name = name; this.engine = engine; numberOfCars++; } // getters and setters }

이제 초기화되는이 클래스의 모든 개체에 대해 numberOfCars 변수 의 동일한 복사본 이 증가합니다. 따라서이 경우 다음 주장이 참입니다.

@Test public void whenNumberOfCarObjectsInitialized_thenStaticCounterIncreases() { new Car("Jaguar", "V8"); new Car("Bugatti", "W16"); assertEquals(2, Car.numberOfCars); }

3.2. 정적 필드 를 사용하는 강력한 이유

  • 변수의 값이 개체와 독립적 인 경우
  • 값이 모든 객체에서 공유되어야하는 경우

3.3. 기억해야 할 요점

  • 이후 정적 변수는 클래스에 속하는, 그들은 클래스 이름을 사용하여 직접 액세스 할 수 및 개체 참조가 필요하지 않습니다
  • 정적 변수는 클래스 수준에서만 선언 할 수 있습니다.
  • 개체 초기화없이 정적 필드에 액세스 할 수 있습니다.
  • 객체 참조 (예 : ford.numberOfCars ++ )를 사용하여 정적 필드에 액세스 할 수 있지만 ,이 경우 인스턴스 변수인지 클래스 변수인지 파악하기가 어려워 지므로 사용을 자제해야합니다. 대신 항상 클래스 이름을 사용하여 정적 변수를 참조해야합니다 (예 :이 경우 Car.numberOfCars ++ ).

4. 정적 메서드 (또는 클래스 메서드)

정적 필드와 마찬가지로 정적 메서드도 개체가 아닌 클래스에 속하므로 자신이 상주하는 클래스의 개체를 만들지 않고도 호출 할 수 있습니다. 클래스의 객체를 생성하지 않고 사용하기위한 것입니다.

4.1. 정적 방법의 예

정적 메서드는 일반적으로 인스턴스 생성에 의존하지 않는 작업을 수행하는 데 사용됩니다.

해당 클래스의 모든 인스턴스에서 공유되어야하는 코드가있는 경우 해당 코드를 정적 메서드에 작성합니다.

public static void setNumberOfCars(int numberOfCars) { Car.numberOfCars = numberOfCars; }

정적 메서드는 유틸리티 또는 도우미 클래스를 만드는데도 널리 사용되므로 이러한 클래스의 새 개체를 만들지 않고도 얻을 수 있습니다.

JDK의 Collections 또는 Math 유틸리티 클래스, Apache의 StringUtils 또는 Spring 프레임 워크의 CollectionUtils를 살펴보면 모든 메서드가 정적 임을 알 수 있습니다.

4.2. 정적 메서드 를 사용하는 강력한 이유

  • 객체에 의존하지 않는 정적 변수 및 기타 정적 메서드에 액세스 / 조작하려면
  • 정적 메서드는 유틸리티 및 도우미 클래스에서 널리 사용됩니다.

4.3. 기억해야 할 요점

  • Java의 정적 메서드는 컴파일 타임에 해결됩니다. 메서드 재정의는 런타임 다형성의 일부 이므로 정적 메서드를 재정의 할 수 없습니다.
  • 추상 메서드는 정적 일 수 없습니다.
  • 정적 메서드는 this 또는 super 키워드를 사용할 수 없습니다.
  • 다음과 같은 인스턴스, 클래스 메서드 및 변수 조합이 유효합니다.
    1. 인스턴스 메서드는 인스턴스 메서드와 인스턴스 변수 모두에 직접 액세스 할 수 있습니다.
    2. 인스턴스 메서드는 정적 변수 및 정적 메서드에 직접 액세스 할 수도 있습니다.
    3. static methods can access all static variables and other static methods
    4. static methods cannot access instance variables and instance methods directly; they need some object reference to do so

5. A static Block

A static block is used for initializing static variables. Although static variables can be initialized directly during declaration, there are situations when we're required to do the multiline processing.

In such cases, static blocks come in handy.

If static variables require additional, multi-statement logic while initialization, then a static block can be used.

5.1. The static Block Example

Suppose we want to initialize a list object with some pre-defined values.

This becomes easy with static blocks:

public class StaticBlockDemo { public static List ranks = new LinkedList(); static { ranks.add("Lieutenant"); ranks.add("Captain"); ranks.add("Major"); } static { ranks.add("Colonel"); ranks.add("General"); } }

In this example, it wouldn't be possible to initialize List object with all the initial values along with declaration; and that's why we've utilized the static block here.

5.2. Compelling Reasons to Use static Blocks

  • If initialization of static variables requires some additional logic except the assignment
  • If the initialization of static variables is error-prone and requires exception handling

5.3. Key Points to Remember

  • A class can have multiple static blocks
  • static fields and static blocks are resolved and executed in the same order as they are present in the class

6. A static Class

Java programming language allows us to create a class within a class. It provides a compelling way of grouping elements that are only going to be used in one place, this helps to keep our code more organized and readable.

The nested class architecture is divided into two:

  • nested classes that are declared static are called static nested classes whereas,
  • nested classes that are non-static are called inner classes

The main difference between these two is that the inner classes have access to all member of the enclosing class (including private), whereas the static nested classes only have access to static members of the outer class.

In fact, static nested classes behaved exactly like any other top-level class but enclosed in the only class which will access it, to provide better packaging convenience.

6.1. Example of static Class

The most widely used approach to create singleton objects is through static nested class is it doesn't require any synchronization and is easy to learn and implement:

public class Singleton { private Singleton() {} private static class SingletonHolder { public static final Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } }

6.2. Compelling Reasons to Use a static Inner Class

  • Grouping classes that will be used only in one place increases encapsulation
  • The code is brought closer to the place that will be only one to use it; this increases readability and code is more maintainable
  • If nested class doesn't require any access to it's enclosing class instance members, then it's better to declare it as static because this way, it won't be coupled to the outer class and hence will be more optimal as they won't require any heap or stack memory

6.3. Key Points to Remember

  • static nested classes do not have access to any instance members of the enclosing outer class; it can only access them through an object's reference
  • 정적 중첩 클래스는 전용 클래스를 포함하여 둘러싸는 클래스의 모든 정적 멤버에 액세스 할 수 있습니다.
  • Java 프로그래밍 사양에서는 최상위 클래스를 정적 으로 선언 할 수 없습니다 . 클래스 내의 클래스 (중첩 된 클래스) 만 정적 으로 만들 수 있습니다.

7. 결론

이 기사에서 우리는 정적 키워드가 작동 하는 것을 보았습니다 . 또한 정적 필드, 정적 메서드, 정적 블록 및 정적 내부 클래스를 사용하는 이유와 이점에 대해서도 읽었습니다.

언제나처럼 GitHub에서 전체 코드를 찾을 수 있습니다.