IT

왜 우리는 Loggers를 static final로 선언합니까?

lottoking 2020. 7. 20. 07:19
반응형

왜 우리는 Loggers를 static final로 선언합니까?


Java에서 로거를 선언하는 것이 가장 좋은 방법은 static final무엇입니까?

private static final Logger S_LOGGER

  • private-다른 클래스가 귀하의 로거를 납치수 있습니다
  • static -클래스 당 하나의 로거 인스턴스 만 있으므로 로거를 만들려는 시도를 피할 수 있습니다.
  • final -수업 기간 동안 로거를 행사 필요가 없습니다.

또한 log가능한 한 단순하면서도 설명적인 이름 선호합니다 .

편집 : 그러나 흥미로운 예외가 있습니다.

protected final Logger log = LoggerFactory.getLogger(getClass());

근처 :

private static final Logger log = LoggerFactory.getLogger(Foo.class);

전자를 사용하면 상속 계층 전체의 모든 클래스에서 동일한 로거 이름 (실제 클래스 이름)을 사용할 수 있습니다. 따라서 Bar확장 Foo하면 Bar로거에 모두 기록 됩니다. 더 많이 인 사람들도 있습니다.


이 블로그 게시물 : Java 정적 로거 제거를 확인하십시오 . 이 jcabi -log 와 함께 slf4j 를 사용하는 방법입니다 .

import com.jcabi.log.Logger;
class Foo {
  void save(File f) {
    Logger.info(this, "file %s saved successfully", f);
  }
}

정적 잡음을 더 이상 사용하지 않습니다.


static클래스의 인스턴스 당 하나의 로거가 아니라 클래스 당 하나의 로거 만 작성 함을 의미합니다 . 로거는 클래스에 따라 달라지는 경향이 있으므로 일반적으로 원하는 것입니다.

finallogger변수 의 값을 변경하지 않을 것임을 의미 합니다. 거의 항상 모든 로그 메시지를 (한 클래스에서) 동일한 로거로 던지기 때문입니다. 드문 경우이지만 클래스가 일부 메시지를 다른 로거에 보내려 widgetDetailLogger는 경우에도 정적 변수의 값을 즉시 변경하지 않고 다른 로거 변수 (예 :)를 작성하는 것이 훨씬 더 명확합니다 .


필드 값을 언제 변경 하시겠습니까?

당신이 무시할 경우 변경하지 않을 경우, 값을 변경하지 않을 경우 변경하지 않을 것입니다.


일반적으로 클래스 이름을 사용하여 기록하도록 로거를 초기화합니다. 즉, 정적이 아닌 경우 클래스의 인스턴스가 많은 각 인스턴스 (메모리 풋 프린트)가있는지만이 로거는 모두 동일한 구성을 공유하고 정확히 동일하게 작동합니다. 그것이 static비트 공동있는 이유 입니다. 각각 또한 Logger클래스 이름으로 초기화 되므로 하위 클래스와의 충돌을 막기 위해 private상속 할 수 없도록 선언합니다 . final당신이 일반적으로 변경하지 않는 것이 포인트에서 유래 Logger하여 (이 경우는 아무도 사용 하지 않는 것이 합리적이다)-그래서 한 번 당신이 초기화-중 실수 또는 개체). 당신이 사용하려는 경우 Logger다른 방법으로 사용 하지 않아도 될 수도 있고 거기에서 사용하는 경우 에도static final 80 %가 로깅을 사용하는 경우 생각합니다.


이 질문에 대답은 "정적"과 "최종"이 무엇인지 스스로에게 물어야합니다.

Logger의 경우 (Log4J Logger 클래스에 대해 이야기합니다 가정) 분류 범주를 원합니다. 이는 한 번만 할당하고 클래스 당 하나 이상의 인스턴스가 필요하지 않다는 사실로 이어질 것입니다. 아마도 한 클래스의 Logger 객체를 다른 클래스에 노출시키는 이유가 없기 때문에 비공개로 만들고 일부 OO 원칙을 지키지 않는 이유는 무엇입니까?

또한 컴파일러는 그 기능을 사용할 수 있습니다. 따라서 코드가 약간 더 잘 수행됩니다. :)


이는 모든 인스턴스에서 공유 할 수있는 기능의 종류이기입니다. 동일한 클래스의 두 인스턴스에 대해 서로 다른 로거를 사용하는 것이 의미가 없습니다 (90 %의 시간).

그러나 단일 톤으로 선언 할 수도 있고 정적 함수를 제공하여 물건을 기록하는 것을 볼 수 있습니다.


Java7 이후 에는 이 코드는 정적 Logger lgr = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); 로거 대신 사용할 수 있습니다 .


대부분의 경우 참조를 변경하지 않습니다 final. 각 클래스 인스턴스마다 별도의 인스턴스가 필요하지 않습니다 static. 그리고 무엇보다 성능을위한 것입니다. 최적화 (최종) 및 메모리 절약 (정적)이 가능합니다.


이상적으로 Logger는 Sonar를 제공하지 않고 호환되는 코드를 제공하기 위해 Java 7까지 다음과 같아야합니다. private : 부모 클래스 외부에서는 액세스 할 수 없습니다. 다른 클래스가 설명을 기록해야하는 경우 자체 로거를 인스턴스화해야합니다. static : 클래스의 인스턴스 (객체)에 의존하지 않습니다. 무엇인가를 로깅 할 때, 물론 정보가 메시지에 제공 될 수있는 상황이 발생하고 함께 로거가 생성하지 않도록 방지 할 수있는 메모리가 많지 않도록 로거를 클래스 레벨에서 작성해야합니다. final : 수업 당 한 번만 작성하십시오.


다른 대답에 주어진 이유 외에도 내가 선호하는 한 가지 이유는 내 로거가 정적이거나 최종적이지 않은 것입니다.

...
public Logger logger = LoggerFactory.getLogger(DataSummary.class);

public String toJson() {
  GsonBuilder gsonBuilder = new GsonBuilder();   
  return gsonBuilder.create().toJsonTree(this).toString();
}
...

어떤 경우에는 (Gson 라이브러리를 사용할 때) stackoverflow 예외가 발생합니다. 내 특정 상황은 비 정적 비 최종 로거를 포함하는 클래스를 인스턴스화하는 것입니다. 그런 다음 GsonBuilder를 호출 한 toJson 메서드를 호출합니다.

...
DataSummary ds = new DataSummary(data);    
System.out.println(ds.toJson());
...

내부 정적 클래스에는 여전히 정적 로거가 필요합니다.

참고 URL : https://stackoverflow.com/questions/6653520/why-do-we-declare-loggers-static-final

반응형