final이란?

  final 변수는 값이 변경될 수 없는 상수이다.

  public static final double PI = 3.14;

  이러한 형태로 변수를 final로 선언하며 오직 한번만 값을 할당할 수 있다.

 

  final키워드는 변수, 메서드, 클래스에 적용할 수 있다.

 

 

  final 변수

 

  final 변수는 원시타입, 객체타입, 메서드인자, 멤버변수 이렇게 세부적으로 나눌 수 있다.

 

  원시타입의 경우 로컬 원시 변수에 final로 선언하면 한번 초기화된 변수는 변경할 수 없는 상수값이 된다.

final int x = 1;

x = 3;//오류발생

  이렇게 한번 assign되면 값을 변경할 수 없게 된다.

 

 

  객체타입은 객체변수에 final로 선언하면 그 변수에 다른 참조값을 지정할 수 없다.

  단, 객체 자체가 immutable 하다는 의미는 아니다. 객체의 속성은 변경이 가능하다.

final Pet pet = new Pet();

pet = new Pet(); //다른 객체로 변경할 수 없다.

pet.setWeight(3); //객체필드는 변경이 가능하다.

 

 

  메서드 인자에 final을 붙이면 메서드 안에서 변수값을 변경할 수 없다.

public class Pet {
  
  int weight;
  
  public void setWeight(final int weight) {
    weight = 1; //오류발생
  }
}

 

 

  멤버변수에 final로 선언하면 생성자 호출시 한번만 초기화 할 수 있다는 의미로 사용된다.

  초기화 된 이후에는 읽기만 허용되면 값을 다시 설정할 수 없다.

public class Employer {
  
  protected final int salary;
  
  public Employer() {
    this.salary = 2400;
  }
}

  

  salary 멤버변수에 final 키워드를 명시했기 때문에 생성자에서 한번만 초기화할 수 있고 이후 다른 메서드에서는

  읽기만 할 수 있다.

public class Employer {
  
  protected final int salary;
  
  public Employer() {
    this.salary = 2400;
  }
  
  public int setSalary(int newSalary) {
    this.salary = newSalary;//오류발생
  }
}

public class Employer {
  
  protected final int salary = 1000;
  
  public Employer() {
    this.salary = 2400;//오류발생
  }
}

  이렇게 final 멤버변수로 설정되어있는 salary를 setSalary 메서드로 수정하려고 하면 오류가 발생한다.

  그리고 아래에 있는 클래스처럼 이미 멤버변수에 값이 있는 상태라면 생성자에서도 초기화 할 수 없다.

  이렇게 인스턴스 생성시에 설정되고 바뀌지 않을 값에 final키워드를 붙여주면 의도하지 않은 멤버변수 변경을

  막을 수 있다.

  또한, 변하지 않은 멤버변수를 final로 선언해두면 자바 컴파일러가 해당 멤버변수를 Read-Only로 인식하여

  레지스터 같은 곳에 값을 캐싱 할수도 있어 성능향상을 노려볼 수도 있다.

 

 

  final 메서드

  메서드를 final로 선언하면 상속받은 클래스에서 오버라이드가 불가능해진다.

  구현한 코드를 하위클래스에서 변경하지 않도록 할 때 사용한다.

public Class Pet {
  public final void makeSound() {
    System.out.println("bark!");
  }
  
  public void walk() {
    System.out.println("walk");
  }
}


//subClass
public Class Dog extends Pet {
  
  @Override
  public void makeSound() {
    System.out.println("bark!!");
  } //오류발생
  
  @Override
  public void walk() {
    System.out.println("run!");
  }
}

 

  위와같이 final로 선언된 makeSound는 재정의 할 수없다.

  이렇게 재정의하면 안되는 메서드인 경우는 final로 막아줄 수 있다.

 

 

  final 클래스

  클래스에 final을 선언하면 상속자체가 안된다. 클래스 그대로 사용해야 하고 Util형식의 클래스나 여러 상수값을

  모아둔 Constants 클래스를 final로 사용한다.

public class Pet{

}


//Sub class
public class Dog extends Pet{

} //오류발생

 

  final 클래스 상수클래스

  상수값을 모아준 클래스는 굳이 상속할 이유가 없다.

public final class Constants {
  public static final int SIZE = 10;
}

 

  final 클래스 Util 형식 클래스

  JDK에서 String도 fianl클래스로 선언되어 있다. 자바의 코어 라이브러리이기 때문에 side-effect가 있으면 안되기

  때문이다. 다른 개발자가 상속해서 새로운 SubString을 만들어 다른곳에서 사용하게 되면 유지보수나 정상실행이

  어려워 질수 있다.

public final class String
  implements java.io.Serializable, Comparable<String>, CharSequence {
  
}

 

 

 

 

레퍼런스

 패스트캠퍼스 올인원 패키지 - 자바 객체지향프로그래밍

soft.plusblog.co.kr/m/2

advenoh.tistory.com/13

'JAVA' 카테고리의 다른 글

Class 클래스  (0) 2021.02.04
Object 클래스  (0) 2021.02.03
템플릿 메서드(Template Method)  (0) 2021.02.02
싱글톤 패턴(Singleton Pattern)  (0) 2021.02.01
인터페이스(Interface)  (0) 2021.01.31

+ Recent posts