1. JVM의 메모리 사용 영역
JVM이 시작되면 즉 .class 파일을 실행하게 되면 OS에서 할당받은 메모리 영역을 아래와 같이 생성하게 된다.
1) Method Area
클래스들을 클래스 로더로 읽어서 Method Area에 클래스 별로 저장한다. Method Area는 JVM이 시작되면 생성되며 모든 스레드가 공유하게 된다.
2) Heap
객체, 참조 타입(배열) 등이 저장되는 공간으로 Call Stack에서 Heap 영역의 객체를 참조할 수 있고 Heap 영역에 서로 다른 객체들간에 참조가 이루어지 수 있다.
3) Call Stack(JVM Stack)
이 영역에서는 Thread별로 하나의 Call Stack이 존재한다.
프로그램에서 작업 스레드를 별도로 추가하지 않는다면 main thread에 해당하는 Call Stack이 1개만 존재하게 된다.
하나의 Call Stack(즉 thread의 활동 영역)에서 메소드가 호출되면 Frame을 push하고 메소드가 종료되면 pop하는 구조로 동작한다.
2. Instance member, overloading
1) 필드
- 필드는 생성자와 메소드 전체에서 사용된다. 객체가 소멸하지 않는 한 객체와 함께 존재한다.
- 필드에는 기본타입과, 참조타입(배열, 클래스, 인터페이스)가 올 수 있다.
- 필드는 객체에 소속된 데이터이므로 객체가 존재하지 않으면 필드도 존재하지 않는다.
2) 생성자
- 생성자는 new 연산자와 같이 사용되어 클래스로부터 객체를 생성할 때 호출되어 객체의 초기화를 담당한다.
- 객체 초기화란 ?
필드를 초기화 하거나, 메소드를 호출해 객체를 사용할 준비를 하는 것이다.
- 기본생성자의 접근 제한자는 클래스의 접근 제한자와 같다.
(3) 생성자 오버로딩
- 외부에서는 모델값과 색값이 제공될 수도 있고 모델값만 제공될수도 있다.
이처럼 생성자가 하나이면 다양한 요구조건을 수행할 수 없다. 생성자 오버로딩이란 매개 변수를 달리하는 생성자를 여러 개 선언하는 것을 말한다.
- 매개변수의 타입이나, 순서, 개수가 다르게 선언된 것이다.
4) 매소드
- 외부에서 값을 매개변수로 복사할 때 매개변수에서는 자동 타입 변환이 일어난다.
예) byte a=1; func(int a); 변수 a는 함수의 매개변수로 복사할 수 있다.
- 메소드 매개변수를 배열로 받는 경우 즉 매개변수가 몇 개가 올지 모를 경우
방법1)
void sum(int[] values) {}
int[] valuse= {1,2,3};
sum(values);
방법2
void sum(int[] values) {}
int[] values;
sum(new int[] {1,2,3});
방법3)
void sum(int...valuse) {}
sum(1,2,3)
방법1,2는 배열변수를 직접 선언해야 한다 하지만 방법3은 배열변수를 직접 선언하지 않아도 된다. sum이라는 함수 안에 자동으로 int[3] valuse가 만들어진 것이다.
5) 메소드 오버로딩
- 클래스 내에 같은 이름의 메소드를 여러 개 선언하는 것을 메소드 오버로딩이라고 한다.
메소드의 오버로딩 조건은 매개변수의 타입, 개수, 순서 중 하나가 달라야 한다.
매개변수는 같고 리턴 타입만 다른 것은 오버로딩이 아니다.
예를 들어 int plus(int x,int y);이러 더하기 메소드는 정수 타입만 메소드로 받을 수 있다.
그래서 int plus(double x, double y);이렇게 오버로딩할 수 있다. 그러면 매개변수에 따라 컴파일러가 자동으로 맞는 메소드를 호출 시킨다.
3. static member
한 클래스내의 인스턴스 맴버(인스턴스 필드,매소드)는 클래스 변수를 선언 한 뒤 객체를 만든 후 클래스 변수를 통해 객체로 접근하여 (도트 연산자) 클래스의 인스턴스 맴버로 접근할 수 있다.
한 클래스내의 정적 맴버는 메모리영역의 매소드영역에 클래스와 함께 저장되어있다.
따라서 클래스를 도트연산자를 통해 접근해야한다.
정적 블록에는 정적 필드의 초기화만 가능하다. 또한 정적 매소드만 호출이 가능하다.
인스턴스 매소드를 호출할 수 없는 이유는 객체가 생성되지도 않았기 때문이다.
정적 블록에는 int a=5; 이런 선언이 가능하며 제어문도 사용 가능하다.( 정적 블록이라는 하나의 frame공간이 있기 떄문에 그 공간의 지역 변수 선언이 가능함)
정적 매소드에서는(메인함수 포함) 인스턴스 맴버에 접근하기 위해서 클래스 변수를 선언 한 뒤 객체를 생성하여 클래스 변수를 통해 접근 해야한다.
정적 맴버는 [클래스 이름].[static member] 이렇게 클래스 이름+도트연산자+접근하려는 맴버 이런식으로 접근할 수 있다.
정적 블록은 클래스 내부에 여러 개가 선언 되도 상관 없으며 클래스가 메모리로 로딩될때 (JVM이 구동 되는 시점) 선언 된 정적 블록 순선되로 실행된다.
package chapter1_4;
public class Mainclass {
public static void main(String ar[]) {
A a = new A();
}
}
class A {
int a;
static int b;
public A() {
this.a = 10;
System.out.println("생성자 초기화");
}
static {
b = 30;
System.out.println("static 초기화");
}
}
JVM이 가동되면 A라는 클래스 파일은 메소드 영역에 등록(?) 되는데 그때 static 맴버 (static block 포함)들의 실행이 진행된다.
생성자는 메인 함수에서 객체를 생성할 때 호출되었으므로 순서적으로 위와 같은 실행 결과가 나오는 것이다. (static 의 동작 방식만 알면 너무 당연함..)
'Java' 카테고리의 다른 글
6. 클래스 정리3 : 패키지와 imoprt (0) | 2022.01.20 |
---|---|
5. 클래스 정리2 : final, 접근 제한자, (0) | 2022.01.20 |
3. 배열을 활용한 문제 만들기 (0) | 2022.01.17 |
3. 1,2 차원 배열 선언 문법 (0) | 2022.01.17 |
2. 자바 명령어 도구(javac, java) (0) | 2022.01.17 |