CodeGym /Java Blog /무작위의 /Java의 정적 수정자에 대해 알아야 할 10가지 사항
John Squirrels
레벨 41
San Francisco

Java의 정적 수정자에 대해 알아야 할 10가지 사항

무작위의 그룹에 게시되었습니다
Java에서 정적 수정자는 무언가가 클래스와 직접적으로 관련되어 있음을 의미합니다. 필드가 정적이면 클래스에 속합니다. 메서드가 정적이면 클래스에 속합니다. 따라서 클래스 이름을 사용하여 정적 메서드를 호출하거나 정적 필드를 참조할 수 있습니다. 예를 들어 count필드가 클래스에서 정적 이면 Counter다음 식으로 변수를 참조할 수 있음을 의미합니다. Counter.count. Java의 정적 수정자에 대해 알아야 할 10가지 사항 - 1물론 액세스 한정자를 고려해야 합니다. 예를 들어 private필드는 선언된 클래스 내에서만 사용할 수 있습니다. 필드 protected는 패키지 내의 모든 클래스와 패키지 외부의 모든 하위 클래스에서 사용할 수 있습니다. 클래스 에 작업을 증가시키는 Counter정적 메서드가 있다고 가정합니다.increment()count필드. 이 메서드를 호출하려면 를 사용할 수 있습니다 Counter.increment(). Counter정적 필드 또는 메서드에 액세스하기 위해 클래스 의 인스턴스를 만들 필요가 없습니다 . 이것이 정적(클래스) 변수 및 메서드와 비정적(인스턴스) 변수 및 메서드 간의 근본적인 차이점입니다. 중요한 메모입니다. 클래스의 정적 멤버는 클래스의 인스턴스가 아니라 클래스에 직접 속한다는 점을 잊지 마십시오. 즉, 정적 count변수의 값은 모든 개체에 대해 동일합니다 Counter. 이 기사에서는 Java에서 정적 한정자를 사용하는 기본적인 측면과 주요 프로그래밍 개념을 이해하는 데 도움이 되는 몇 가지 기능을 살펴보겠습니다.

모든 프로그래머가 Java의 정적 수정자에 대해 알아야 할 사항.

이 섹션에서는 정적 메서드, 필드 및 클래스 사용의 주요 측면을 살펴봅니다. 변수부터 시작하겠습니다.
  1. 정적 메서드 또는 블록과 같은 정적 컨텍스트 내에서 클래스의 비정적 멤버에 액세스할 수 없습니다. 아래 코드를 컴파일하면 오류가 발생합니다.

    
    public class Counter {
    private int count;
    public static void main(String args []) {
       System.out.println(count); //  Compile time error
    }
    }
    

    이것은 Java 프로그래머, 특히 초보자가 저지르는 가장 일반적인 실수 중 하나입니다. main메소드는 정적이고 count변수는 정적이 아니기 때문에 메소드 println내부에서 메소드를 사용하면 main"컴파일 시간 오류"가 발생합니다.

  2. thread safe로컬 변수와 달리 정적 필드 및 메서드는 Java에 없습니다 . 실제로 이것은 다중 스레드 프로그래밍에서 보안 문제의 가장 빈번한 원인 중 하나입니다. 클래스의 각 인스턴스가 정적 변수의 동일한 복사본을 참조한다는 점을 고려하면 이러한 변수는 클래스에 의해 보호되거나 "잠겨" 있어야 합니다. 따라서 정적 변수를 사용할 synchronized때는 race conditions.

  3. 정적 메서드는 호출할 때마다 새 객체를 생성할 필요가 없다는 실용적인 이점이 있습니다. 정적 메서드는 선언한 클래스의 이름을 사용하여 호출할 수 있습니다. 그렇기 때문에 이러한 방법은 factory방법과 utility방법에 적합합니다. 클래스 java.lang.Math는 훌륭한 예입니다. 거의 모든 메서드가 정적입니다. finalJava의 유틸리티 클래스도 같은 이유로 표시됩니다 .

  4. @Override또 다른 중요한 점은 정적 메서드를 재정의( )할 수 없다는 것입니다 . 에 그러한 메서드, 즉 동일한 이름과 서명을 가진 메서드를 선언하면 subclass해당 메서드를 superclass재정의하는 대신 "숨기기"만 하면 됩니다. 이 현상은 method hiding. 즉, 정적 메서드가 부모 클래스와 자식 클래스 모두에서 선언되면 호출되는 메서드는 항상 컴파일 타임에 변수 유형을 기반으로 합니다. 메서드 재정의와 달리 이러한 메서드는 프로그램이 실행될 때 실행되지 않습니다. 예를 들어 보겠습니다.

    
    class Vehicle {
         public static void kmToMiles(int km) {
              System.out.println("Inside the parent class / static method");
         } 
    }
    
    class Car extends Vehicle {
         public static void kmToMiles(int km) {
              System.out.println("Inside the child class / static method");
         } 
    }
    
    public class Demo {   
       public static void main(String args []) {
          Vehicle v = new Car();
           v.kmToMiles(10);
      }
    }
    

    콘솔 출력:

    상위 클래스/정적 메소드 내부

    이 코드는 객체가 이라는 사실에도 불구하고 클래스 Car의 정적 메서드가 Vehicle컴파일 타임에 호출되었기 때문에 호출되었음을 분명히 보여줍니다. 그리고 컴파일 오류가 없었습니다!

  5. 또한 최상위 클래스 이외의 클래스를 정적으로 선언할 수 있습니다. 이러한 클래스는 nested static classes. 더 나은 응집력을 제공하는 데 유용합니다. 중첩된 정적 클래스의 놀라운 예는 HashMap.Entry내부의 데이터 구조인 입니다 HashMap. 내부 클래스와 마찬가지로 정적 중첩 클래스는 별도의 .class 파일에서 선언된다는 점은 주목할 가치가 있습니다. 따라서 기본 클래스에서 5개의 중첩 클래스를 선언하면 .class 확장자를 가진 6개의 파일이 생깁니다. 또 다른 예는 클래스 의 나이 비교기( ) Comparator와 같은 우리 자신의 선언입니다 .AgeComparatorEmployee

  6. 정적 수정자는 클래스가 로드될 때 실행되는 "정적 초기화 블록"으로 더 잘 알려진 정적 블록에 지정할 수도 있습니다. 이러한 블록을 선언하지 않으면 Java는 모든 정적 필드를 단일 목록으로 수집하고 클래스가 로드될 때 초기화합니다. 정적 블록은 확인된 예외를 throw할 수 없지만 확인되지 않은 예외는 throw할 수 있습니다. 이 경우 ExceptionInInitializerError발생합니다. 실제로 정적 필드를 초기화하는 동안 발생하는 모든 예외는 Java에 의해 이 오류로 래핑됩니다. NoClassDefFoundError이것은 클래스가 참조될 때 메모리에 있지 않기 때문에 의 가장 일반적인 원인이기도 합니다 .

  7. 실제 개체에서 호출될 때 런타임에 연결되는 가상 또는 비정적 메서드의 연결과 달리 정적 메서드는 컴파일 시간에 연결된다는 점을 아는 것이 유용합니다. 따라서 정적 메서드는 런타임에 다형성이 적용되지 않기 때문에 Java에서 재정의할 수 없습니다. 이는 메서드를 정적으로 선언할 때 고려해야 할 중요한 제한 사항입니다. 그렇게 하는 것은 하위 클래스의 메서드를 재정의할 능력이 없거나 재정의할 필요가 없을 때만 의미가 있습니다. 팩토리 메서드와 유틸리티 메서드는 정적 한정자를 적절하게 사용하는 좋은 예입니다. Joshua Bloch는 모든 Java 프로그래머가 반드시 읽어야 할 저서 Effective Java에서 정적 팩터리 메서드가 구성자에 비해 몇 가지 장점을 지적합니다.

  8. 초기화는 정적 블록의 중요한 측면입니다. 정적 필드 또는 변수는 클래스가 메모리에 로드된 후 초기화됩니다. 초기화 순서는 Java 클래스의 소스 파일에 선언된 순서와 동일하게 위에서 아래로 진행됩니다. 정적 필드는 스레드로부터 안전한 방식으로 초기화되기 때문에 이 프로세스는 Singleton패턴을 구현하는 데에도 사용됩니다. Enum어떤 이유로 as a를 사용하지 않는 경우 Singleton좋은 대안이 있습니다. 그러나 이 경우 "지연" 초기화가 아님을 고려해야 합니다. 이것은 정적 필드가 누군가 "요청"하기 전에 초기화된다는 것을 의미합니다. 개체가 리소스가 많거나 거의 사용되지 않는 경우 정적 블록에서 개체를 초기화하는 것이 유리하지 않습니다.

  9. 직렬화 중에 transient변수와 같은 정적 필드는 직렬화되지 않습니다. 실제로 정적 필드에 데이터를 저장하면 역직렬화 후 초기(기본값) 값이 포함됩니다. 예를 들어 정적 필드가 인 경우 int역직렬화 후 해당 값은 0이 됩니다. 유형이 인 경우 float값은 0.0이 됩니다. 필드가 이면 Object값은 입니다 null. 솔직히 말해서 이것은 Java 직책에 대한 인터뷰에서 직렬화에 대해 가장 자주 묻는 질문 중 하나입니다. 필수 개체 데이터를 정적 필드에 저장하지 마십시오!

  10. 마지막으로 정적 가져오기에 대해 이야기해 보겠습니다. 이 수정자는 표준 문과 공통점이 많지만 import하나 또는 모든 정적 클래스 멤버를 가져올 수 있다는 점에서 다릅니다. 정적 메서드를 가져오면 동일한 클래스에서 선언된 것처럼 액세스할 수 있습니다. 마찬가지로 정적 필드를 가져오면 클래스 이름을 지정하지 않고도 액세스할 수 있습니다. 이 기능은 Java 1.5에 등장했으며 올바르게 사용하면 코드 가독성이 향상됩니다. 이 구성은 JUnit 테스트에서 가장 자주 발견됩니다. 거의 모든 테스트 개발자가 assert 메서드(예: assertEquals()오버로드된 변형)에 대해 정적 가져오기를 사용하기 때문입니다.

  11. 지금은 여기까지입니다. 모든 Java 프로그래머는 위에서 언급한 정적 수정자의 모든 측면을 알아야 합니다. 이 기사에서는 정적 변수, 필드, 메소드, 초기화 블록 및 가져오기에 대한 기본 정보를 검토했습니다. 또한 Java 프로그램을 작성하고 이해하기 위해 알아야 하는 몇 가지 중요한 속성에 대해서도 다루었습니다. 진지한 소프트웨어 개발에 매우 ​​중요하기 때문에 모든 개발자가 정적 멤버를 능숙하게 사용하기를 바랍니다."

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION