오늘은 꽤나 흥미로운 주제로 강의 흐름이 이어졌다.
1. JVM과 관련 메모리(자바 프로그램이 메모리에 올라 갈 때, stack heap , 각각의 pool에서는 어떤일이 일어나는가
2. 추상 클래스 와 인터페이스
3. Java API - Collections
먼저, 메모리에 관한 얘기부터 진행 해 보자.
우리가 어떤 Application을 실행 할 때의 원리를 먼저 살펴보면, HW 위에 Operation System이 올라가고, 그 위는어떤이가 만든 Application이 돌아가게 된다. Java VM은 기본적으로 OS에서 프로세스를 하나 할당 받으면 VM 위에서 여러개의 쓰레드를 관리하게 된다. 그리고 그 쓰레드들 위해서 우리가 만든 JAVA 어플리케이션이 돌아가게 되는 것 이다.
JVM에는 여러개의 공간이 있지만, 몇가지만 설명 해 보겠다.
1.static pool
1번만 공유해서 사용되는 공간으로, 프로그램이 시작 될 때, static키워드가 붙은 변수 또는 함수 등등은 가장먼저 메모리에 올라가게 된다. 데이터를 공유한다는 장점이 있지만, 잘못 사용하면 쓸데없이 메모리에 올라가있는 상황이 벌어지기 때문에 꼭 사용해야 하는 이유가 없다면, 사용하지 않는 편이 좋다.
2.Stack(FILO)
어떤 블록이 시작되면 스택에 지역변수등드의 메모리가 잡히며, 블록이 끝나면 메모리가 해제 된다. 블록을 길게 짠 메소드나 반복문 조건문등이 여러개 중첩되다보면 stack over flow가 나는 이유가 여기에 있다.
3.Heap
우리가 자바 코드 내에서 new 즉 객체를 생성하는 코드가 있다면, 이 공간에 메모리가 잡히게 된다. 책꽂이 같이 객체들이 세로로 꽂혀있다고 봐도 무방하다. 이공간에 있는 객체들은 어떠한 변수도 이 메모리를 참조하지 않으면, garbage collector에 의해서 메모리 할당이 해제된다. 책꽂이에서, 책을 빼내다 보면 공간이 있지 않은가? 그럼 듬성듬성 공간이 남게 되는데, 이때 가비지컬렉터가 책을 쭉 밀듯 메모리를 정리 해 준다.
4.Literal pool
Literal이란 컴파일시 프로그램내에 정확히 표현되어야 할 값을 의미한다. 일반적으로 상수가 이 의미에 부합한다. 만약 int num = 1234; 라는 선언이 있다면, num은 stack내에 있을것이고, 1234는 상수 즉 값 그대로 표현되어야 할 값이므로, Literal pool에 들어가며, 주소값을 가지고, num은 그 주소값을 참조하게 된다. 만약 중복되는 값들이 선언된다면, 같은 주소값을 가리키게 한다.
5.String pool
말 그대로, 문자열들을 관리하는 pool이다. 어떤 문자열이 선언되면, 이공간에 할당되어 주소값을 가지게 되며, String변수는 여기에 있는 주소값을 가리키게 된다. 같은 문자열이 선언된다면, 그 문자열을 가리키는 변수들은 같은 주소값을 가지게 된다.
코드와 그림으로 메모리 상황을 살펴보자.
코드의 int 부분을 살펴보자.
1. 변수들은 stack에 배정되며, 1234와 같은 상수들은 Literal pool에 들어가게 된다, 그리고 그 주소값을 int형 변수들이 참조하게 된다.
2. 상수는 ==으로 비교해도 되는 이유가 여기에 있다. 중복되는 수가 pool에 들어가면 그냥 그에 해당하는 주소값을 반환하게 되므로 ==으로 비교해도 된다.
코드의 String 부분을 살펴보자
1. 큰따옴표로 String 변수를 초기화 하면, 문자열은 String pool에 들어가게 되며, String변수는 String pool에 있는 문자열의 주소값을 참조하게 된다.
2. new 로 String객체를 생성했을 경우를 보자. Heap영역에 공간이 할당되게 되며, "Hello"를 매개값으로 넣었으므로, "Hello"의 주소값을 참조하게 된다. String class에 있는 여러 변수들과 메소드들도 같이 메모리에 올라가게 되며, 메소드를 호출하면 Stack에서 블록이 끝날 때 까지 올라가 있다가 할당 해제 되게 된다.
코드의 PersonVO 부분을 살펴보자.
1. 먼저 객체를 생성 했으므로(new PersonVO) Heap영역에 할당되게 된다. 맨 처음 PersonVO의 부모형인 Object 객체가 먼저 메모리에 올라가게 되며, 그 후 PersonVO가 메모리에 할당 되며, super 부분에 부모형의 주소값을 가지고, 그후 "홍길동"의 메모리 주소를 참조하게 된다.
2. new StudentVO 했다면, Object , PersonVO, StudentVO 순서대로 메모리에 올라가며 줄줄이 참조하게 된다.
이걸로 메모리 설명은 끝이 났고, 추상 클래스 설명으로 넘어가 보자.
< 추상클래스와 인터페이스 >
우리는 프로그램을 설계할 때 두가지 방식을 사용하게 된다.
1. class -> abstract class -> interface
2. interface -> abstract class -> class
배울때는 1번의 방식으로 배우지만 현업에서는 2번 방식으로 많이 개발을 진행한다고 한다. 그렇다면 추상클래스는 무엇이며 인터페이스는 무엇인가
1. 추상클래스
먼저 추상 메서드는 구현부가 없고 이름만 있는 메서드 이다. (abstract public void print();)
이 추상 메서드를 1개라도 가진 클래스는 무조건 추상 클래스 이다.
1) 구현부가 없고
2) 메서드 앞에 abstract 붙으면 추상 메서드
3) 클래스 앞에 abstract 붙으면 추상 클래스
그리고 추상 클래스를 사용 하기 위해서는 그 클래스를 상속받은 자식 클래스가 필수이다. 또한 추상 메서드가 없더라도 abstract 키워드를 붙여서 추상 클래스로 만들 수 있다.
자 그러면 추상 클래스를 만들 수 있는 경우의 수를 정리 해 보면
1) 추상메소드를 가진다.
2) 추상메소드를 가지지 않지만 추상 클래스로 선언한다 -> 많은 메소드 중 어떤 메소드를 재정의해서 사용 할 지 애매할 때 사용한다.
3) 모든 메소드가 추상메소드 이다.
자바에서는 왜 상속의 모호성이 생길까? -> 구현부 때문이다. 자바가 다중상속을 지원하지 않는 이유도 여기에 있다. 만약 A라는 클래스가 두 클래스 B, C 를 상속 한다고 했을 때, 두 클래스의 이름이 같다면, super.을 했을때 어떤 클래스의 메소드를 불러올 것 인가? 하지만 모든 메소드가 추상 메소드라면 상속의 모호성이 생길 이유가 없어진다. -> 여러개 상속이 가능하다 -> 자바에서는 그 기능을 하는 것을 인터페이스 라고 한다.
2. 인터페이스
추상 클래스의 모든 메소드가 추상 메소드라면 인터페이스로 정의하는것이 좋다. 그리고 인터페이스를 구현하는 모든 클래스는, 인터페이스에 있는 모든 메소드를 추상 메소드나 아니면 구현을 꼭 해야한다.
그렇다면 추상 클래스와 인터페이스 간의 차이는 무엇일까? 그 둘의 목적을 생각 해 보자
추상클래스 : 추상클래스를 상속받아서 기능을 이용하고, 확장시키는 데 있다. 해당 메소드들의 구현을 강제한다. 또한 다중상속의 모호성 때문에 하나만 상속 받을 수 있다.
인터페이스: 구현객체의 같은 동작을 보장하는데 목적이 있다.
완벽한 설명은 아니지만 곰곰히 생각해보면 차이점을 느낄 수 있을 것 이다.
출처 : https://brunch.co.kr/@kd4/6
자 그러면 예제를 들어보자.
요구사항
1. 학교의 인증을 받은 사람들만 로그인 할 수 있다.
너무 명확하게 분석하려 하지 말고, 어디까지 불명확한지 정하고, 기본틀을 만들어본다.
어제 했던 Student와 Person 클래스를 활용 해 보자. 그렇다면 Person과 Student 클래스는 생성이 될 것이다.
그러나, 우리의 요구사항에서는 학교의 "인증을 받은사람만" 로그인이 가능해야 하는데 Person 도 객체생성이 되어버린다.
-> 안되게 막아야할 필요성이 있다
-> abstract class로 수정하여서 객체생성이 안되도록 바꾼다.
<Collection>
Collection Framework는 자바에서 많이 쓰이는 것 이고, 구조가 Basic하다. 따라서 이 API 구조만 잘 파악해도 많은 것을 얻어 갈 수 있다.
자바 컬렉션은 Object 목록을 관리하는 가변 메모리 이다. 종류는
Set : 중복체크
List : 순서체크
가 있다.
위의 그림을 세 부분으로 쪼개보면 크게, Interface, abstract class, class 부분으로 나눌 수 있다. 이때의 구현 방식을 살펴보자
1) 먼저 Set, AbstractCollection, List 부분을 구성한다.
2) 공통적인 부분을 추출한다.
3) 공통적인 부분은 Collection Interface로 묶는다.
4) 인터페이스나 추상클래스를 구현하는 클래스들을 만들고, 구현부를 구현한다.
5) 더 필요한 기능이 있으면 클래스를 확장 해 나간다.
자 예시를 통해 Collection을 사용 해 보자.
요구사항 : 객체들을 비 연속적으로 관리하는 업무 - 기준 : 순서
객체들을 비연속적으로 - Collection
기준 : 중복 - ArrayList
사소한 테스트 하나로 클래스를 만들어 나가면서 클래스를 구현 해 나간다. 일단 ListTest와 SetTest클래스를 보자.
이렇게 데이터 중심이 아닌 operation 중심으로 Test해가면서 클래스를 구성하는 1번방식으로 진행 해 보았다. 다음에는 예외와 JDBC를 중심으로 리뷰해 볼 계획이다.
'Advanced java > T Academy' 카테고리의 다른 글
[3일차] JAVA API 사용 및 JDBC 프로그래밍 (0) | 2017.02.06 |
---|---|
[1일차] JAVA API 사용 및 JDBC 프로그래밍 (0) | 2017.02.01 |