자바 익명 클래스 는 왜 부분 변 수 를 final 로 설명 해 야 합 니까?

4562 단어 자바
1)  프로 그래 밍 언어의 이론 적 으로 부분 내부 류(즉,방법 에 정 의 된 내부 류)는 그 자체 가 방법 내부(형식 매개 변수 정의 처 나 방법 체 에 나타 날 수 있 음)이기 때문에 방문 방법 중의 부분 변수(형식 매개 변수 또는 부분 변수)는 자연의 이치 이다.
2)  왜 JAVA 에 하나의 제한 을 붙 여야 합 니까?final 형의 국부 변수 만 접근 할 수 있 습 니까?
3)  JAVA 언어의 컴 파일 러 디자이너 는 당연히 모두 실현 된다.국부 내부 클래스 가 접근 할 수 있 는 방법 중의 모든 국부 변수(이론 적 으로 이것 은 자 연 스 러 운 요구 이기 때 문).그러나 컴 파일 기술 은 실현 할 수 없 거나 대가 가 매우 높다.
4)  어려움 은 어디 에 있 습 니까?도대체 어디 가 어려워?
     국부 변수의 생명주기 와 국부 내부 류 의 대상 의 생명주기 의 불일치 성!
5)  설정 방법 f 가 호출 되 어 호출 스 택 에서 변 수 를 생 성 했 습 니 다.이 때 부분 내부 클래스 대상 inner 가 생 겼 습 니 다.object,이 부분 변수 i 에 접근 하 였 습 니 다.방법 f()가 실 행 된 후에 부분 변수 i 는 이미 사망 하여 존재 하지 않 습 니 다.단:부분 내부 클래스 대상 inner이 가능 하 다,~할 수 있다,...   계속 존재 합 니 다(이 대상 을 더 이상 인용 하지 않 을 때 만 사망 합 니 다).방법 f()가 실 행 됨 에 따라 사망 하지 않 습 니 다.이때'황당 함'결과 가 나 왔 습 니 다.국부 내부 대상 innerobject 는 존재 하지 않 는 부분 변수 i 에 접근 하려 고 합 니 다!
6)  어떻게 해야만 실현 할 수 있 습 니까?변수 가 final 일 때 final 부분 변 수 를'복사'한 부 를 통 해 복제품 은 국부 내부 의 데이터 구성원 으로 직접 합 니 다.이렇게:국부 내부 류 가 국부 변 수 를 방문 할 때 사실은 이 부분 변수의'복제품'(즉,이 복제품 은 그 부분 변 수 를 대표 합 니 다)을 방문 합 니 다.따라서 스 택 의 진정한 부분 변 수 를 실행 할 때부분 내부 클래스 대상 은 부분 변 수 를 방문 할 수 있 습 니 다.
그렇다면 핵심 적 인 문 제 는'복제품'을 방문 하 는 것 과 진정한 원시 적 인 부분 변 수 를 방문 하 는 것 이다.그 의미 효 과 는 똑 같 을 까?
변수 가 final 일 때 기본 데이터 형식 이 라면 그 값 이 변 하지 않 기 때문에 복제품 은 원시 적 인 양 과 같 습 니 다.의미 효과 가 같 습 니 다.
변수 가 final 일 때 인용 유형 이 라면 인용 값 이 변 하지 않 기 때문에(즉,영원히 같은 대상 을 가리 키 기 때문에)그 복제품 은 원시 적 인 인용 변수 와 마찬가지 로 영원히 같은 대상 을 가리 키 고(final 이기 때문에 보증:이 대상 만 가리 키 고 다른 대상 을 가리 키 지 못 함)국부 내부 클래스 에서 방문 한 복제품 과 방법 코드 에서 방문 한 원시 대상 에 도달 합 니 다.영원히 같은 것 이다.즉,의미 효 과 는 같다.그렇지 않 으 면 방법 에서 원시 변 수 를 바 꾸 고 국부 내부 클래스 에서 복제품 을 바 꿀 때 복제품 은 원시 변수 와 일치 하 는 것 을 보장 할 수 없다.(따라서 복제품 은 원래 같은 변수 여야 한다.)
한 마디 로 이 규정 은 어 쩔 수 없 는 것 이다.또한 프로그램 설계 언어의 디자인 은 실현 기술 의 제한 을 받는다.이것 이 바로 한 예 이다.왜냐하면 나 는 많은 사람들 이 이런 관점 을 가지 고 있 기 때문이다.디자인 과 생각 이 가장 중요 하고 실현 하 는 기술 은 중요 하지 않다.네가 디자인 과 규정 을 만 들 면 모두 실현 할 수 있다.
지금 우리 가 볼 때 만약 에 내 가 하나의 방법 에서 익명 으로 ABSClass 를 호출 하 는 예 를 실현 하려 면:
public static void test(final String s){
     // final String s = "axman";
  ABSClass c = new ABSClass(){
   public void m(){
      int x = s.hashCode();
 
      System.out.println(x);
 
   }
  };
  //    .
 }

코드 를 보면 한 방법 내부 에서 정 의 된 내부 클래스 의 방법 이 외부 방법의 국부 변수 나 방법 파 라미 터 를 방문 하 는 것 은 매우 자 연 스 러 운 일이 지만 내부 클래스 를 컴 파일 할 때 이 변 수 를 어떻게 얻 는가.왜냐하면 내부 클래스 는 그의 생명주기 가 방법 내부 에 있 는 것 을 제외 하고 다른 측면 은 일반 클래스 이기 때문이다.그러면 그 밖의 부분 변수 나 방법 매개 변 수 는 어떻게 내부 클래스 에 접근 합 니까?컴 파 일 러 가 실 현 될 때 실제로 다음 과 같다.
 public static void test(final String s){
     // final String s = "axman";
 
  class OuterClass$1 extends ABSClass{
 
   private final String s;
   public OuterClass$1(String s){
      this.s = s;   
   }
   public void m(){
      int x = s.hashCode();
      System.out.println(x);
   }
  };
  ABSClass c = new OuterClass$1(s);
  //    .
 }

즉,외부 클래스 의 변 수 는 구조 방법의 매개 변수 로 내부 클래스 의 개인 구성원 에 게 전달 된다.
final 이 없다 면:
public static void test(String s){
     // String s = "axman";
  ABSClass c = new ABSClass(){
   public void m(){
     s = "other";
   }
  };
  System.out.println(s);
 }

다음 으로 컴 파일 됩 니 다:
 public static void test(String s){
     // String s = "axman";
  class OuterClass$1 extends ABSClass{
 
   private String s;
   public OuterClass$1(String s){
      this.s = s;   
   }
   public void m(){
     s = "other";
 
   }
  };

   ABSClass c = new OuterClass$1 (s);
  }

내부 클래스 의 s 는'other'를 다시 가리 키 며 test 의 매개 변수 나 외부 정의 에 영향 을 주지 않 습 니 다.마찬가지 로 외부 s 가 내부 클래스 의 s 를 다시 할당 하면 변 하지 않 습 니 다.
니 가 본 건
 public static void test(String s){
     // String s = "axman";
  ABSClass c = new ABSClass(){
   public void m(){
     s = "other";
   }
  };
  System.out.println(s);
 }
 

문법 적 으로 s 입 니 다.내부 클래스 에서 바 뀌 었 지만 결 과 는 같은 s 라 고 생각 하지만 원래 의'axman'입 니 다.
당신 은 이런 결 과 를 받 아들 일 수 있 습 니까?
그래서 final 은 문법 적 으로 실제 두 변수의 일치 성 을 제약 했다(같은 변수 로 표현).
본문 과 전재,원문 참조:
http://www.189works.com/article-97599-1.html

좋은 웹페이지 즐겨찾기