[Java의 정석 I] 배열, 객체지향 프로그래밍 I
1권 - Chapter 5 ~ 6
Chapter 5. 배열
-
for 문
을 통해 배열을 복사하는 것 보다,System.arraycopy()
-
String 클래스
는char 배열
에 기능(메서드)을 추가한 것이다.- 문자열을 단순히 문자의 배열로 정의하지 않고 클래스로 정의한 이유는
문자열과 문자열을 다루는데 필요한 함수들을 함께 묶기 위해서
이다. -
char 배열
과String 클래스
의 한가지 중요한 차이가String 객체
는read
만 가능하고, 내용을 변경할 수는 없다. - 변경 가능한 문자열을 다루려면
StringBuffer 클래스
를 사용하자.
- 문자열을 단순히 문자의 배열로 정의하지 않고 클래스로 정의한 이유는
-
JVM
은 입력된 매개변수가 없을 때,null
대신 크기가 0인 배열을 생성해서args
에 전달하도록 구현되어 있다.
Chapter 6. 객체지향 프로그래밍 I
-
클래스
는객체
를 정의해 놓은 것이다. - 프로그래밍에서의
객체
는클래스에 정의된 내용대로 메모리에 생성된 것
// 이렇게 구현하면 power의 값이 true면 false로, false면 true로 변경하도록 구현 가능하다.
void power() { power = !power; }
Tv t; // 메모리에 참조변수 t를 위한 공간이 할당됨.
t = new Tv(); // Tv클래스의 인스턴스가 메모리의 빈 공간에 생성된다.
- 자신을 참조하고 있는 참조변수가 하나도 없는 인스턴스는
가비지 컬렉터(Garbage Collector)
에 의해서 자동적으로메모리
에서 제거된다. - 인스턴스는
독립적인 저장공간
을 가지므로 서로 다른 값을 가지고 있다. 인스턴스 마다고유한 상태를 유지해야 하는 속성의 경우
는인스턴스 변수
로 선언한다. - 클래스 변수는
모든 인스턴스가 공통된 저장공간(변수)을 공유
한다. 클래스가메모리에 로딩(loading)
될 때 생성되어 프로그램 이 종료될 때 까지 유지된다.public
으로 선언하면 같은 프로그램 내에서 어디서나 접근할 수 있는전역변수(global variable)
성격을 가진다.- ex. Card 클래스는 자신만의
무늬(kind)
와숫자(number)
를 가지지만, 모든 카드는 같은폭(width)
과높이(height)
를 가진다.
- ex. Card 클래스는 자신만의
-
인스턴스 변수
는인스턴스가 생성될 때 마다 생성
되고,클래스 변수
는모든 인스턴스가 하나의 저장공간을 공유
함. -
static 메서드
는 같은 클래스 내의인스턴스 메서드
를 호출할 수 없다. - 메서드의 구현부를 작성할 때, 제일 먼저 해야 하는 일이
매개변수의 값이 적절한지 확인하는 것
.- 매개변수의 유효성 검사 로직을 넣어야 한다.
-
JVM의 메모리 구조
는Method area, Call stack, heap
으로 이루어진다.- Method area
- 클래스 데이터, 클래스 변수 등 저장
- Heap
- 프로그램 실행 중 생성되는 인스턴스는 모두 여기에 생성됨. (인스턴스 변수 포함)
- Call stack
- 메서드의 작업에 필요한 메모리 공간을 제공함. 호출된 메서드를 위한 메모리가 Call stack에 메모리가 할당됨. 메서드가 작업을 수행하는 동안 지역변수, 매개변수, 연산의 중간결과 등을 저장하는데 사용됨.
- Call stack 동작 흐름
- 메서드가 호출되면 필요한 만큼의 메모리를 스택에 할당받음.
- 수행을 마치면 사용했던 메모리를 반환하고 스택에서 제거됨.
- 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드.
- Method area
-
반환값이 없어도 메서드의 실행결과를 받아올 수 있다.
int add(int a, int b, int[] result) { result[0] = a + b; }
-
반복문 보다 재귀호출의 수행시간이 더 오래걸리는 이유
는매개변수 복사와 종료 후 복귀할 주소저장 등 작업
이 추가로 필요하기 때문이다. - 생성자가 인스턴스를 생성하는 것이 아니라,
연산자 new가 인스턴스를 생성하는 것
이다. -
컴파일
시 클래스에생성자
가 정의되지 않은 경우는컴파일러
가 자동적으로 기본 생성자를 추가하여 컴파일 한다. - 생성자 내에서 다른 생성자 호출은 첫번째 줄이 아니면 에러가 발생한다.
- 생성자 내에서 초기화 작업 도중 다른 생성자를 호출하면,
다른 생성자 호출 이전의 초기화 작업이 무의미해지기 때문
.
- 생성자 내에서 초기화 작업 도중 다른 생성자를 호출하면,
- 멤버변수는 초기화 하지 않아도 자동적으로 변수의 자료형에 맞는 기본값으로 초기화가 이루어진다.
-
초기화 블럭(Initialization Block)
class InitBlock { static { /* 클래스 초기화 블럭 */ } { /* 인스턴스 초기화 블럭 */ } }
-
명시적 초기화 만으로 부족할 만큼 복잡할 경우 초기화 블럭을 사용해서 초기화.
/* 명시적 초기화 예시 */ class InitTest { int x = 1; // 명시적 초기화 void method() { int i; i = 2; // 명시적 초기화 } }
-
클래스 초기화 블럭
은클래스가 메모리에 처음 로딩될 때 한번만 수행
되고,인스턴스 초기화 블럭
은 생성자와 같이인스턴스를 생성할 때 마다 수행
됨. -
생성자
보다인스턴스 초기화 블럭
이 먼저 실행됨. - 클래스가 로딩될 때
클래스 변수
들이 자동적으로 메모리에 만들어지고, 바로클래스 초기화블럭
이 실행됨. -
인스턴스 초기화 블럭은
모든 생성자에서 공통으로 수행되어야 하는 코드
를 넣음.{ count++; serialNo = count; } Car() { color = "White"; gearType = "Auto"; } Car(String color, String gearType) { this.color = color; this.gearType = gearType; }
- 멤버변수의 초기화 순서
- 클래스변수의 초기화 순서
- 기본값 → 명시적초기화 → 클래스 초기화 블럭
- 기본값 → 명시적초기화 → 인스턴스 초기화 블럭 → 생성자
- 클래스변수의 초기화 순서
-