[java] 메서드를 정적으로 선언하면 얻는 이점은 무엇입니까?

최근 Eclipse에서 내 경고를 살펴본 결과 다음과 같은 문제가 발생했습니다.

정적 경고

메서드가 정적으로 선언 될 수 있으면 컴파일러 경고를 제공합니다.

[편집] 개인 및 최종 스트레스와 이클립스 도움말 내 정확한 인용 :

활성화되면 컴파일러는 private 또는 final 이고 정적 멤버 만 참조하는 메서드에 대해 오류 또는 경고를 발행합니다 .

예, 끌 수 있다는 것을 알고 있지만 켜는 이유알고 싶습니다 .

가능한 모든 메서드를 정적으로 선언하는 것이 좋은 이유는 무엇입니까?

성능상의 이점이 있습니까? (모바일 도메인에서)

메서드를 정적으로 지적하면 인스턴스 변수를 사용하지 않으므로 utils 스타일 클래스로 이동할 수 있음을 보여줍니다.

하루가 끝날 때이 기능을 ‘무시’로 설정해야합니까? 아니면 100 개 이상의 경고를 수정해야합니까?

컴파일러가 어쨌든 이러한 메서드를 인라인하기 때문에 이것이 코드 를 더럽히는 추가 키워드라고 생각하십니까 ? (종료 할 수있는 모든 변수를 선언 하지는 않지만 가능합니다 .)



답변

메소드를 작성할 때마다 주어진 범위에서 계약을 이행합니다. 범위가 좁을수록 버그를 작성할 가능성이 줄어 듭니다.

메서드가 정적이면 비 정적 멤버에 액세스 할 수 없습니다. 따라서 범위가 더 좁습니다. 따라서 계약을 이행하기 위해 비 정적 멤버가 필요하지 않고 필요하지 않은 경우 (하위 클래스에서도) 비 정적 멤버가 왜 메서드에 이러한 필드에 대한 액세스 권한을 부여합니까? static이 경우 메서드 를 선언하면 컴파일러에서 사용하지 않을 멤버를 사용하지 않는지 확인할 수 있습니다.

또한 코드를 읽는 사람들이 계약의 성격을 이해하는 데 도움이됩니다.

이것이 static실제로 정적 계약을 구현할 때 메서드를 선언하는 것이 좋은 이유 입니다.

경우에 따라 메서드는 클래스의 인스턴스와 관련된 것을 의미 할 뿐이며 해당 구현은 실제로 비 정적 필드 또는 인스턴스를 사용하지 않습니다. 이 경우 메소드를 표시하지 않습니다 static.

static키워드를 사용하지 않을 경우의 예 :

  • 아무것도하지 않는 확장 후크 (하지만 서브 클래스의 인스턴스 데이터로 뭔가를 할 수 있음)
  • 서브 클래스에서 사용자 정의 할 수있는 매우 간단한 기본 동작입니다.
  • 이벤트 처리기 구현 : 구현은 이벤트 처리기의 클래스에 따라 다르지만 이벤트 처리기 인스턴스의 속성을 사용하지 않습니다.

답변

여기에는 최적화에 대한 개념이 없습니다.

static방법은 static당신이 명시 적으로 인스턴스가 필요하지 않습니다해서 둘러싸는 클래스를 의존하지 않는 방법을 선언하기 때문이다. 따라서 문서에 명시된대로 Eclipse 경고 :

활성화되면 컴파일러는 private 또는 final이고 정적 멤버 만 참조하는 메서드에 대해 오류 또는 경고를 발행합니다.

인스턴스 변수가 필요하지 않고 메서드가 비공개 (외부에서 호출 할 수 없음)이거나 최종 (재정의 할 수 없음) 인 경우 정적 메서드 대신 일반 메서드가되도록 할 이유가 없습니다. 정적 메서드는 더 적은 작업을 수행 할 수 있기 때문에 본질적으로 더 안전합니다 (인스턴스가 필요하지 않으며 암시 적 this개체가 없음).


답변

성능에 대한 정보는 없지만 코드가 유형에 따라 동적 디스패치를 ​​수행 할 필요가 없기 때문에 기껏해야 약간 더 낫다고 생각합니다.

그러나 정적 메서드로 리팩토링하는 것에 대한 훨씬 더 강력한 주장은 현재 정적을 사용하는 것이 나쁜 습관으로 간주된다는 것입니다. 정적 메서드 / 변수는 객체 지향 언어에 잘 통합되지 않으며 제대로 테스트하기 어렵습니다. 이것이 일부 새로운 언어가 정적 메서드 / 변수의 개념을 완전히 포기하거나 OO (예 : 스칼라의 객체)에서 더 잘 작동하는 방식으로 언어로 내재화하려는 이유입니다.

대부분의 경우 매개 변수 만 입력으로 사용하고이를 사용하여 출력을 생성하는 함수를 구현하려면 정적 메서드가 필요합니다 (예 : 유틸리티 / 도우미 함수) 현대 언어에는이를 허용하는 첫 번째 클래스 Function 개념이 있습니다. 필요하지 않습니다. Java 8에는 람다식이 통합되어 있으므로 이미이 방향으로 이동하고 있습니다.


답변

1. 신고 방법static약간의 성능 이점을 제공하지만 더 유용한 것은 객체 인스턴스가 없어도 사용할 수 있다는 것입니다 (예를 들어 팩토리 메서드 또는 싱글 톤을 가져 오는 경우를 생각해보십시오). 또한 메서드의 특성을 알려주는 문서화 목적으로도 사용됩니다. 이 문서화 목적은 코드 독자와 API 사용자에게 메소드의 본질에 대한 즉각적인 힌트를 제공하고 원래 프로그래머에게 사고의 도구 역할을하므로 무시해서는 안됩니다. 의도 된 의미에 대해 명시하면 도움이됩니다. 당신은 또한 똑바로 생각하고 더 나은 품질의 코드를 생성합니다 (나는 개인적인 경험을 기반으로 생각하지만 사람들은 다릅니다). 예를 들어, 유형에서 작동하는 메소드와 유형의 인스턴스에서 작동하는 메소드를 구별하는 것이 논리적이므로 바람직합니다.Jon Skeet의 C # 질문에 대한 의견 ).

static메서드의 또 다른 사용 사례 는 절차 적 프로그래밍 인터페이스를 모방하는 것입니다. java.lang.System.println()클래스와 그 안에있는 메서드 및 속성을 생각하십시오 . 클래스 java.lang.System는 인스턴스화 가능한 개체가 아닌 그룹화 이름 공간처럼 사용됩니다.

2. Eclipse (또는 다른 프로그래밍 된 또는 다른 종류의-생체 구성 또는 비 생체 구성-개체)는 어떤 메서드가 정적으로 선언 될 수 있는지 어떻게 알 수 있습니까? 기본 클래스가 인스턴스 변수에 액세스하지 않거나 비 정적 메서드를 호출하지 않더라도 상속 메커니즘에 의해 상황이 변경 될 수 있습니다. 하위 클래스를 상속하여 메서드를 재정의 할 수없는 경우에만 메서드가 실제로 선언 될 수 있다고 100 % 확실하게 주장 할 수 있습니다 static. 두 가지 경우에 메서드를 재정의하는 것은 정확히 불가능합니다.

  1. private (어떤 서브 클래스도 직접 사용할 수 없으며 원칙적으로도 알지 못함) 또는
  2. final (하위 클래스에서 액세스 할 수 있더라도 인스턴스 데이터 또는 함수를 참조하도록 메서드를 변경할 수있는 방법이 없습니다).

따라서 Eclipse 옵션의 논리입니다.

3. 원본 포스터는 또한 다음과 같이 묻습니다. ” 메서드를 정적으로 지적하면 인스턴스 변수를 사용하지 않으므로 utils 스타일 클래스로 이동할 수 있음을 보여주고 있습니까? “이것은 매우 좋은 점입니다. 때때로 이러한 종류의 설계 변경은 경고로 표시됩니다.

Eclipse를 사용하고 Java로 프로그래밍하는 경우 개인적으로 활성화해야하는 옵션이 매우 유용합니다.


답변

방법의 범위가 어떻게 변경되는지에 대한 Samuel의 답변을 참조하십시오. 이것이 메서드를 정적으로 만드는 주요 측면이라고 생각합니다.

성능에 대해서도 질문했습니다.

정적 메서드를 호출 할 때 매개 변수로 암시 적 “this”참조가 필요하지 않기 때문에 약간의 성능 향상이있을 수 있습니다.

그러나 이러한 성능 영향은 매우 작습니다. 따라서 그것은 모두 범위에 관한 것입니다.


답변

Android 성능 가이드 라인에서 :

가상보다 정적 선호 객체의 필드에 액세스 할 필요가없는 경우 메서드를 정적으로 만드십시오. 호출은 약 15 % -20 % 더 빠릅니다. 또한 메서드 시그니처에서 메서드를 호출해도 개체의 상태를 변경할 수 없다는 것을 알 수 있기 때문에 좋은 방법입니다.

http://developer.android.com/training/articles/perf-tips.html#PreferStatic


답변

음, Eclipse 문서는 문제의 경고에 대해 다음과 같이 말합니다.

메서드는 정적 일 수 있습니다.

활성화되면 컴파일러는 private 또는 final이고 정적 멤버 만 참조하는 메서드에 대해 오류 또는 경고를 발행합니다.

나는 그것이 거의 모든 것을 말한다고 생각합니다. 메서드가 private이고 final이고 static 멤버 만 참조하는 경우 해당 메서드는 static으로 선언 될 수 있으며 이에 따라 정적 콘텐츠에만 액세스 할 것임을 분명히합니다.

솔직히 그 뒤에는 다른 신비한 이유가 없다고 생각합니다.