정의: 생성과 동시에 인스턴스 변수를 초기화 하는 메소드
문법
클래스이름() { ... } //매개변수가 없을 때
클래스이름(인수1, 인수2, ...) { ... } //매개변수가 있는 생성자 선언
호출
new 생성자로 인스턴스를 생성할 때 자동으로 호출
상속관계
부모, 자식 클래스에 명시적으로 정의된 생성자가 없는 경우-> 부모클래스에 대한 default 생성자를 자동으로 생성
부모 클래스가 매개변수가 있는 생성자만을 가지고 있는 경우 -> 자식 클래스는 명시적으로 부모 클래스의 매개변수를 가진 생성자를 호출해야 한다.
정의
Java에서 클래스 또는 인스턴스가 생성될 때 특정한 코드 블록이 실행되도록 하는 구조
인스턴스 초기화 블록
단순히 중괄호({})만을 사용하여 정의. 인스턴스가 생성될 때마다 실행됨
클래스 초기화 블록
(static {}) 형태로 정의. 클래스 변수의 초기화를 수행할 때 사용.
클래스가 처음으로 메모리에 로딩될 때 단 한 번만 실행됨
(메모리에 로딩된다는 것은 주로 Method Area에 해당 클래스의 정보가 로드되고 초기화되는 것을 의미)
장점
여러 생성자가 있는 클래스에서 공통적으로 수행되어야 하는 초기화 작업이 있다면, 인스턴스 초기화 블록을 사용하면 중복 코드를 피하고, 여러 생성자 간에 초기화 코드를 공유할 수 있다.
실행 순서
상속시 부모타입 초기화 블록이 먼저 실행> 부모타입 생성자 호출 > 자식타입 초기화 블록 호출 > 자식타입 생성자 호출
배열의 단점
배열은 초기화 할 때 배열의 크기를 미리 정해줘야한다.
저장할 데이터의 양이 가변적일 경우, 대응이 어려워진다.
List의 특징
자바에서 제공하는 컬랙션 중 하나로써, 순서가 있고, 중복을 허용하며, 동적으로 크기 조절이 가능하다.
List 인터페이스의 구현체들
제네릭 타입
List의 경우 제네릭을 통해, List에 담을 객체의 타입을 지정 할 수 있다.
객체 생성시 제네릭타입 자체를 생략하면 타입을 Object로 간주한다.
객체 생성시 제네릭 타입을 비워둘 경우 <> 컴파일러가 타입을 유추하려한다.
제네릭타입 - 타입을 클래스 내부에서 지정하는게 아니라, 생성하는 쪽에서 타입을 지정하는 것
힙(Heap):
객체 인스턴스, 배열 등의 동적으로 할당되는 데이터가 저장됨
스택(Stack):
지역 변수, 메소드 호출, 스레드 정보 등이 저장됩니다.
메소드 영역(Method Area) 또는 Metaspace:
클래스의 바이트코드, 상수, 클래스 변수, 메소드 등의 정보가 저장됨.
클래스를 만들 때 필드의 접근 지정자를 전부 private로 지정하는 경우가 많다.
접근지정자가 private인 필드에 외부에서 값을 넣고 빼기 위한 메소드가 게터 세터 메소드다.
왜 이렇게 번거로운 짓을 할까?
예를들어 사람 객체의 나이 필드에 그동안 한국 나이로 값을 지정했는데, 어제 클라이언트가 갑자기 한국 나이 말고 만나이로 저장하자고 이야기를 했다.
나이 필드에 값을 넣는 로직을 찾아봤더니 전체 클래스에 1000개 이상 되었다. 일일이 찾아서 수정해야 될까?
이럴때 age필드가 private라면, setter과 getter 메소드로 수정범위가 좁아질 것이다.
인스턴스의 멤버필드의 값 저장 방식의 책임을, 오로지 해당 인스턴스만이 지게 되는 것이다.
오류(error)
일반적으로 컴파일 타임에 발생
예외(Exception)
프로그램 실행 중에 발생
예외 처리 문법
try{
예외가 발생 되는 로직
}catch(예외 타입){
해당 예외 발생시 처리 로직
}finally{
모든 경우에 반드시 수행되어야 되는 로직.
리소스 반납 등.
}
0으로 나누기
int 타입을 0으로 나누면 ArithmeticException발생
double 타입을 0으로 나누면 infinity라는 결과값이 나옴
이유) infinity의 실제 데이터가 아래와 같기 떄문
양의 무한대: 부호(0) + 지수(모두 1) + 가수(모두 0)
음의 무한대: 부호(1) + 지수(모두 1) + 가수(모두 0)
에러 메세지 출력방법
System.err.println() 에러메세지로 출력(이클립스에서는 해당 문자가 빨갛게 출력됨)
예외 던지기
예외상황은 메소드에 명시적으로 throws 적지 않아도, 자동으로 호출한 곳으로 전파된다.
throws를 사용하는 이유는 호출한 코드에서 어떤 종류의 예외가 발생할 수 있는지 명시적으로 나타내어, 이에 대한 적절한 예외 처리를 수행할 수 있도록 하기 위함이다.
예외 클래스 상속 구조
