JavaRush /Java Blog /Random-KO /Java의 정적 수정자에 대한 10가지 참고 사항

Java의 정적 수정자에 대한 10가지 참고 사항

Random-KO 그룹에 게시되었습니다
Java의 static 한정자는 클래스와 직접 연결됩니다. 필드가 정적이면 클래스에 속하고, 메서드가 정적이면 동일합니다. 즉, 클래스에 속합니다. 이를 기반으로 클래스 이름을 사용하여 정적 메서드나 필드에 액세스할 수 있습니다. 예를 들어 Counter 클래스에서 개수 필드가 정적이면 Counter.count와 같은 쿼리를 사용하여 변수에 액세스할 수 있습니다. 설명을 시작하기 전에 정적 이 무엇인지 , Java에서 정적일 수 있는 것이 무엇인지 10 Java의 정적 수정자에 대한 참고 사항 - 1기억해 보겠습니다 . 정적은 필드, 블록, 메서드 또는 내부 클래스에 적용되는 수정자입니다. 이 수정자는 주제가 현재 클래스에 바인딩되어 있음을 나타냅니다.

정적 필드

클래스 수준 변수를 표시할 때 해당 값이 클래스에 속한다는 것을 나타냅니다. 이렇게 하지 않으면 변수 값이 이 클래스를 사용하여 생성된 개체에 바인딩됩니다. 무슨 뜻이에요? 10 Java의 정적 수정자에 대한 참고 사항 - 2그리고 사실은 변수가 정적이 아닌 경우 이 클래스의 각각의 새 객체는 이 변수의 고유한 값을 가지게 되며 이를 변경하여 하나의 객체에서만 이를 변경합니다. 예를 들어, 우리는 비 -정적 변수:
public class Car {
  int km;
}
그런 다음 주요 내용은 다음과 같습니다.
Car orangeCar = new Car();
orangeCar.km = 100;

Car blueCar = new Car();
blueCar.km = 85;

System.out.println("Orange car - " + orangeCar.km);
System.out.println("Blue car - " + blueCar.km);
우리가 얻는 결과는 다음과 같습니다:

Orange car - 100
Blue car - 85
보시다시피 각 개체에는 고유한 변수가 있으며 변경 사항은 이 개체에 대해서만 발생합니다. 음, 정적 변수가 있는 경우 이 전역 값은 모든 사람에게 동일합니다. 이제 정적 변수가 있는 Car가 있습니다.
public class Car {
  static int km;
}
그러면 main의 동일한 코드가 콘솔에 출력됩니다.

Orange car - 85
Blue car - 85
결국, 우리 모두를 위한 하나의 변수가 있고, 매번 이를 변경할 때마다 그렇습니다. 정적 변수는 일반적으로 객체 참조(orangeCar.km)가 아닌 클래스 이름(Car.km)을 통해 액세스됩니다.

정적 블록

일반 및 정적의 두 가지 초기화 블록이 있습니다. 블록은 내부 변수를 초기화하기 위한 것입니다. 블록이 일반이면 객체의 내부 변수가 초기화되지만 정적이면 정적 변수(즉, 클래스 변수)가 할당됩니다. 정적 초기화 블록이 있는 클래스의 예:
public class Car {
  static int km;

  static {
     km = 150;
  }
}

정적 방법

정적 메서드는 객체가 아닌 클래스에도 바인딩된다는 점에서 일반 메서드와 다릅니다. 정적 메서드의 중요한 속성은 정적 변수/메서드에만 액세스할 수 있다는 것입니다. 예를 들어, 메서드 호출을 추적하는 일종의 카운터 역할을 하는 클래스를 살펴보겠습니다.
public class Counter {
  static int count;

  public static void invokeCounter() {
     count++;
     System.out.println("Current counter value - " + count);
  }
}
이것을 메인으로 부르자:
Counter.invokeCounter();
Counter.invokeCounter();
Counter.invokeCounter();
그리고 콘솔에 출력을 얻습니다.

Текущее meaning счётчика - 1
Текущее meaning счётчика - 2
Текущее meaning счётчика - 3

Java의 정적 클래스

내부 클래스만 정적 클래스가 될 수 있습니다. 다시 말하지만, 이 클래스는 외부 클래스에 묶여 있으며, 외부 클래스가 다른 클래스에 상속되면 이 클래스는 상속되지 않습니다. 게다가 이 클래스는 다른 클래스에서 상속될 수 있고 인터페이스를 구현할 수 있는 것처럼 상속될 수 있습니다. 본질적으로 정적 중첩 클래스는 해당 객체가 자신을 생성한 외부 클래스 객체에 대한 참조를 포함하지 않는다는 점을 제외하면 다른 내부 클래스와 다르지 않습니다. 그러나 이는 정적 클래스를 중첩되지 않은 일반 클래스와 가장 유사하게 만듭니다. 유일한 차이점은 다른 클래스에 래핑된다는 것입니다. 어떤 경우에는 외부 클래스의 비공개 정적 변수에 액세스할 수 있기 때문에 이것이 우리에게 이점이 됩니다. 중첩된 정적 클래스의 예:
public class Vehicle {

  public static class Car {
     public int km;
  }
}
이 클래스의 인스턴스를 생성하고 내부 변수의 값을 설정합니다.
Vehicle.Car car = new Vehicle.Car();
car.km = 90;
정적 메소드/변수/클래스를 사용하기 위해 해당 클래스의 객체를 생성할 필요가 없습니다. 물론 접근 수정자를 고려해야 합니다. 예를 들어 필드는 private해당 필드가 선언된 클래스 내에서만 액세스할 수 있습니다. 필드는 protected패키지( package ) 내부의 모든 클래스와 패키지 외부의 모든 상속 클래스에서 사용할 수 있습니다. 자세한 내용은 " 개인 vs 보호 vs 공개 " 기사를 확인하세요 . 카운터를 증가시키는 작업을 수행하는 increment()클래스에 정적 메서드가 있다고 가정합니다 . 이 메소드를 호출하려면 양식 호출을 사용할 수 있습니다 . 정적 필드나 메서드에 액세스하기 위해 클래스를 인스턴스화할 필요가 없습니다 . 이것이 정적 개체와 비정적 개체(클래스 멤버) 간의 근본적인 차이점입니다. 정적 클래스 멤버는 해당 인스턴스가 아닌 클래스에 직접 속한다는 점을 다시 한 번 상기시켜 드리겠습니다. 즉, 정적 변수의 값은 유형의 모든 객체에 대해 동일합니다 . 이 기사의 뒷부분에서는 Java에서 static 수정자를 사용하는 기본 측면과 주요 프로그래밍 개념을 이해하는 데 도움이 되는 몇 가지 기능을 살펴보겠습니다. CountercountCounter.increment()CountercountCounter

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

이 섹션에서는 정적 메서드, 필드 및 클래스 사용에 대한 기본 사항을 살펴보겠습니다. 변수부터 시작해 보겠습니다.
  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), во избежание проблем, например таких How «состояние гонки» (race condition).

  3. Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый an object для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы How нельзя лучше подходят в качестве методов-фабрик (factory), и методов-утorт (utility). Класс java.lang.Math — замечательный пример, в котором почти все методы статичны, по этой же причине классы-утorты в Java финализированы (final).

  4. Другим важным моментом является то, что вы НЕ можете переопределять (Override) статические методы. Если вы объявите такой же метод в классе-наследнике (subclass), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса (superclass) instead of переопределения. Это явление известно How сокрытие методов (hiding methods). Это означает, что при обращении к статическому методу, который объявлен How в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример:

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

    Вывод в консоль:

    Внутри родительского класса/статического метода

    Код наглядно демонстрирует: несмотря на то, что an object имеет тип Car, вызван статический метод из класса Vehicle, т.к. произошло обращение к методу во время компиляции. И заметьте, ошибки во время компиляции не возникло!

  5. Объявить статическим также можно и класс, за исключением классов верхнего уровня. Такие классы известны How «вложенные статические классы» (nested static class). Они бывают полезными для представления улучшенных связей. Яркий пример вложенного статического класса — HashMap.Entry, который предоставляет структуру данных внутри HashMap. Стоит заметить, также How и любой другой внутренний класс, вложенные классы находятся в отдельном файле .class. Таким образом, если вы объявor пять вложенных классов в вашем главном классе, у вас будет 6 файлов с расширением .class. Ещё одним примером использования является объявление собственного компаратора (Comparator), например компаратор по возрасту (AgeComparator) в классе сотрудники (Employee).

  6. Модификатор static также может быть объявлен в статичном блоке, более известным How «Статический блок инициализации» (Static initializer block), который будет выполнен во время загрузки класса. Если вы не объявите такой блок, то Java соберёт все статические поля в один список и выполнит его во время загрузки класса. Однако, статичный блок НЕ может пробросить перехваченные исключения, но может выбросить не перехваченные. В таком случае возникнет «Exception Initializer Error». На практике, любое исключение возникшее во время выполнения и инициализации статических полей, будет завёрнуто Java в эту ошибку. Это также самая частая причина ошибки «No Class Def Found Error», т.к. класс не находился в памяти во время обращения к нему.

  7. Полезно знать, что статические методы связываются во время компиляции, в отличие от связывания виртуальных or не статических методов, которые связываются во время исполнения на реальном an objectе. Следовательно, статические методы не могут быть переопределены в Java, т.к. полиморфизм во время выполнения не распространяется на них. Это важное ограничение, которое необходимо учитывать, объявляя метод статическим. В этом есть смысл, только тогда, когда нет возможности or необходимости переопределения такого метода классами-наследниками. Методы-фабрики и методы-утorты хорошие образцы применения модификатора static. Джошуа Блох выделил несколько преимуществ использования статичного метода-фабрики перед конструктором, в книге «Effective Java», которая является обязательной для прочтения каждым программистом данного языка.

  8. Важным свойством статического блока является инициализация. Статические поля or переменные инициализируются после загрузки класса в память. Порядок инициализации сверху вниз, в том же порядке, в Howом они описаны в исходном файле Java класса. Поскольку статические поля инициализируются на потокобезопасный манер, это свойство также используется для реализации паттерна Singleton. Если вы не используется список Enum How Singleton, по тем or иным причинам, то для вас есть хорошая альтернатива. Но в таком случае необходимо учесть, что это не «ленивая» инициализация. Это означает, что статическое поле будет проинициализировано ещё ДО того How кто-нибудь об этом «попросит». Если an object ресурсоёмкий or редко используется, то инициализация его в статическом блоке сыграет не в вашу пользу.

  9. 직렬화 중에는 변수와 마찬가지로 transient정적 필드도 직렬화되지 않습니다. 실제로 정적 필드에 데이터를 저장하면 역직렬화 후 새 개체에 기본(기본값) 값이 포함됩니다. 예를 들어 정적 필드가 유형의 변수인 경우 역 int직렬화 후 해당 값은 0이 됩니다. – 유형인 경우 유형 float은 0.0입니다 . 솔직히 이것은 Java 인터뷰에서 직렬화와 관련하여 가장 자주 묻는 질문 중 하나입니다. 개체에 대한 가장 중요한 데이터를 정적 필드에 저장하지 마세요!Objectnull

  10. 그리고 마지막으로 에 대해 이야기 해 봅시다 static import. 이 수정자는 표준 연산자와 공통점이 많지만 import, 이와는 달리 클래스의 정적 멤버 하나 또는 전체를 가져올 수 있습니다. 정적 메서드를 가져올 때 동일한 클래스에 정의된 것처럼 액세스할 수 있으며, 마찬가지로 필드를 가져올 때 클래스 이름을 지정하지 않고도 액세스할 수 있습니다. 이 기능은 Java 버전 1.5에서 도입되었으며 올바르게 사용하면 코드 가독성이 향상됩니다. 이 구성은 JUnit 테스트 에서 가장 자주 발견됩니다 . 예를 들어 거의 모든 테스트 개발자는 static importAssert 메서드 assertEquals()와 오버로드된 중복 메서드를 사용합니다. 명확한 내용이 없다면 추가 정보를 제공해 주시기 바랍니다 .

그게 다야. 모든 프로그래머는 Java의 정적 수정자 에 대해 위의 모든 사항을 알아야 합니다 . 이 문서에서는 정적 변수, 필드, 메서드, 초기화 블록 및 가져오기에 대한 기본 정보를 다루었습니다. Java로 프로그램을 작성하고 이해할 때 이에 대한 지식이 중요한 몇 가지 중요한 속성을 포함합니다. 나는 모든 개발자가 정적 개념을 사용하는 기술을 완벽하게 갖추기를 바랍니다. 왜냐하면... 이는 진지한 프로그래밍에 매우 중요합니다."
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION