[Java] Java의 정석 정리 (클래스와 객체, 변수와 메소드)

송병훈·2022년 9월 21일
0

자바의 정석

목록 보기
1/15


클래스와 객체 (Class and Object)

공장에서 제품을 생산하듯이
클래스로부터 객체가 생성된다.

객체라는 용어 말고 "인스턴스" 라는 용어도 사용하는데,
객체는 인스턴스를 포함하는 일반적인 의미다.
new로 객체가 생성되면 인스턴스라는 이름을 붙인다.

클래스 --인스턴스화--> 인스턴스(객체)

클래스로부터 객체가 생성되는 걸 코드로 보자.

Class var_name = new Class();	// 인스턴스 var_name이 생성됨, var_name은 Class의 객체.

객체변수명(참조변수명) var_name은 이 객체를 다루기 위한 리모콘과 같다.
왜냐하면 객체변수명(참조변수명)을 통해
객체의 변수와 메소드에 접근하기 때문이다.

Java에서 객체는 변수와 메소드 로 이루어져 있다.

왜냐하면 클래스에서 변수와 메소드 를 만들어놓기 때문에
객체 역시 클래스에 있는 변수와 메소드를 지니고 있는 것이다.


Class Card{
	String kind;	// 카드의 무늬 (다이아, 스페이드, 하트, 클로버)
    int number;		// 카드의 숫자 (2~13)
    
    static int width = 100;		// 카드의 가로 (변하지 않는 공통속성)
    static int height = 250;	// 카드의 세로 (변하지 않는 공통속성)
    
    Card heart(Card c) {
    	c.kind = "Heart";	// kind를 Heart로 바꾸고
        return c;	// c를 반환
    }
}
  • 위와 같은 클래스가 있을 때 Card card = new Card(); 를 한다면?

  • 인스턴스가 생성된 후에 값을 저장하거나 꺼내오려면 . 을 찍어 사용한다.
Card card = new Card();	// card 인스턴스(객체) 생성

card.kind = "Spade";	// card의 kind와 number에 값을 저장
card.number = 9;
System.out.print(card);	// card에 저장된 주소 0xaaaa가 출력
System.out.print(card.kind);	// Spade가 출력

card.Heart(card);
System.out.print(card.kind);	// Heart가 출력
  • 여러 개의 객체변수명이 하나의 인스턴스를 가리킬 수도 있다.
Card card1 = new Card();
Card card2 = new Card();
card1.kind = "Spade";
card2.kind = "Diamond";

card1 = card2;	// card2의 주소를 card1에 저장함으로써 card1도 card2 인스턴스를 가리키게 함

System.out.print(card1.kind);	// Diamond가 출력됨

변수 (Variable)

1. 클래스 변수

  • 같은 클래스의 모든 인스턴스들이 공유함.
  • 변수 선언시 앞에 static을 붙임
static int width = 100;	
static int height = 250;
  • 인스턴스 생성없이 '클래스명.클래스변수명'으로 접근한다.
    (클래스 전체에 적용된다는 것을 직관적으로 보여줌)
Card.width
Card.height
  • 클래스가 메모리에 로드될 때 생성되고, 프로그램이 종료될 때 소멸함.

2. 인스턴스 변수

  • 각 인스턴스마다의 개별적인 저장공간. 인스턴스마다 다른 값 저장함.
  • 인스턴스 생성 후 '객체변수명.인스턴스변수명'으로 접근한다.
  • 인스턴스를 생성할 때 생성되고, 객체변수(=참조변수)가 없을 때 Garbage Collector에 의해 자동 제거됨

3. 지역 변수

  • 메소드 내에서 선언되며, 메서드의 종료와 함께 소멸함
  • { } 을 벗어나면 소멸

메소드 (Method)

  • 클래스 안에서 선언되는, 어떤 작업을 수행하기 위한 코드의 집합
  • 매개변수를 받아서 처리하고 결과를 return 한다.
  • ※ 반복적인 코드가 줄어들어 관리가 용이함
  • ※ 하나의 메소드는 한 가지 기능만 수행하도록 작성하자
Card heart(Card c) {	//Card: 반환타입, heart: 메소드명, (Card C): 매개변수의 타입과 변수명
	c.kind = "Heart";	// kind를 Heart로 바꾸고
	return c;	// c를 반환
}
  • 반환타입: return할 타입을 지정해준다. return값이 없으면 void로 작성
  • 메소드명: 소문자로 시작한다
  • 매개변수: 파라미터라고도 하며, 메소드명 옆의 ( ) 안에 적는다.
    +여러 개 작성 가능
  • return: 작업의 결과를 반환한다.
    +무조건 하나만 반환하며, 여러 데이터를 넘길 때는 객체형식으로 여러 데이터를 담아 반환하면 된다.

1. 인스턴스 메소드

  • static 키워드 없이 선언된 메소드
  • 인스턴스 생성 후 '객체변수(=참조변수).메소드명()' 으로 호출
  • 인스턴스 변수나 인스턴스 메소드 관련 처리를 함

2. 클래스 메소드 (static)

  • static 키워드가 붙은 메소드
  • 인스턴스 생성없이 '클래스명.메소드명()' 으로 호출
  • 인스턴스 변수와 관련 없는 작업을 한다면 static을 붙여라.
  • 클래스 메소드 내에 인스턴스 변수를 사용할 수 없다.
    왜냐하면 클래스메소드는 객체 생성없이 사용하는 것이지만,
    인스턴스 변수나 인스턴스 메소드는 객체를 생성한 후에 사용할 수 있기 때문이다.

JVM의 메모리 구조

1. 메소드영역

  • 클래스 정보와 클래스 변수가 저장되는 곳

2. 호출 스택 (Call Stack)

  • 메소드의 작업공간
  • 메소드가 호출되면 메모리 공간을 할당받고, 메소드가 종료되면 메모리를 반환한다.
  • 선입후출
    ex) main메소드 실행 중에 다른 메소드가 실행되고
    그 메소드가 종료되면 다시 main메소드가 실행된다.
    맨 위에 있는 메소드가 현재 실행 중인 메소드.

3. 힙 (Heap)

  • 인스턴스가 생성되는 공간
  • new 연산자에 의해서 생성되는 배열과 객체는 모두 여기에 저장된다.

그림으로 다시 확인해볼까요?

Google에 검색하니 위키에 이런 이미지가 나오네요.

지금 수준에서는 어려워 보여요..ㅠ

나중에 더 파고들어 봅시다.


지금은 간단하게 봐요.

  • 메소드 영역에는 클래스(static) 멤버들이 있어요.
  • 호출스택에는 메소드가 실행되고 있어요.
  • 힙 영역에는 수많은 인스턴스가 만들어졌어요.

근데 이 메모리 공간을 계속 사용하면 안되겠죠?
성능도 중요하고, 공간도 중요하잖아요.

  • 메소드 영역에 있는 데이터들은 프로그램이 종료될 때 같이 사라져요.
  • 호출스택에 있는 데이터들은 메소드가 종료되면 바로 사라져요.
  • 힙 영역에 있는 데이터들은 참조변수와의 연결이 끊어지면 Garbage Collector가 정리해준대요.

Java 프로그램이 실행되었다고 생각해봅시다.

가장 먼저 저장장치에 있던 파일들이 메모리(RAM)에 올라갈 거에요.
이때 클래스 파일의 데이터Method Area의 메모리에 같이 올라가고,
각각의 클래스 안에 있는 static 멤버들도 Method Area의 메모리에 올라가요.

이렇게 Method Area에 올라간 데이터들은 공용 변수, 공용 메소드가 되어
이후에 어떤 인스턴스가 생성되더라도 꺼내 쓸 수 있고
이 값을 변경하면 모든 인스턴스에 영향을 미칠 거예요.

이제 main메소드가 실행되었다고 생각해봅시다.

우선은 Call Stack에 main메소드가 올라가겠죠.

main 메소드 안에는 객체를 만드는 코드가 있을 거예요.
new로 Heap 영역에 인스턴스가 만들어지죠.

하지만, 이 인스턴스 안에 static 멤버들은 없어요.
이미 만들어져서 Method Area에 있으니까요.
생성된 위치가 다르니 static 멤버들을 사용할 때
참조변수가 아니라 클래스명을 이용하는 거죠.

하나의 클래스에서 여러 인스턴스를 생성하면
Method Area에 있는 static 멤버는 모든 인스턴스가 공유해요.

인스턴스 생성 후에,
main메소드 안의 다른 메소드들이 호출되면
Call Stack에 올라가 실행-pop이 실행돼요.
실행되지 않는 메소드들은 대기 상태구요.

main메소드가 종료되면 Call Stack은 비워지고
인스턴스가 다 쓰이면 Heap도 비워지고
프로그램이 종료되면 Method Area도 비워지면서
JVM가 비워지겠죠.


사실 지금은 저도 모르는 게 많아요. 그래서 더 알아보려구요.
확실히 이해하게 되면, 그때 다시 설명해드릴게요.
감사합니다.

profile
성실하고 꼼꼼하게

0개의 댓글