2011-11-04 3 views
38

일반적으로 최종 정적 멤버, 특히 변수 (또는 정적 최종 변수는 의미가 겹치지 않고 어느 순서로든 사용할 수 있음)는 Java의 인터페이스와 함께 광범위하게 사용되며 구현 클래스의 프로토콜 동작은 인터페이스를 구현 (상속)하는 클래스가 해당 인터페이스의 모든 구성원을 통합해야 함을 의미합니다.Java의 정적 변수와 정적 변수의 차이점


은 내가 최종최종 정적 멤버를 구별 할 수없는거야. 최종 정적 멤버는 final 또는 다른 것으로 선언 된 정적 멤버 인 멤버입니까? 특정 상황에서 구체적으로 사용해야합니까?


정적 변수 또는 최종 정적 변수는 정적 메서드 내부 나 인스턴스 메서드 내부에서 선언 할 수 없습니다. 왜?

따라서 다음 코드 세그먼트는 컴파일되지 않으며 컴파일 할 때 컴파일러에서 컴파일 할 때 오류가 발생합니다.

public static void main(String args[]) 
{ 
    final int a=0; //ok 

    int b=1; //ok 

    static int c=2; //wrong 

    final static int x=0; //wrong 
} 
+7

static' '필드는 단지 클래스에 따라서 컴파일러 에러가 속할 수있다. 'final'은 첫 번째 초기화 후에 변수가 절대로 변경 될 수 없다는 것을 의미합니다. – brc

+0

@ EJP, 아, 아마도 나는 그 때 착각을합니다. 신경 쓰지 마! – bdonlan

+0

@bdonlan 실제로 인터페이스 변수는 Effective Java에서 안티 패턴으로 구체적으로 언급되었습니다. @EJP, –

답변

115

거대한 혼합 개념을 만들고 있습니다. 제목의 질문조차도 신체의 질문과 일치하지 않습니다.

어쨌든, 이들은 당신이 혼합 된 개념입니다

  • 변수는
  • 최종 변수
  • 필드
  • 최종 필드
  • 정적 필드
  • 최종 정적 필드

키워드 static은 필드에 대해서만 의미가 있지만, 코드에서 필드를 선언 할 수없는 함수 내에서 사용하려고한다는 것을 보여줍니다 (필드는 클래스의 멤버입니다. 변수는 메소드에서 선언됩니다.)

신속하게 설명해 보겠습니다. 방법 선언하고 가변 로컬 스토리지 (int x; x = 5; x++)과 같은 방법에 선언

  • 최종 변수의 일종으로 사용하고 로서 사용된다

    1. 변수 불변의 로컬 스토리지 (final int y; y = 0; y++; // won't compile). 그들은 누군가가 수정해서는 안되는 것을 수정하려고하는 버그를 잡는 데 유용합니다. 개인적으로 로컬 변수 및 메소드 매개 변수 대부분을 final으로 만듭니다. 또한 내부 익명 클래스에서 참조 할 때 필요합니다.어떤 프로그래밍 언어에서 변수의 유일한 종류는 불변 변수입니다 (다른 언어에서는 "기본"종류의 변수는 불변 변수입니다). - 연습으로, 실행하는 루프를 작성하는 방법을 찾으십시오. 초기화 후 아무 것도 변경할 수없는 지정된 횟수 예를 들어 fizzbuzz을 최종 변수 만 사용하여 해결하십시오!). 객체의 가변 상태를 정의하고 클래스 (class x { int myField; })에서 선언

    2. 필드.

    3. 최종 필드 개체의 불변 상태를 정의는 클래스에 선언 생성자 마감재 (class x { final int myField = 5; }) 전에 초기화되어야한다. 그들은 수정할 수 없습니다. 스레드가 스레드간에 객체를 공유하는 것과 관련된 특수한 특성을 가지고 있기 때문에 다중 스레드를 수행 할 때 매우 유용합니다 (생성자가 완료된 후에 객체가 공유되는 경우 모든 스레드가 객체의 최종 필드 값을 올바르게 초기화한다는 것을 보장합니다. 데이터 경주와 공유 되더라도). 다른 연습을 원하면 fizzbuzz을 다시 사용하고 최종 필드 만 사용하고 다른 필드는 사용하지 말고 변수 나 메서드 매개 변수를 사용하지 마십시오. (물론 생성자에서 매개 변수를 선언 할 수 있지만 모두 사용할 수 있습니다!)

    4. 정적 필드는는 모든 클래스의 모든 인스턴스들 사이 을 공유됩니다. 당신은 그것들을 일종의 글로벌 가변 저장 장치 (class x { static int globalField = 5; })라고 생각할 수 있습니다. 가장 간단한 (대개는 쓸데없는) 예제는 객체의 인스턴스를 계산하는 것입니다 (즉, class x { static int count = 0; x() { count++; } }, 여기에서는 생성자가 호출 될 때마다 카운트를 증가시킵니다. 즉, 의 인스턴스를 new x()으로 생성 할 때마다). 최종 필드와는 달리 스레드 안전성이 본질적으로 없다는 점에 유의하십시오. 즉, 다른 스레드에서 인스턴스화하는 경우 위 코드에서 x 인스턴스의 잘못된 개수가 가장 확실하게 발생합니다. 그것을 올바르게하기 위해서는 동기화 메커니즘을 추가하거나이 목적을 위해 특수 클래스를 사용해야합니다. 그러나 이것은 또 다른 질문입니다 (사실, 전체 책의 주제가 될 수 있습니다).

    5. 최종 정적 필드는 전역 상수 (class MyConstants { public static final double PI = 3.1415926535897932384626433; })이다.

    다른 많은 미묘한 특성 (이 있습니다 같은 : 컴파일러는 필드에 반사 쓸모하게 직접 값으로 최종 정적 필드에 대한 참조를 대체 할 자유, 최종 필드는 실제로 반사와 수정 될 수 있지만, 이것은 매우 오류가 발생하기 쉽습니다; 등등), 그러나 나는 당신이 더 깊이 파고 가기 전에 갈 길이 멀다고 말하고 싶습니다.

    마지막으로, 다른 transient, volatile처럼 필드와 함께 사용할 수 있습니다 키워드 및 액세스 레벨 (public, protected, private)이있다. 그러나 그것은 또 다른 질문입니다 (사실, 당신이 그들에 대해 물어보기를 원한다면, 다른 많은 질문들입니다.).

  • +5

    +1 명확하고 좋은 설명! –

    +0

    @Bruno - FizzBuzz는 최종 변수와 최종 필드를 사용하여 구현됩니다. 설명해 주시겠습니까? 고맙습니다. – rtindru

    +0

    @rtindru, 힌트 : 같은 클래스의 새로운 인스턴스를 재귀 적으로 생성하고 재귀 적으로 동일한 메소드를 호출하는 메소드를 가진 클래스에 대해 생각해보십시오. 꽤 고된,하지만할만한. –

    25

    정적 구성원은 개체를 만들지 않고도 액세스 할 수있는 구성원입니다. 이것은 그것들이 클래스 멤버이고 어떤 인스턴스와도 관련이 없다는 것을 의미합니다. 따라서이 방법에서는 정의 할 수 없습니다.

    다른 말로하면,은 상수 (C에서와 같이)입니다. 메소드 내부와 클래스 레벨에서 최종 변수를 가질 수 있습니다. final을 static으로두면 "상수 인 클래스 멤버"이됩니다.

    +6

    +1, 짧고 좋은 설명을 위해 – Naved

    +0

    @downvoters 설명하십시오 – NavSoft

    +1

    * 메서드 내에서 최종 필드를 가질 수 있습니다 * - 메서드 내에서 필드를 선언 할 수 없습니다. 이를 최종 변수라고합니다. –

    1

    나는 최종 및 최종 정적 멤버를 구별 할 수없는거야. 최종 정적 멤버는 정적 멤버가 최종 또는 다른 무언가로 를 선언 된 일입니까? 특정 상황에서 특별히 을 사용해야합니까?

    이되도록하려면 final static을 사용하십시오. static이 아닌 경우 final (비 정적)을 사용하십시오.

    정적 변수 나 최종 정적 변수

    정적 메소드 내부 나 인스턴스 있어서 내부 어느 방법 내측 선언 될 수 없다. 왜?

    디자인 결정. James Gosling에게 묻지 않고 대답 할 방법이 없습니다.

    따라 다음의 코드 세그먼트는 컴파일되지 않고 시도가 이 컴파일하게되는 경우 컴파일 타임 오류는 컴파일러에 의해 발행됩니다.

    당신이 방금 설명한 규칙을 위반 때문입니다.

    1

    최종 키워드는 단순히 "this can not change"를 의미합니다. 메소드의 필드와 변수 모두에서 사용할 수 있습니다. 변수가 final로 선언되면 변수를 변경하려고하면 컴파일 타임 오류가 발생합니다 .For 예를 들어 변수를 final int x = 12로 선언하면; x를 증가 시키려고하면 (++ x) 에러를 발생시킬 것입니다. 간단히 말해서 primitives final은 값을 일정하게 만듭니다. 한편 정적은 필드에만 적용 할 수 있지만 메서드에는 적용 할 수 없습니다. 최종 정적 인 필드에는 하나의 저장소 만 있습니다. 최종 결과는 상수 (변경할 수 없음)를 보여 주며, 정적은 하나만임을 보여줍니다.

    0

    당신은 정적 블록의 정적 필드를 선언 할 수 없습니다 정적 필드는, 클래스에 따라서 컴파일러 오류가 속할 수 있습니다.