스택과 힙 지역변수와 인스턴스 변수 객체 생성과 생성자 객체 제거 (가비지 컬렉션)

Slides:



Advertisements
Similar presentations
3. 메소드와 변수 SCJP 자격증 프로젝트 발표자 : 최선웅. 1. 메 소 드 개 념 2. 메 소 드 양 식 3. 메 소 드 변 수 4. 메 소 드 예 제 5. 참 고 문 헌 / 자 료 목 차.
Advertisements

01_ 가상 함수를 사용한 다형성의 구현 02_ 오버라이딩
OpenCV 안드로이드 연동 환경설정 OpenCV-Android 를 다운 받습니다.
ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
ㅎㅎ 구조체 C++ 프로그래밍 기초 : 객체지향의 시작 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스
클래스 class, 객체 object 생성자 constructor 접근 access 제어 이벤트 event 처리.
인스턴스 변수와 메소드의 상호 관계에 대해 알아봅니다. 매개변수와 리턴값에 대해 알아봅니다. 객체의 동치에 대해 알아봅니다.
원시 변수와 레퍼런스 변수에 대해 알아봅니다. 변수가 저장되는 힙에 대해 알아봅니다. 배열에 대해 알아봅니다.
Chap07 상속 Section 1 : 상속의 개요 Section 2 : 멤버 변수의 상속
최윤정 Java 프로그래밍 클래스 상속 최윤정
클래스 구성 요소 1개의 클래스는 최대 8개의 구성 요소를 가질 수 있다
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
Java로 배우는 디자인패턴 입문 Chapter 5. Singleton 단 하나의 인스턴스
제 9 장 구조체와 공용체.
컴퓨터 프로그래밍 기초 [Final] 기말고사
JAVA 언어로 배우는 디자인 패턴 입문 chap. 1-2.
Lesson 5. 레퍼런스 데이터형.
제 6장. 생성자와 소멸자 학기 프로그래밍언어및실습 (C++).
8.1 인터페이스 개요와 인터페이스 정의 8.2 인터페이스의 사용 8.3 인터페이스의 상속 8.4 인터페이스 참조
Lesson 9. 예외처리.
Lesson 6. 형변환.
8장. 심각한 다형성 “추상”과 “구상”의 차이점에 대해 알아봅니다. Object 클래스에 대해 알아봅니다.
5장. 참조 타입.
제 3장. C보다 나은 C++ II.
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
6장. 클래스.
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
자바 5.0 프로그래밍.
패키지와 접근 제어 패키지에 대하여 접근 제어에 대하여.
정렬 제네릭 Comparator 컬렉션 클래스
Java 6장. 클래스 : 속성 public class SumTest {
Lesson 7. 클래스와 메소드 - 1.
컴퓨터 프로그래밍 실습 #6 제 4 장 클래스 작성.
자바 5.0 프로그래밍.
C#.
6장 클래스 6.1 클래스의 일반 구조 6.2 클래스 선언 6.3 객체의 생성 6.4 멤버 변수 6.5 멤버변수 접근 한정자
13. 연산자 오버로딩.
10강. JSP 본격적으로 살펴보기-II 스크립트릿, 선언, 표현식 지시자 주석 Lecturer Kim Myoung-Ho
7장 인터페이스와 추상 클래스.
자바응용.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
29강 JAVA 스레드 - 스레드란? - 멀티스레드 문법 - synchronized Lecturer Kim Myoung-Ho
Lesson 2. 기본 데이터형.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
Effective Java [Issue 1 and 2]
에어 조건문.
Lab 8 Guide: 멀티스레딩 예제 2 * Critical Section을 이용한 멀티스레딩 동기화 (교재 15장, 쪽)
자바 5.0 프로그래밍.
자바 가상 머신 프로그래밍 Chap 10. 자바 컴파일링의 안쪽 ② Pslab 오민경.
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
Power Java 제11장 상속.
9강. 클래스 실전 학사 관리 프로그램 만들기 프로그래밍이란 결국 데이터를 효율적으로 관리하기 위한 공구
JA A V W. 06.
10장 상속 Section 1 상속의 개요 Section 2 상속과 한정자 Section 3 상속과 생성자
객체기반 SW설계 팀활동지 4.
클래스 : 기능 CHAPTER 7 Section 1 생성자(Constructor)
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
Lecture 04 객체지향 페러다임 Kwang-Man Ko
3. 모듈 (5장. 모듈).
함수, 모듈.
발표자 : 이지연 Programming Systems Lab.
컴퓨터 프로그래밍 기초 - 9th : 배열 / 포인터 -
9 브라우저 객체 모델.
Android -Data Base 윤수진 GyeongSang Univ. IT 1.
Static과 const 선언 조 병 규 한 국 교 통 대 학 교 SQ Lab..
2.가상머신의 탐험 도구, Oolong에 대하여 ps lab 김윤경.
1. 지역변수와 전역변수 2. auto, register 3. static,extern 4. 도움말 사용법
Java의 정석 제 8 장 예외처리 (Exception handling) Java 정석 남궁성 강의
7 생성자 함수.
6 객체.
Presentation transcript:

스택과 힙 지역변수와 인스턴스 변수 객체 생성과 생성자 객체 제거 (가비지 컬렉션) 9장. 생성자와 가비지 컬렉션 스택과 힙 지역변수와 인스턴스 변수 객체 생성과 생성자 객체 제거 (가비지 컬렉션)

객체의 삶과 죽음 그리고 그가 말했어. “다리에 감각이 없어!” 그리고 내가 말했지. “조! 정신 차려 조!” 하지만 이미 너무 늦었어. 가비지 컬렉터가 나타났고 그는 죽고 말았지. 내가 만나 본 가장 좋은 객체였는데 말야…

스택과 힙 스택 (stack) 힙 (heap) 메소드 호출과 지역 변수가 사는 곳 지역 변수는 스택 변수라고도 부릅니다. 모든 객체가 사는 곳 인스턴스 변수는 객체 안에 들어있습니다. go() doStuff() main() Dog 객체 Snowboard 객체 Button 객체

인스턴스 변수와 지역 변수 인스턴스 변수 (instance variable) 지역 변수 (local variable) 클래스 내에서 선언한 변수 그 변수가 속한 객체 안에서 삽니다. public class Duck { int size; } 지역 변수 (local variable) 메소드 내에서 선언한 변수 매개변수도 지역 변수에 포함됩니다. public void foo(int x) { int i = x + 3; boolean b = true;

스택과 메소드 메소드를 호출하면 메소드는 호출 스택(call stack) 맨 위에 올라갑니다. 스택 맨 위에 있는 메소드는 그 스택에서 현재 실행중인 메소드입니다. 메소드는 그 끝을 나타내는 중괄호에 다다를 때까지 스택에 머무릅니다. foo()라는 메소드에서 bar()라는 메소드를 호출하면 bar() 메소드가 foo() 위에 얹힙니다. bar() s foo() x i b

스택과 메소드 public void doStuff() { boolean b = true; go(4); } public void go(int x) { int z = x + 24; crazy(); public void crazy() { char c = ‘a’; crazy() c x z go() x z go() x z go() b doStuff() b doStuff() doStuff() b doStuff() b

지역 변수로 쓰이는 객체는? 원시 변수가 아닌 변수에는 객체에 대한 레퍼런스가 들어있습니다. 지역 변수가 객체 레퍼런스인 경우에는 변수(레퍼런스)만 스택에 들어갑니다. 객체 자체는 여전히 힙 안에 들어있습니다. public class StackRef { public void foof() { barf(); } public void barf() { Duck d = new Duck(24); barf() d foof() Duck 객체

바보 같은 질문은 없습니다 이런 내용을 왜 배우는 거죠? 변수 영역, 객체 생성 문제, 메모리 관리, 스레드, 예외 처리 등을 이해하는 데 있어서 스택과 힙에 관한 내용은 필수적입니다. 특정 JVM, 플랫폼에서 스택과 힙을 구현하는 방법은 몰라도 됩니다. 일단 스택과 힙에 대해 이해하고 나면 다른 내용을 이해하는 것이 한결 수월해집니다.

핵심 정리 자바에서 우리가 관심을 가져야 할 메모리 공간에는 힙과 스택, 이렇게 두 가지가 있습니다. 클래스 안에서, 하지만 메소드 밖에서 선언된 변수는 인스턴스 변수입니다. 메소드 안에서 선언된 변수, 또는 매개변수는 지역 변수입니다. 모든 지역 변수는 스택에 들어있으며 그 변수를 선언한 메소드에 해당하는 프레임 안에 들어있습니다. 객체 레퍼런스 변수도 지역 변수라면 스택에 저장됩니다. 모든 객체는 힙에 저장됩니다.

인스턴스 변수는 어디에? CellPhone 객체 CellPhone 객체 Antenna 객체 CellPhone 객체 y x public class CellPhone { private Antenna ant; } x y int long CellPhone 객체 ant Antenna CellPhone 객체 public class CellPhone { private Antenna ant = new Antenna(); } ant Antenna Antenna 객체 CellPhone 객체

Duck myDuck = new Duck(); 객체 선언, 생성, 대입 Duck myDuck = new Duck(); 1. 레퍼런스 변수 선언 Duck myDuck = new Duck(); myDuck Duck 레퍼런스

Duck myDuck = new Duck(); 객체 선언, 생성, 대입 Duck myDuck = new Duck(); 2. 객체 생성 Dog myDuck = new Duck(); Duck 객체

Duck myDuck = new Duck(); 객체 선언, 생성, 대입 Duck myDuck = new Duck(); 3. 객체와 레퍼런스 연결 Dog myDog = new Dog(); Duck 객체 myDuck Duck 레퍼런스

메소드? 생성자! 생성자 (Constructor) 객체를 생성할 때 실행되는 코드가 들어있습니다. Dog myDuck = new Duck(); 생성자 (Constructor) 객체를 생성할 때 실행되는 코드가 들어있습니다. 모든 클래스에 생성자가 있습니다. 직접 만들지 않아도 컴파일러에서 자동으로 생성자를 만들어줍니다. public Duck() { // 생성자 코드가 들어갈 자리 }

생성자 예제 public class Duck { public Duck() { System.out.println(“Quack”); } public class UseADuck { public static void main(String[] args) { Duck d = new Duck(); % java UseADuck Quack

객체의 상태를 초기화하는 방법 객체의 상태를 초기화하는 작업은 대부분 생성자에서 처리합니다. public Duck() { size = 34; } Duck을 사용하는 프로그래머가 오리의 크기를 결정하도록 하려면? public class Duck { public Duck() { System.out.println(“Quack”); } public void setSize(int newSize) { size = newSize; public class UseADuck { public static void main(String[] args) { Duck d = new Duck(); d.setSize(34);

바보 같은 질문은 없습니다 컴파일러에서 자동으로 만들어주는데 왜 생성자를 따로 만들어야 하나요? 객체 초기화 작업 및 각종 준비 작업이 필요하다면 생성자를 따로 만들어야 합니다. 객체를 완전히 만들기 전에 사용자로부터 뭔가를 입력 받는다거나 하는 경우에는 생성자가 반드시 필요합니다. 상위 클래스 생성자 문제로 인해 초기화 및 준비 작업이 필요하지 않은 경우에도 생성자를 만들어야 할 수도 있습니다.

바보 같은 질문은 없습니다 메소드와 생성자를 어떻게 구분할 수 있나요? 그리고 클래스와 이름이 같은 메소드를 만들 수 있나요? 가능합니다. 클래스와 같은 이름을 가지고 있다고 해서 무조건 생성자가 되는 것은 아닙니다. 생성자와 메소드는 리턴 유형 유무로 구분합니다. 생성자에는 리턴 유형이 없어야 하고 메소드에는 리턴 유형이 있어야만 합니다. public Duck() { … } public int Duck() { … }

바보 같은 질문은 없습니다 생성자도 상속되나요? 상위클래스에서만 생성자를 만들고 하위클래스에서 생성자를 만들지 않으면 기본 생성자 대신 상위클래스의 생성자가 쓰이나요? 아닙니다. 생성자는 상속되지 않습니다. 이와 관련된 내용은 잠시 후에 살펴보겠습니다.

생성자를 이용한 초기화 인스턴스 변수가 초기화되기 전까지 객체를 사용해선 안 된다면 생성자에서 초기화하면 됩니다. public class Duck { int size; public Duck(int duckSize) { System.out.println(“Quack”); size = duckSize; System.out.println(“size is “ + size); } public class UseADuck { public static void main(String[] args) { Duck d = new Duck(42); % java UseADuck Quack size is 42

인자가 없는 생성자 인자가 있는 생성자만 있으면 사용하기가 불편합니다. 기본 크기가 자동으로 정해지는 인자가 없는 Duck 생성자를 만들면 편하지 않을까요? public class Duck { int size; public Duck(int newSize) { if (newSize == 0) { size = 27; } else { size = newSize; } public class Duck2 { int size; public Duck2() { size = 27; } public Duck2(int duckSize) { size = duckSize; Duck2 d = new Duck2(15); Duck2 d = new Duck2();

인자가 없는 생성자 인자가 없는 생성자는 컴파일러에서 자동으로 만들어주지 않나요? 아닙니다. 컴파일러에서는 생성자가 전혀 없는 경우에만 생성자를 자동으로 만들어줍니다. 인자가 있는 생성자를 만들었을 때 인자가 없는 생성자도 필요하다면 인자가 없는 생성자도 직접 만들어야 합니다. 한 클래스에 생성자가 두 개 이상 있으면 각 생성자의 인자 목록은 반드시 서로 달라야 합니다.

생성자 오버로딩 두 개 이상의 생성자가 필요하다면 생성자 오버로딩을 사용하면 됩니다. 각 생성자의 인자 목록은 서로 달라야만 합니다. Public class Mushroom { public Mushroom(int size) { } public Mushroom( ) { } public Mushroom(boolean isMagic) { } public Mushroom(boolean isMagic, int size) { } public Mushroom(int size, boolean isMagic) { } }

핵심 정리 인스턴스 변수는 그 변수가 들어있는 객체 안에 저장됩니다. 인스턴스 변수가 레퍼런스 변수인 경우에는 레퍼런스와 객체가 모두 힙에 저장됩니다. new 키워드를 사용할 때 실행되는 코드를 생성자라고 합니다. 생성자명은 반드시 클래스명과 같아야 하며 리턴 유형은 없어야 합니다. 생성자를 이용하여 객체의 상태(인스턴스 변수)를 초기화할 수 있습니다. 클래스에 생성자가 없으면 컴파일러에서 기본 생성자를 만듭니다. 기본 생성자에는 인자가 없습니다. 생성자를 하나라도 만들면 컴파일러에서 기본 생성자를 만들어주지 않습니다.

핵심 정리 인자가 없는 생성자를 만들고 싶은데 인자가 있는 생성자가 따로 있다면 인자가 없는 생성자도 손수 만들어야 합니다. 가능하면 인자가 없는 생성자도 만드는 것이 좋습니다. 생성자 오버로딩을 활용하면 한 클래스에 두 개 이상의 생성자를 만들 수 있습니다. 오버로드된 생성자들의 인자 목록은 반드시 서로 달라야 합니다. 인자 목록이 똑같은 생성자가 두 개 이상 있을 수 없습니다. 인스턴스 변수에는 자동으로 기본값이 지정됩니다. 원시 유형의 기본값은 0/0.0/false이며 객체에 대한 레퍼런스의 기본값은 null입니다.

바보 같은 질문은 없습니다 기본값을 지정할 수 없기 때문에 인자가 없는 생성자를 만들지 않아야 하는 경우는 없나요? 물론 적당한 기본값이 없는 경우에는 인자가 없는 생성자를 만드는 것이 무의미할 수도 있습니다. 예) Color 클래스 Color c = new Color(3, 45, 200); Color c = new Color(); cannot resolve symbol : constructor Color() location: class java.awt.Color Color c = new Color(); ^ 1 error

생성자에 대해 반드시 알아야 할 네 가지 생성자는 누군가가 어떤 클래스 유형에 대해 new를 쓸 때 실행되는 코드입니다. Duck d = new Duck(); 생성자명은 반드시 클래스명과 같아야 하며 리턴 유형은 없습니다. public Duck(int size) { } 클래스를 만들 때 생성자를 만들지 않으면 컴파일러에서 기본 생성자를 자동으로 추가해줍니다. 기본 생성자는 언제나 인자가 없는 생성자입니다. public Duck() { }

생성자에 대해 반드시 알아야 할 네 가지 인자 목록만 다르면 한 클래스에 생성자를 여러 개 만들 수도 있습니다. 한 클래스에 두 개 이상의 생성자가 있으면 오버로드된 생성자가 있다고 말합니다. public Duck() { } public Duck(int size) { } public Duck(String name) { } public Duck(String name, int size) { } public Duck(int size, String name) { }

바보 같은 질문은 없습니다 생성자는 반드시 public이어야 하나요? 아닙니다. 생성자도 public, private, default로 지정할 수 있습니다. private 생성자는 어떤 용도로 쓰나요? 아무도 그 생성자를 호출할 수 없으면 그 생성자를 가지고 새로운 객체를 만들 수 없지 않나요? 그렇진 않습니다. 클래스 “밖에서” 접근할 수 없을 뿐입니다. 즉 같은 클래스 안에 있는 코드에서는 그 생성자를 사용할 수 있습니다.

상위클래스와 상속, 생성자 사이의 관계 Snowboard 객체 y x z Snowboard a Object b c Object Foo a; int b; int c; equals() getClass() hashCode() toString() Snowboard y x z Object a b c Snowboard Foo x; Foo y; int z; turn() shred() getAir() loseControl() Snowboard 객체

(constructor chaining) 상위클래스 생성자의 역할 Object Hippo y x Animal s v k Object Animal a b c Hippo 생성자 연쇄 (constructor chaining) Hippo 객체

생성자 연쇄 % java TestHippo Starting… Making an Animal Making a Hippo public class Animal { public Animal() { System.out.println(“Making an Animal”); } public class Hippo extends Animal { public Hippo() { System.out.println(“Making a Hippo”); public class TestHippo { public static void main(String[] args) { System.out.println(“Starting…”); Hippo h = new Hippo(); % java TestHippo Starting… Making an Animal Making a Hippo Object() Animal() Animal() Animal() Hippo() Hippo() Hippo() Hippo()

상위클래스 생성자 호출 방법 public class Duck extends Animal { int size; public Duck(int newSize) { Animal(); size = newSize; } super();

상위클래스 생성자 생성자를 만들지 않은 경우 생성자를 만들긴 했는데 super()를 호출하지 않은 경우 컴파일러에서 다음과 같은 내용을 추가합니다. public ClassName() { super(); } 생성자를 만들긴 했는데 super()를 호출하지 않은 경우 컴파일러에서 super()를 자동으로 추가해줍니다.

super() 호출 선언문의 위치 자식이 있으려면 반드시 부모가 먼저 있어야 합니다. 마찬가지로 상위클래스 생성이 끝나야만 하위클래스 생성이 끝날 수 있습니다. super()를 호출하는 선언문은 모든 생성자의 첫 번째 선언문이어야 합니다. public Boop() { } public Boop(int i) { size = i; super(); public Boo() { super(); } public Boop(int i) { size = i;

인자가 있는 상위클래스 생성자 % java MakeHippo Buffy Animal Hippo public abstract class Animal { private String name; public String getName() { return name; } public Animal(String theName) { name = theName; public class Hippo extends Animal { public Hippo(String name) { super(name); public class MakeHippo { public static void main(String[] args) { Hippo h = new Hippo(“Buffy”); System.out.println(h.getName()); Animal private String name Animal(String n) String getName() Hippo Hippo(String n) (Hippo용 메소드) % java MakeHippo Buffy

오버로드된 생성자 호출 방법 같은 클래스에 있는 다른 생성자를 호출할 때는 this()를 쓰면 됩니다. super()와 this()를 동시에 호출할 수는 없습니다. class Mini extends Car { Color color; public Mini() { this(Color.Red); } public Mini(Color c) { super(“Mini”); color = c; public Mini(int size) { super(size); % javac Mini.java Mini.java:16: call to super must be first statement in constructor super(); ^

객체의 생존 기간 지역 변수 인스턴스 변수 그 변수를 선언한 메소드 안에서만 살 수 있음 객체가 살아있는 동안 살 수 있음 public void read() { int s = 42; } 인스턴스 변수 객체가 살아있는 동안 살 수 있음 public class Life { int size; public void setSize(int s) { size = s;

지역 변수의 삶과 영역 삶(life) 영역(scope) 지역 변수는 스택 프레임이 스택에 들어있는 한 계속 살아있습니다. public void doStuff() { boolean b = true; go(4); } public void go(int x) { int z = x + 24; crazy(); public void crazy() { char c = ‘a’; 삶(life) 지역 변수는 스택 프레임이 스택에 들어있는 한 계속 살아있습니다. 영역(scope) 지역 변수의 영역은 그 변수를 선언한 메소드 내로 제한됩니다. crazy() c x z go() x z go() x z go() b doStuff() b doStuff() doStuff() b doStuff() b

레퍼런스 변수의 삶 마지막 레퍼런스가 사라지면 그 객체는 가비지 컬렉션 대상이 됩니다. 객체 레퍼런스 제거 방법 void go() { Life z = new Life(); } z = new Life(); z = null; 레퍼런스가 영역을 벗어남 다른 객체 대입 레퍼런스를 null로 설정

숙제 본문을 꼼꼼하게 읽어보세요. 본문에 들어있는 연필을 깎읍시다, 두뇌 운동 등을 전부 여러분 힘으로 해결해보세요. 연습문제를 모두 풀어보세요. 퍼즐도 해 보는 것이 좋습니다.