Java 대상 프로그래밍에서의 final 키워드 사용 방법 상세 설명

5071 단어 Javafinal
자바에서final 키워드를 통해 대상이 불변성(immutable)을 가지고 있음을 설명합니다. 이 대상은 변수, 방법, 클래스를 포함하고 C++의const 키워드 효과와 유사합니다.
immutable은 대상이 생성된 후 상태를 바꿀 수 없음을 가리킨다
세 가지 측면에서 final 키워드를 사용할 수 있습니다.
  • 코드 자체:final이 기술한 대상이 나타내는 의미가 바뀌기를 원하지 않는다
  • 안전:final 대상은 읽기 전용 속성을 가지고 라인 안전
  • 효율:final 대상 자체를 수정할 수 없고 인용하는 작업이 더욱 효율적이다
  • final 변수
    final Object a를 정의하면 a는 한 번만 초기화됩니다. 초기화되면 a의 데이터는 수정할 수 없습니다. 만약에 a가 인용 형식이라면 다른 대상을 다시 연결할 수 없습니다.
    초기화되지 않은final 변수는blankfinal라고 불리며, 구성원 변수라면 초기화되거나 구조기에 값을 부여해야 합니다.
    예:
    
    class Circle {
     static final double PI = 3.1415926;
     final int radius = 5;
     final int xPos;
     final int yPos;
     public Circle(int x, int y) {
     xPos = x; 
     yPos = y;
     }
    }
    
    final 방법
    final method를 정의하면 이 방법은 다시 불러올 수 없습니다. 방법 디자이너는 방법에 대한 재부팅으로 인해 다른 관련 기능에 이상이 생기기를 원하지 않습니다.
    예:
    
    class BaseClass {
     public final void method() {}
    }
    
    class DerivedClass extends BaseClass {
     public final void method() {} //  
    }
    
    
    주의해야 할 것은final 방법의 정의가 반드시 inline 효과를 낼 수 있는 것은 아니다. 왜냐하면 방법의 inline 여부는 JVM의 전략에 달려 있기 때문에final 키워드가 아니라final의 디자인을 통해 방법의 효율을 높이는 것은 정확하지 않다.
    final 클래스
    final class X가 정의한 클래스 X는 계승할 수 없습니다.
    Java에서 String 클래스는final로 설계되었으며 정의는 다음과 같습니다.

    public class final String extends Object  implements Serializable, Comparable<String>, CharSequence
    왜 String이 final로 설계되었습니까?
  • 하나의 String 클래스의 실례가 초기화되면 쌓인 내용을 바꿀 수 없다. String 클래스가 제공하는 모든 String 대상을 수정하는 방법은 새로운 String 대상만 생성할 수 있고 String에 대한 조작을 크게 간소화하며 코드를 더욱 쉽게 읽고 이해할 수 있다.
  • Stringfinal은 Stringinterning(메모리에 다른string값은 하나밖에 없음)을 실현하는 필수 조건이다. 일반적인 코드에 대량의 String 대상이 존재하기 때문에 서로 다른 인용은 같은 문자열 공간을 가리킨다. 만약에 String이final이 아니라면 문자열 공간의 내용이 바뀔 때 모든 인용은 이 상황을 알아야 한다. 이 메커니즘의 실현은 매우 복잡하고 효율에 영향을 미칠 것이다.String interning은 메모리 공간을 절약할 수 있을 뿐만 아니라 시간도 절약할 수 있다.
  • String은 읽기만 하면 중요한 내용이 왜곡될 염려가 없습니다.
  • 내부 클래스와final
    한 방법에서 익명 내부 클래스를 정의할 때 내부 클래스는 방법 내final 형식 변수에만 접근할 수 있기 때문에 자바 컴파일러는 변수의 값을 미리 포획하고 내부 클래스에 복사본을 저장할 수 있다. 방법이 삭제되었을 때 내부 클래스의 메모리 공간은 여전히 완전하다.
    예:
    
    public class Wrapper {
    
      public static void main(String[] args) {
       
        // Object obj = null; // 
        final Object obj = null;
        new Thread(new Runnable() {
         public void run() {
         obj = "hello";
         }
        }).start();
      }
    }
    
    
    PS: 내부 익명 클래스에서 외부 비final 변수에 접근할 수 없는 문제
    이것은 듣기에 좀 까다롭다. 사실 나는 자바 내부류의 일부 특성을 말하고 싶다.
    이 제목이 생각나는 이유는 최근에 JDK 원본 코드에서 HTTPkeepalive에 관한 코드를 읽었을 때 원본 파일 중 하나인sun.net.www.protocol.http.HttpURLConnection.자바는 무의식중에 아래의 코드를 보았다.
    
    final boolean result[] = {false};
    java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {
      public Object run() {
        try {
          InetAddress a1 = InetAddress.getByName(h1);
          InetAddress a2 = InetAddress.getByName(h2);
          result[0] = a1.equals(a2);
        } catch (UnknownHostException e) {
        } catch (SecurityException e) {
        }
        return null;
      }
    });
    
    return result[0];
    
    
    자바의 익명 내부 클래스는 대응하는 함수의 비final 변수에 접근할 수 없습니다.외부의localvariable에 접근하려면 이variable는fianl로 정의해야 하지만final로 정의하면 익명 내부 클래스에서 이 변수의 값을 수정할 수 없기 때문에 익명 내부 클래스가 유용한 값을 되돌려주는 것은 쉽지 않습니다.이 코드는 매우 교묘한 방법을 사용합니다. 여기는 수조의 방식으로 이 제한을 우회합니다. 비록 우리는result라는 변수의 인용을 수정할 수 없지만, 우리는result가 가리키는 그 수조의 내용을 수정할 수 있습니다.
    단지 내부 익명류가 외부 변수를 수정하는 작은 기교를 기록하고 싶을 뿐이다.하지만 여기까지 왔으니 내부류에 어떤 특성이나 제한이 있는지 계속 살펴보자.
    본문을 계속하기 전에 저는 본고에 언급된 자바 용어를 명확하게 해야 한다고 생각합니다. 이런 용어들은 중국어로 번역하기가 쉽지 않기 때문에 우리는 영어로 묘사합니다.
    
    // This is class
    public class JavaTerm {
    
      // field or member variable
      private int field;
    
      // constructor
      public JavaTerm() {
      }
    
      // method
      public void method() {
    
        // local variable
        int localVariable = 0;
    
        // local class
        class LocalClass {
          public LocalClass() {
          }
        }
        // anonymous class
        new Runnable() {
          public void run() {
          }
        };
      }
    }
    
    
    우리는 오늘 더 많은localclass와anonymousclass에 관심을 가질 것이다. 그들은 모두 innerclass에 속한다.
    Java는 우리가class에서 하나의 클래스를 다시 정의할 수 있도록 합니다. 이것은 플러그인 클래스(nestedclass)라고 하고,nestedclass는 두 종류로 나눌 수 있습니다. 하나는 staticnestedclass이고, 다른 하나는 non-staticnestedclass이며, innerclass라고도 합니다.innerclass는localclass와anonymousclass로 나눌 수 있습니다.
    anonymous class의 제한 사항
  • anonymousclass는 클래스를 포함하는 클래스 변수에 접근할 수 있습니다 (field/member variable)
  • anonymousclass는final이 아닌 로컬 변수
  • 에 대한 역할을 포함하는 anonymousclass에 접근할 수 없습니다.
  • nestedclass와 같이anonymousclass에서 정의한variable는 이 내부 클래스를 포함하는 작용역의 동명의variable
  • 을 덮어씁니다.
  • 정적 초기화 방법을 정의할 수 없습니다
  • anonymousclass는 정적 구성원 변수를 가지고 있다.이 구성원 변수는 반드시 상량이어야 한다.
  • anonymousclass 하나에 구조 함수가 있으면 안 된다
  • 좋은 웹페이지 즐겨찾기