반응형
Final의 정의
자료형에 값을 단 한번만 설정할수 있게 강제하는 키워드 즉, 값을 한번 설정하면 그 값을 다시 설정할 수 없다
public class Sample {
public static void main(String[] args) {
final int n = 123; // final 로 설정하면 값을 바꿀수 없다.
n = 456; // 컴파일 에러 발생
}
}
한 번만 할당 가능하다는 선언. 재할당하려고 하면, 컴파일 오류가 발생하여 바로 확인이 가능.
final은 프로그램 수행 도중 그 값이 변경되면 안되는 상황에 사용한다.
Final 변수
- 변수에 final을 붙이면 이 변수는 수정할 수 없다는 의미.
- 수정될 수 없기 때문에 초기화 필수.
- final 키워드가 붙은 변수는 초기화 후 변경 불가. 다음과 같이 변경하려고 하면 컴파일 에러가 발생!
final String hello = "Hello world";
hello = "See you around"// compile error!
수정 불가의 범위
- 그 변수의 값에 한정.
- 다른 객체 참조 시 객체 내부의 값은 변경 가능.
- 기본형 변수: 값 변경 불가
- 참조형 변수: 객체 내부의 값 변경 가능, 가리키는 객체 변경 불가능. →set을 통해 값 변경 가능. 재 할당 불가능!
public class Service {
public void variableFinal() {
final int value = 2;
final Person person = new Person("사바라다", 29);
System.out.println("value = " + value);
System.out.println("person_1 = " + person);
// value = 5; // 컴파일 에러 - 기본형 변수 값 변경 불가
person.setAge(10);
person.setName("사바라");
System.out.println("person_2 = " + person);
// person = new Person("염광호", 29); // 컴파일 에러
}
}
class Person {
private String name;
private int age;
//.. get, set, toString 메서드 존재하나 길이상 생략
}
- stack 메모리에서 기본형 변수는 **값(2)**를 가지고, 참조형 변수는 객체의 주소를 가짐.
- 객체 내부의 값은 final 영향 밖에 있어 변경 가능!
- 리스트의 경우, final로 선언시 재할당 불가
- 리스트 또한 참조형 변수이므로, 리스트에 값을 더하거나(add) 빼는(remove) 것, 내부 값 변경은 가능
- 재할당만 불가능
- 만약 그 값을 더하거나 빼는 것도 불가능하게 하고 싶은 경우에는 List.of로 수정이 불가능한 리스트(Unmodifiable List)를 사용
import java.util.ArrayList;
import java.util.Arrays;
public class Sample {
public static void main(String[] args) {
final ArrayList<String> a = new ArrayList<>(Arrays.asList("a", "b"));
// 컴파일 에러 발생
a = new ArrayList<>(Arrays.asList("c", "d"));
}
}
import java.util.List;
public class Sample {
public static void main(String[] args) {
final List<String> a = List.of("a", "b");
a.add("c"); // UnsupportedOperationException 발생
}
}
초기화
- 변수를 final로 선언 시 초기화 전에 사용하면 컴파일 에러 발생.
- 메서드 내부 변수의 초기화 방법
- 선언시 초기화
- 사용하기 전 초기화
public void variableFinal() { //선언시 초기화 final int value_1 = 2; final int value_2; System.out.println("value = " + value_1); //사용하기 전 초기화 value_2 = 3; System.out.println("person_2 = " + value_2); }
- 객체 멤버 변수의 초기화 방법
- 선언시 초기화
- 생성자를 이용한 초기화
- 초기화 block을 이용한 초기화
public void variableFinal() { Person person = new Person("사바라다"); System.out.println("person = " + person); } class Person { private final String name; //초기화 블록을 이용한 초기화 private final int age; { age = 10; } //선언시 초기화 private final String email = "abab@naver.com"; //생성자를 이용한 초기화 public Person(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\\'' + ", age=" + age + ", email='" + email + '\\'' + '}'; } }
- static 변수의 초기화 방법
- 선언시 초기화
- static 초기화 block을 이용한 초기화
class Person { //선언시 초기화 private static final String DEFAULT_NAME = "보경"; //static 초기화 block을 이용한 초기화 private static final int DEFAULT_AGE; static { DEFAULT_AGE = 10; }
Final 인자(arguments)
- 메소드 내에서 변경이 불가능
- 따라서 다음과 같이 final int로 선언한 number는 읽을 수 있지만, number = 2처럼 값을 변경하려고 하면 컴파일 에러가 발생한다.
public void func(final int number) {
System.out.println(number);
// number = 2; compile error!
}
Final 클래스(class)
- final 키워드를 클래스에 붙이면 상속 불가능
- 다른 클래스에서 상속하여 재정의 불가.
- ex) Wrapper클래스(Integer): 클래스 설계시 재정의 불가능하게 사용.
final class finalclass{
final String hello;
finalclass() {
hello = "hello world";
}
}
//컴파일 에러 발생
class finalfinaclass extends finalclass() {
}
Final 메소드(method)
- Override 불가
class finalclass{
final String hello = "hello world";
final String getHello() {
return hello;
}
}
class finalfinalclass extends finalclass{
@Override
String getHello() { //컴파일 에러
return "See you";
}
}
Final의 효과/사용 이유
효과
서비스 안정성이 높아진다.
- 버그 발생 가능성이 줄어든다.
- 버그를 찾는 시검이 빨라진다.(컴파일 오류)
- 코드 품질이 높아져 변화에 좀 더 빠르게 대응할 수 있다.
불변 객체
- 한 번 생성되면 상태를 수정할 수 없는 객체 → 생성이 된 불변 객체는 신뢰할 수 있다.
- 스레드 동기화 문제 방지
- 돈 넣을 때마다 새로운 객체 생성 → 여러 스레드 동시에 사용해도 신뢰 가능.
불변 객체 사용이유
- 한번 생성되면 상태를 수정할 수 없는 객체 -> 생성이 된 불변 객체는 신뢰할 수 있다.
- 아래와 같이 작성시 실수 할 확률이 적어진다.
public int addFromTo(final int a, final int b){ return addFromOneTo(b) - addFromOneTo(a-1); } public int addFromOneTo(final int n){ return (n * (n + 1)) / 2; }
- public int addFromTo(final int a, final int b){ int sum = 0; for (int i = a; i < b ; i++) { //b까지 더해야하는데, 실수 발생 sun += i; } return sum; }
- 스레드 동기화 문제를, 오류 방지를 사전에 할 수 있다.
- 값 타입(VO)은 불변 객체(immutable object)로 설계해야한다!
Final 클래스(class)
- final 키워드를 클래스에 붙이면 상속 불가능
- 다른 클래스에서 상속하여 재정의 불가.
- ex) Wrapper클래스(Integer): 클래스 설계시 재정의 불가능하게 사용.
final class finalclass{
final String hello;
finalclass() {
hello = "hello world";
}
}
//컴파일 에러 발생
class finalfinaclass extends finalclass() {
}
Final 메소드(method)
- Override 불가
class finalclass{
final String hello = "hello world";
final String getHello() {
return hello;
}
}
class finalfinalclass extends finalclass{
@Override
String getHello() { //컴파일 에러
return "See you";
}
}
Final의 효과/사용 이유
효과
서비스 안정성이 높아진다.
- 버그 발생 가능성이 줄어든다.
- 버그를 찾는 시검이 빨라진다.(컴파일 오류)
- 코드 품질이 높아져 변화에 좀 더 빠르게 대응할 수 있다.
불변 객체
- 한 번 생성되면 상태를 수정할 수 없는 객체 → 생성이 된 불변 객체는 신뢰할 수 있다.
- 스레드 동기화 문제 방지
- 돈 넣을 때마다 새로운 객체 생성 → 여러 스레드 동시에 사용해도 신뢰 가능.
불변 객체 사용이유
- 한번 생성되면 상태를 수정할 수 없는 객체 -> 생성이 된 불변 객체는 신뢰할 수 있다.
- 아래와 같이 작성시 실수 할 확률이 적어진다.
public int addFromTo(final int a, final int b){ return addFromOneTo(b) - addFromOneTo(a-1); } public int addFromOneTo(final int n){ return (n * (n + 1)) / 2; }
- public int addFromTo(final int a, final int b){ int sum = 0; for (int i = a; i < b ; i++) { //b까지 더해야하는데, 실수 발생 sun += i; } return sum; }
- 스레드 동기화 문제를, 오류 방지를 사전에 할 수 있다.
- 값 타입(VO)은 불변 객체(immutable object)로 설계해야한다!
Final 클래스(class)
- final 키워드를 클래스에 붙이면 상속 불가능
- 다른 클래스에서 상속하여 재정의 불가.
- ex) Wrapper클래스(Integer): 클래스 설계시 재정의 불가능하게 사용.
final class finalclass{
final String hello;
finalclass() {
hello = "hello world";
}
}
//컴파일 에러 발생
class finalfinaclass extends finalclass() {
}
Final 메소드(method)
- Override 불가
class finalclass{
final String hello = "hello world";
final String getHello() {
return hello;
}
}
class finalfinalclass extends finalclass{
@Override
String getHello() { //컴파일 에러
return "See you";
}
}
Final의 효과/사용 이유
효과
서비스 안정성이 높아진다.
- 버그 발생 가능성이 줄어든다.
- 버그를 찾는 시검이 빨라진다.(컴파일 오류)
- 코드 품질이 높아져 변화에 좀 더 빠르게 대응할 수 있다.
불변 객체
- 한 번 생성되면 상태를 수정할 수 없는 객체 → 생성이 된 불변 객체는 신뢰할 수 있다.
- 스레드 동기화 문제 방지
불변 객체 사용이유
- 한번 생성되면 상태를 수정할 수 없는 객체 -> 생성이 된 불변 객체는 신뢰할 수 있다.
- for 문을 통해 합을 구하는 것 보다 아래와 같이 작성시 실수 할 확률이 적어진다.
public int addFromTo(final int a, final int b){ return addFromOneTo(b) - addFromOneTo(a-1); } public int addFromOneTo(final int n){ return (n * (n + 1)) / 2; }
- 스레드 동기화 문제를, 오류 방지를 사전에 할 수 있다.
- 값 타입(VO)은 불변 객체(immutable object)로 설계해야한다!
- 출처
반응형
'코딩기록 > CS' 카테고리의 다른 글
왜 싱글톤 패턴을 사용할까? (0) | 2023.11.13 |
---|---|
[운영체제] 메모리의 연속 할당 방식 (0) | 2023.04.13 |
[네트워크] DHCP(Dynamic Host Configuration Protocol) (0) | 2023.04.05 |
[네트워크] [모든 개발자를 위한 HTTP 웹 기본 지식(김영한)] 1 (0) | 2023.03.22 |
[OS] 프로세스 스케줄링 알고리즘 (1) | 2023.03.13 |