final int num = 10;
num = 11; // 에러
초기값이 곧 최종값이다.
프로그램 실행 도중에 변경 불가능!
"final" = "마지막의", "변경될 수 없는"
public class Person {
final String nation = "Korea"; // 1. 필드 선언 시 주기
final String ssn; // 2. 생성자에게 주기
String name; // 2. 생성자에게 주기
public Person(String ssn, String name) { // 2. 생성자에게 주기
this.ssn = ssn; // ssn은 객체 Person 이 생성될 때, 초기값이 부여됨
this.name = name;
}
}
필드 선언 시 주기
- 단순 값일 경우 사용. 제일 간단함
생성자에게 주기
- 복잡한 초기화 코드 필요한 경우
- 객체 생성 시, 외부 데이터로 초기화 할 경우
// 예시 1
class EX {
final int MAX_SIZE = 10; // 멤버변수 (상수)
final void getMaxSize() {
final int LV = MAX_SIZE; // 지역변수 (상수)
return MAX_SIZE;
}
}
// 예시 2
public class Earth {
static final double EARTH_RADIUS = 6400; // static final (상수)
}
class Company{
String name = "회사명";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Final_ex {
public static void main(String[] args) {
final Company company = new Company();
//company = new Company(); // 객체를 한번 생성했다면 재생성 불가능
company.setName("ex회사"); // 클래스의 필드는 변경가능
}
}
객체 변수에 final 로 선언하면, 그 변수에 다른 참조 값을 지정할 수 없다.
→ 즉, 한번 생성된 final 객체는 같은 타입으로 재생성이 불가능
→ 단, 객체 내부 변수는 변경이 가능
final class Company {
String name = "회사명";
}
// 상속 불가능
class A_Company extends Company {
}
다른 클래그싕 부모 클래스가 될 수 X (= 자식 클래스를 만들 수 X)
class Company{
String name = "회사명";
public final void print() {
System.out.println("회사 이름은 :"+name+" 입니다.");
}
}
class A_Company extends Company{
String name = "a회사";
// 메서드 오버라이드 불가능
public void print() {
}
}
class Company{
String name = "회사명";
public void setName(final String name) {
//name = "ex회사2"; //인자값으로 받은 final변수는 변경 불가능
this.name = name;
}
}
public class Final_ex {
public static void main(String[] args) {
final Company company = new Company();
company.setName("ex회사");
}
}
(잘 사용하지는 않는다.)
아래 코드는 JWTUtil 클래스에서 JWT 데이터를 준비하는 부분이다.
static final 를 사용해서 선언 및 초기화를 해둔 것을 볼 수 있다.
public static final String AUTHORIZATION_HEADER = "Authorization"; // Header KEY 값
public static final String AUTHORIZATION_KEY = "auth"; // 사용자 권한 값의 KEY
public static final String BEARER_PREFIX = "Bearer "; // Token 식별자
private static final long TOKEN_TIME = 60 * 60 * 1000L; // 토큰 만료시간 : 60분
@Value("${jwt.secret.key}") // Base64 Encode 한 SecretKey (application.properties 에 추가해둔 값)
private String secretKey; // 그 값을 가져와서 secretKey 변수에 넣는다
private static Key key; // Secret key 를 담을 변수 // static 을 추가함
private static final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; // 사용할 알고리즘 선택
@PostConstruct // 한 번만 받으면 값을 사용할 때마다, 매번 요청을 새로 호출하는 것을 방지
public void init() {
byte[] bytes = Base64.getDecoder().decode(secretKey); // Base64 를 디코딩
key = Keys.hmacShaKeyFor(bytes);
}