티스토리 뷰

오늘 작성내용은 final static에 관한 내용입니다.

이전부터 작성해두었는데.. 수정을 이제서야 시작해서 몇 달만에 올리는 건지 ㅠ_ㅠ


우선적으로 final과 static의 일반적인 쓰임에 대해서 보면

final은 상속불가 또는 변할 수 없는 상수 선언에 사용되고static은 공용의 변수를 만들 때 사용되는 예약어라서 

완전 반대의 성격을 띄고 있어 보이는데 이 두가지 예약어가 사용되는 형태가 어떠한지 어떻게 사용해야 하는 지 알아봅시다.

 



 

final

final의 사용범위는 크게 세 가지입니다

변수와 메소드, 그리고 클래스에 사용할 수 있습니다.

 



가장 먼저 제일 많이 사용되는 부분인, 변수 선언에서의 final!

final이라는 뜻이 가지고 있는 것처럼마지막값이 되도록 만들어 줍니다.

final로 선언된 변수는 값을 초기화만 할 수 있고, 그 값의 변경 및 새로운 할당이 불가능 한 상수가 됩니다

(반드시! 초기화하여야 합니다.)


일반적으로 final이 붙은 상수 변수는 static을 함께 붙여서 사용합니다.

 

public class Test {

static final int thisIsFinal = 10;

static int notFinal = 15;


public static void main (String [] args) {

    thisIsFinal = 50;   // 여기서 문제가 발생합니다.

          notFinal = 5;

}

}



위와 같이 정의되어 있는 경우에는

final 상수로 선언한 thisIsFinal에는 값의 새 할당이 불가능하기 때문에

thisIsFinal = 50; 의 라인에서 에러가 발생하게 됩니다.


에러의 내용은 다음과 같습니다.


ð  Test.java:6: cannot assign a value to final variable thisIsfinal

 


 



다음은 클래스명 앞에 final을 붙여서 사용하는 final 클래스

클래스에 final을 사용하게 되면 상속 불가 클래스를 의미합니다.

 

사용방법은 

[final] [접근제한자] 클래스명

 

Final 클래스를 상속받으려는 클래스는 컴파일 시 다음과 같은 에러가 발생합니다.

ð  Cannot inherit from final class

 

또한 class에 붙는 예약어로는 final abstract를 함께 사용할 수 없습니다.

Final은 상속 불가를 나타내는데, abstract는 추상 클래스를 생성할 때 사용하는 내용이므로 

상속이 필수적 (상속 강제) 이기 때문에 서로 배타적인 내용이 됩니다

따라서 이 역시 final, abstract를 함께 사용하게 되면 컴파일 시에 에러가 발생합니다.

ð  Illegal combination of modifiers : abstract and final

 






마지막 final의 사용 영역은 final 메소드입니다.

메소드에 final을 선언하게 되면 그 메소드가 포함된 클래스를 상속받은 클래스에서 

오버라이딩을 통해 재정의 할 수 없는 메소드가 됩니다. 이 역시 final 메소드에 오버라이딩을 시도할 경우 에러가 발생합니다.

 

class PapaClass {

int age = 40;


final String name() {

                   return “아빠!”;

}

}


public class FatherClass extends PapaClass {

String name() { // 여기서 에러 발생

return “아버지~”;

}

}



ð  FatherClass.java:10: name() in FatherClass cannot override name() in PapaClass; overridden method is final

 

 




static

static 역시 세 가지의 용도로 사용됩니다.

 



먼저 익숙하게 사용하고 있는 static 변수의 사용형태에 대해서 봅시다.

일반적인 멤버 변수는 하나의 객체 내에서만 전역 변수처럼 사용되지만

static이 붙은 변수는 클래스의 모든 객체가 공유할 수 있다고 해서 클래스 변수라고도 불립니다.

또한 static 변수는 클래스 객체의 생성 없이도 호출하여 사용할 수 있다는 장점이 있습니다

다른 클래스에서 접근하려는 경우에는, static 변수가 존재하는 클래스 명 뒤에 

(.) 을 찍고 static 변수의 명을 써주면 접근이 가능합니다.

 

 



static 메소드도 존재합니다.

static이 붙은 메소드 역시 클래스 메소드로 불리기도 합니다

이는 어느 객체의 내용에도 의존적이지 않은 하나의 작업을 수행하기 때문인데요

static이 선언된 메소드는 오버라이딩 되지 않고 메소드 숨김이 일어나 상속 받은 클래스에서 사용이 불가능합니다.

클래스 메소드라고 불리는 static 메소드답게, 객체의 레퍼런스를 통한 call이 아닌 클래스의 이름으로 메소드를 호출할 수 있습니다.

 

 



static 초기화블록 (static initial block) 의 형태도 static의 한 형태입니다.

클래스에서 static 키워드만을 사용하여 초기화 블록으로 사용할 수 있습니다.

static 초기화 블록은 클래스가 초기화 될 때 수행되고, main() 메소드보다 먼저 수행된다는 것이 큰 특징입니다.

프로그램 실행 시, 가장 먼저 수행되는 것은 main으로 알고 있었는데

그보다 먼저 수행되는 내용이 있을 수 있다는 것이 신기했습니다~

 

static {

 // 초기화 할 내용 선언

 // main() 보다도 더 먼저 수행되는 내용이 들어갑니다.

}




그리고 추가적으로 static의 사용 형태에 대해서 알게 된 내용이라 덧붙여 써봅니다.


STATIC IMPORT

static import는 다른 클래스에 존재하는 static 멤버들을 불러와서 사용하기 위해 선언합니다. 

이전에 클래스명.static멤버명 과 같이 사용했다면, static import를 통해서 불러왔기 때문에 

클래스명과 점을 통한 호출이 필요 없이 바로 사용할 수 있게 됩니다.


ex) import static packageName.ClassName.staticMemberName


위와 같이 불러들일 특정 static 멤버만을 지정해도 되고,


ex) import static packageName.ClassName.* 

위와 같이 * 를 사용하여 모든 static 멤버를 불러와도 됩니다.


 





드디어 static과 final의 사용 방법에 대해서 정리를 마쳤습니다.

다양한 내용에 대해서 글을 쓰려고 주제는 많이 잡아놨는데 시작을 못하고 있네요.

봄이 아직 멀었나 봅니다. 바람이 많이 부네요.



2012.04 오혜영 작성


댓글
  • 프로필사진 매한가지 감사합니다진짜유용한정보였어욘^^^^ 2012.06.05 23:08
  • 프로필사진 Brad 안녕하세요 글 잘 읽었습니다~!
    오라클에서 지원하는 튜토리얼 따라하다가 궁금한게 생겨서 그러는데요
    public class Card {
    public final int suit;
    public final int rank;

    이런식으로 정의해서 사용하던데
    처음에 초기값을 안주고 이렇게 사용하면...
    아래에 get함수가 있기는 한데
    그걸로 변수 받은후에는
    변동이 불가능한건가요
    아니면 아예 저런식으로 초기값 없이 선언해도 이미 변경이 불가능한건가요?
    클래스 통째로 읽어보면 전자가 맞는거 같은데 혹시나해서요...
    답변 꼭좀 부탁드릴게요!!
    brad.jang.gbc@gmail.com
    2012.11.21 09:41
댓글쓰기 폼