검수요청.png검수요청.png

"파이널"의 두 판 사이의 차이

위키원
이동: 둘러보기, 검색
(참고자료)
잔글
 
(사용자 2명의 중간 판 9개는 보이지 않습니다)
1번째 줄: 1번째 줄:
'''파이널'''(final)이란 [[객체 지향 프로그래밍]](OOP)에서 더이상 확장하거나 변경할 수 없는 마지막 단계의 [[클래스]]나 [[메소드]] 또는 [[변수]]에 사용하는 [[제어자]]이다. '파이널'이라고 읽는다.
+
'''파이널'''<!--파이날-->(final)이란 [[객체 지향 프로그래밍]](OOP)에서 더이상 확장하거나 변경할 수 없는 마지막 단계의 [[클래스]]나 [[메소드]] 또는 [[변수]]에 사용하는 [[제어자]]이다. '''수정제어자'''<!--수정 제어자-->라고도 한다.
  
 
==개요==
 
==개요==
 +
파이널(final)은 Java에서 오직 한 번만 할당할 수 있는 객체를 정의할 때 사용된다. <ref name="위키피디아">〈[https://en.wikipedia.org/wiki/Final_(Java) final(Java)]〉, 《위키피디아》, 2020-05-11 </ref> 파이널은 크게 3가지 방법으로 클래스, 메소드, 변수에 사용할 수 있다. 클래스에 사용하면 해당 클래스는 다른 클래스가 상속받을 수 없게 되고, 메소드에 사용하면 해당 메소드는 오버라이딩(overriding)을 통해 재정의를 할 수 없고, 필드나 지역 변수에 사용하면 값을 변경할 수 없는 상수가 된다. <ref name="TCPSCHOOL.com">〈[http://tcpschool.com/java/java_modifier_ectModifier 기타 제어자]〉, 《TCPSCHOOL.com》</ref> final을 사용한 메소드와 클래스는 주로 라이브러리 형태의 프로젝트를 작성할 때 사용한다. 라이브러리를 완전히 이해하지 못한 상황에서 재정의를 하게된다면, 에러가 발생할 확률이 높아지기 때문에 원천적으로 수정이 불가능하도록 막아놓기 위해서다. <ref name="Oh! My Library"></ref>
  
 
==특징==
 
==특징==
 +
 
===이용 방법===
 
===이용 방법===
====클래스===
+
====클래스====
클래스에서 파이널(final)을 사용하게되면 그 클래스는 최종상태가 되어 더이상 상속이 불가능하다. <ref name="코딩팩토리">〈[https://coding-factory.tistory.com/525 자바 final의 의미와 사용법]〉, 《개인사이트》, 2020-04-23 </ref> 즉, 선언된 클래스 그대로 사용해야한다. 상속이 불가능하기 때문에 서브클래스도(subclass)도 생성할 수 없다.  <ref name="Oh! My Library">〈[https://library1008.tistory.com/1 Java final 키워드]〉, 《개인블로그》, 2015-02-14</ref> 주로 상수 클래스나 Util형식의 클래스를 final로 선언해서 사용한다. <ref name="Frank's blog">〈[https://blog.advenoh.pe.kr/java/%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C-final%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4/ 자바에서 final에 대한 이해]〉, 《개인블로그》, 2018-09-11</ref>
+
[[클래스]](class)에서 파이널(final)을 사용하게되면 그 클래스는 최종상태가 되어 더이상 상속이 불가능하다. <ref name="코딩팩토리">〈[https://coding-factory.tistory.com/525 자바 final의 의미와 사용법]〉, 《개인사이트》, 2020-04-23 </ref> 즉, 선언된 클래스 그대로 사용해야한다. 상속이 불가능하기 때문에 서브클래스도(subclass)도 생성할 수 없다.  <ref name="Oh! My Library">〈[https://library1008.tistory.com/1 Java final 키워드]〉, 《개인블로그》, 2015-02-14</ref> 주로 상수 클래스나 Util형식의 클래스를 final로 선언해서 사용한다. <ref name="Frank's blog">〈[https://blog.advenoh.pe.kr/java/%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C-final%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4/ 자바에서 final에 대한 이해]〉, 《개인블로그》, 2018-09-11</ref> 이 방법은 보안이나 효율성 측면에서 장점이 있다. <ref name="도더니">〈[https://makemethink.tistory.com/184 final그게뭔데, 어떻게 쓰는건데]〉, 《개인사이트》, 2019-12-13 </ref>
  
;예시
+
;예제
 
  // 클래스를 final로 선언
 
  // 클래스를 final로 선언
 
  final class Coding {
 
  final class Coding {
18번째 줄: 20번째 줄:
  
 
====메소드====
 
====메소드====
 +
[[메소드]](method)에서 파이널(final)을 사용하게 되면 상속받은 클래스에서 [[오버라이딩]](overriding)이 불가능하다. <ref name="Oh! My Library"></ref> 즉, 상속받은 클래스에서 부모의 final 메서드를 재정의할 수 없다. 자신이 생성한 메서드를 변경할 수 없게끔 하고싶을때 사용하며 시스템의 코어부분에서 많이 구현되고 있다. <ref name="코딩팩토리"></ref> 이것은 클래스의 기능이나 일관성에 중요할 수 있는 메소드를 변경하는 하위 클래스의 예기치 않는 행동을 방지하기 위해 사용된다. 대부분 메소드를 final로 선언하면 컴파일러가 호출되는 곳마다 메소드를 직접 삽입할 수 있기 때문에 효율성이 향상된다고 오해한다.
 +
메소드가 런타임에 로드되기 때문에 컴파일러는 이를 수행할 수 없다. 오직 런타임 환경과 JIT 컴파일러만이 어떤 클래스가 로드되었는지 정확히 알고 있기 때문에, 메소드의 final 여부에 관계없이 인라인 시점에 대한 결정을 내릴 수 있다. 플랫폼 별로 직접 실행 가능한 시스템 코드를 생성하는 시스템 코드 컴파일러는 예외다. 정적 링크를 사용할 때 컴파일러는 컴파일 시간에 계산할 수 있는 메소드와 변수가 삽입될 수 있다고 가정할 수 있다.<ref name="wiki">WIKIPEDIA , 〈[https://en.wikipedia.org/wiki/Final_(Java) Final (Java)]〉, 《WIKIPEDIA》, 2020-05-11</ref>
 +
 +
;예제
 +
// 메소드를 final로 선언
 +
class Coding {
 +
    String coding_language = "JAVA";
 +
    public final void print() {
 +
        System.out.println( coding_language + "는 프로그래밍 언어이다.");
 +
    }
 +
}
 +
// final로 선언된 메소드 사용
 +
class test_Coding extends Coding{
 +
    String coding_language = "C";
 +
    // 오버라이딩 불가능
 +
    public void print() {
 +
    }
 +
}
  
 
====변수====
 
====변수====
 +
* 원시 타입
 +
로컬 원시 변수에 파이널(final)로 선언하면 한번 초기화된 변수는 변경할 수 없는 상수값이 된다. <ref name="Frank's blog"></ref>
 +
 +
;예제
 +
public void Test() {
 +
    // final로 선언되어 변경 불가능
 +
    final int x = 5;
 +
}
 +
 +
* 객체 타입
 +
객체 변수에 파이널(final)로 선언하면 해당 변수에 다른 참조값을 지정할 수 없다. 또한 원시 타입과 동일하게 한번 초기화된 변수는 값을 변경할 수 없다. 단, 객체 자체가 변경이 불가능하다는 의미는 아니다. 객체의 속성은 변경이 가능하다. <ref name="Frank's blog"></ref>
 +
 +
;예제
 +
public void Test() {
 +
    // final로 선언된 객체
 +
    final Coding coding = new Coding();
 +
    // final로 선언되어 다른 객체로 변경 불가능
 +
    coding = new Coding();
 +
    // 객체 필드는 변경 가능
 +
    coding.setWeight(5);
 +
}
 +
 +
* 메소드 인자
 +
메소드(method) 인자에 파이널(final)로 선언하면 메소드 안에서 변수값을 변경할 수 없다. <ref name="Frank's blog"></ref>
 +
 +
;예제
 +
public class Coding {
 +
    String coding_language;
 +
    //메서드 인자에 final 선언
 +
    public void setCoding(final int coding_language) {
 +
        // 메서드 안에서 변경 불가능
 +
        conding_language = "JAVA";
 +
    }
 +
}
 +
 +
* 멤버 변수
 +
클래스의 멤버 변수에 final로 선언하면 상수값이 되거나 write-once 필드로 한 번만 쓰이게 된다. 초기화가 되는 시점은 생성자 메소드가 끝나기 전에 초기화 된다. 단, static이 사용되냐 아니냐에 따라 초기화 시점이 바뀌게 된다.
 +
 +
:{|class=wikitable cellpadding="10" cellspacing="0" border="1""
 +
|+ < static의 유무 - 초기화되는 시점 차이 >
 +
!width = "80px"| \
 +
!width ="350px"| static final(정적 초기화)
 +
!width ="350px"| final(인스턴스 초기화)
 +
|-
 +
!width = "80px"|공통점
 +
|width ="350px" colspan="2"| 값과 함께 선언시 초기화
 +
|-
 +
!width = "80px"|차이점
 +
|width ="350px"| '''*''' 정적 초기화 블록에서 초기화
 +
|width ="350px"|'''*''' 인트너스 초기화 블록에서 초기화
 +
'''*'''  생성자 메소드에서 초기화
 +
|}
 +
 
{{각주}}
 
{{각주}}
  
 
==참고자료==
 
==참고자료==
 
* 코딩팩토리, 〈[https://coding-factory.tistory.com/525 자바 final의 의미와 사용법]〉, 2020-04-23
 
* 코딩팩토리, 〈[https://coding-factory.tistory.com/525 자바 final의 의미와 사용법]〉, 2020-04-23
 +
* WIKIPEDIA , 〈[https://en.wikipedia.org/wiki/Final_(Java) Final (Java)]〉, 《WIKIPEDIA》, 2020-05-11
 
* Frank's blog, 〈[https://blog.advenoh.pe.kr/java/%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C-final%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4/ 자바에서 final에 대한 이해]〉, 2018-09-11
 
* Frank's blog, 〈[https://blog.advenoh.pe.kr/java/%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C-final%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4/ 자바에서 final에 대한 이해]〉, 2018-09-11
  

2020년 8월 21일 (금) 09:28 기준 최신판

파이널(final)이란 객체 지향 프로그래밍(OOP)에서 더이상 확장하거나 변경할 수 없는 마지막 단계의 클래스메소드 또는 변수에 사용하는 제어자이다. 수정제어자라고도 한다.

개요[편집]

파이널(final)은 Java에서 오직 한 번만 할당할 수 있는 객체를 정의할 때 사용된다. [1] 파이널은 크게 3가지 방법으로 클래스, 메소드, 변수에 사용할 수 있다. 클래스에 사용하면 해당 클래스는 다른 클래스가 상속받을 수 없게 되고, 메소드에 사용하면 해당 메소드는 오버라이딩(overriding)을 통해 재정의를 할 수 없고, 필드나 지역 변수에 사용하면 값을 변경할 수 없는 상수가 된다. [2] final을 사용한 메소드와 클래스는 주로 라이브러리 형태의 프로젝트를 작성할 때 사용한다. 라이브러리를 완전히 이해하지 못한 상황에서 재정의를 하게된다면, 에러가 발생할 확률이 높아지기 때문에 원천적으로 수정이 불가능하도록 막아놓기 위해서다. [3]

특징[편집]

이용 방법[편집]

클래스[편집]

클래스(class)에서 파이널(final)을 사용하게되면 그 클래스는 최종상태가 되어 더이상 상속이 불가능하다. [4] 즉, 선언된 클래스 그대로 사용해야한다. 상속이 불가능하기 때문에 서브클래스도(subclass)도 생성할 수 없다. [3] 주로 상수 클래스나 Util형식의 클래스를 final로 선언해서 사용한다. [5] 이 방법은 보안이나 효율성 측면에서 장점이 있다. [6]

예제
// 클래스를 final로 선언
final class Coding {
   String coding_language = "JAVA";
}
// 상속 불가능
class test_Coding extends Coding{
}

메소드[편집]

메소드(method)에서 파이널(final)을 사용하게 되면 상속받은 클래스에서 오버라이딩(overriding)이 불가능하다. [3] 즉, 상속받은 클래스에서 부모의 final 메서드를 재정의할 수 없다. 자신이 생성한 메서드를 변경할 수 없게끔 하고싶을때 사용하며 시스템의 코어부분에서 많이 구현되고 있다. [4] 이것은 클래스의 기능이나 일관성에 중요할 수 있는 메소드를 변경하는 하위 클래스의 예기치 않는 행동을 방지하기 위해 사용된다. 대부분 메소드를 final로 선언하면 컴파일러가 호출되는 곳마다 메소드를 직접 삽입할 수 있기 때문에 효율성이 향상된다고 오해한다. 메소드가 런타임에 로드되기 때문에 컴파일러는 이를 수행할 수 없다. 오직 런타임 환경과 JIT 컴파일러만이 어떤 클래스가 로드되었는지 정확히 알고 있기 때문에, 메소드의 final 여부에 관계없이 인라인 시점에 대한 결정을 내릴 수 있다. 플랫폼 별로 직접 실행 가능한 시스템 코드를 생성하는 시스템 코드 컴파일러는 예외다. 정적 링크를 사용할 때 컴파일러는 컴파일 시간에 계산할 수 있는 메소드와 변수가 삽입될 수 있다고 가정할 수 있다.[7]

예제
// 메소드를 final로 선언
class Coding {
   String coding_language = "JAVA";
   public final void print() {
       System.out.println( coding_language + "는 프로그래밍 언어이다.");
   }
}
// final로 선언된 메소드 사용
class test_Coding extends Coding{
   String coding_language = "C";
   // 오버라이딩 불가능
   public void print() {
   }
}

변수[편집]

  • 원시 타입

로컬 원시 변수에 파이널(final)로 선언하면 한번 초기화된 변수는 변경할 수 없는 상수값이 된다. [5]

예제
public void Test() {
    // final로 선언되어 변경 불가능
    final int x = 5;
}
  • 객체 타입

객체 변수에 파이널(final)로 선언하면 해당 변수에 다른 참조값을 지정할 수 없다. 또한 원시 타입과 동일하게 한번 초기화된 변수는 값을 변경할 수 없다. 단, 객체 자체가 변경이 불가능하다는 의미는 아니다. 객체의 속성은 변경이 가능하다. [5]

예제
public void Test() {
    // final로 선언된 객체
    final Coding coding = new Coding();
    // final로 선언되어 다른 객체로 변경 불가능
    coding = new Coding();
    // 객체 필드는 변경 가능
    coding.setWeight(5);
}
  • 메소드 인자

메소드(method) 인자에 파이널(final)로 선언하면 메소드 안에서 변수값을 변경할 수 없다. [5]

예제
public class Coding {
    String coding_language;
    //메서드 인자에 final 선언
    public void setCoding(final int coding_language) {
        // 메서드 안에서 변경 불가능
        conding_language = "JAVA";
    }
}
  • 멤버 변수

클래스의 멤버 변수에 final로 선언하면 상수값이 되거나 write-once 필드로 한 번만 쓰이게 된다. 초기화가 되는 시점은 생성자 메소드가 끝나기 전에 초기화 된다. 단, static이 사용되냐 아니냐에 따라 초기화 시점이 바뀌게 된다.

< static의 유무 - 초기화되는 시점 차이 >
static final(정적 초기화) final(인스턴스 초기화)
공통점 값과 함께 선언시 초기화
차이점 * 정적 초기화 블록에서 초기화 * 인트너스 초기화 블록에서 초기화

* 생성자 메소드에서 초기화

각주[편집]

  1. final(Java)〉, 《위키피디아》, 2020-05-11
  2. 기타 제어자〉, 《TCPSCHOOL.com》
  3. 3.0 3.1 3.2 Java final 키워드〉, 《개인블로그》, 2015-02-14
  4. 4.0 4.1 자바 final의 의미와 사용법〉, 《개인사이트》, 2020-04-23
  5. 5.0 5.1 5.2 5.3 자바에서 final에 대한 이해〉, 《개인블로그》, 2018-09-11
  6. final그게뭔데, 어떻게 쓰는건데〉, 《개인사이트》, 2019-12-13
  7. WIKIPEDIA , 〈Final (Java)〉, 《WIKIPEDIA》, 2020-05-11

참고자료[편집]

같이 보기[편집]


  검수요청.png검수요청.png 이 파이널 문서는 프로그래밍에 관한 글로서 검토가 필요합니다. 위키 문서는 누구든지 자유롭게 편집할 수 있습니다. [편집]을 눌러 문서 내용을 검토·수정해 주세요.