본문 바로가기
knowledge/development

final과 static

by 앙냥냥냥 2020. 7. 15.

static vs final

final

A Java(TM) programming language keyword. You define an entity once and cannot change it or derive from it later. More specifically: a final class cannot be subclassed, a final method cannot be overridden and a final variable cannot change from its initialized value.

class에서의 사용

final로 선언된 class는 extend가 불가능하다. class나 내부의 변수가 immutable해 지는게 아니다.

public final class Greet { }

public class Greet extends GoodMorning { }

이 경우 final class인 greet를 상속할 수 없다는 에러가 뜬다.

error: cannot inherit from final Greet

 

method에서의 사용

final로 선언된 변수는 override가 불가능하다.

public class Greet {
  public final void sayHi() { }
}

public class SayGreet extends Greet {
  public void sayHi() { }
}

에러메시지

overridden method is final

 

변수에서의 사용

final 선언된 변수는 생성자나 대입 연산자를 통해 단 한번만 초기화가 가능함을 의미한다.

primitive 변수

원시변수에 final을 선언하면 변경할 수 없는 값, 상수값이 된다.

final String greet = "hi";
greet = "bye";

이 경우 다음과 같은 에러가 뜬다.

error: cannot assign a value to final variable greet

object 변수

객체를 바라보는 변수에 final을 지정하면, 해당 객체 외의 다른 객체를 바라볼 수 없다.(객체를 바라보는 참조값에 대한 immutable이 걸린 것.) 따라서 객체 자체는 여전히 inmmutable하지 않다.

final Scanner scan = new Scanner(System.in);
scan = new Scanner(System.in);

마찬가지로 final variable에 assign 할 수 없다는 에러가 뜬다.

error: cannot assign a value to final variable scan

method 인자

메소드에서 인자를 받을 때, final을 사용할 수 있다. 이 경우 메소드 내에서 인자값을 변경할 수 없게 한다.

public void testFinal(final String greet) {
  greet = "bye";
}

마찬가지로 final parameter가 assigned 될 수 없다고 함.

error: final parameter greet may not be assigned

class field로써의 final

클래스의 필드를 선언할 때 final을 사용하면 constants or write-once fields가 된다. constants냐 write-once냐는 사실 이 필드(멤버변수)가 이 객체를 serialize 하기 위해 이 필드가 필요한가에 따라서 나뉜다.

따라서, 해당 필드가 필요하다면 static initialize block( static { } 그거다. ) 이나

static final String GREET = "hi";

처럼 선언되는 클래스 내의 constants로 선언하고, 아니라면 인스턴스 생성자나 생성시에 초기화한다.

 

static

A Java(TM) programming language keyword used to define a variable as a class variable. Classes maintain one copy of class variables regardless of how many instances exist of that class. "static" can also be used to define a method as a class method. Class methods are invoked by the class instead of a specific instance, and can only operate on class variables.

static을 사용하면 class 공간에 존재하기 위한 class, method, 변수를 선언할 수 있다.(인스턴스 공간 말고, 클래스 공간)
static 선언 시 runtime시에 메모리에 올라가는 것이 아니라 compile시에 메모리에 올라간다.
또한 heap상에 존재하는 것이 아니라서 garbage collector가 관리하지 못하게 된다.

 

class에서의 사용

다른 어떤 클래스 내에 존재하는 내부클래스를 정의할 때 사용가능하다. inner class가 아니면 static 선언 불가.

class OuterClass {
    class InnerClass { }
    
    static class StaticInnerClass { }
}


static inner class와 그냥 inner class의 차이는,

  • static inner class의 경우, outer class를 인스턴스화 하지 않고 inner class를 인스턴스화 시킬 수 있고 (그냥 inner class의 경우 불가.)
  • static inner class의 경우, outer class의 static member(field)에만 접근할 수 있다. (그냥 inner class의 경우 static, non-static 모두 접근 가능

 

method에서의 사용

static method는 class method라고도 한다. class method의 정의는

A method that is invoked without reference to a particular object. Class methods affect the class as a whole, not a particular instance of the class. Also called a static method.

인스턴스 생성 없이 클래스에서 호출이 가능하다. instance에서도 접근이 가능하기는 하지만, 장려하지 않는다.(나 말고 oracle이) class method 임이 명시되지 않기 때문. class method의 일반적인 용도는 static 변수에 접근하기 위한 것.

instance method는 class 변수 및 class method, instance 변수, (다른) instance method에 직접 접근할 수 있다.
class method는 class 변수 및 class method에 접근할 수 있지만, instance 변수나 instance method에 직접 접근할 수 없다.
(당연한 얘기지만 해당 method가 생성되는 시점에 runtime 시점에 생성되는 instance, instance 변수, instance method가 메모리에 생성되지 않기 때문이다. 마찬가지로 참조할 수 있는 인스턴스가 없으므로 this 키워드를 사용할 수 없다.)

 

변수에서의 사용

A data item associated with a particular class as a whole--not with particular instances of the class. Class variables are defined in class definitions. Also called a static field.

static 변수는 class 변수라고도 한다. class method 처럼 class 공간에 저장하는 변수. 상수를 선언하기 위해 final과 함께 사용하여 정의한다.

static final String GREET = "hi";

 

 

REFERENCE

oracle docs - Glossary of terms
oracle docs - Understanding Class Members
baeldung - The “final” Keyword in Java
GeeksforGeeks - static class in java
Marco Pivetta - When to declare classes final