JAVA_객체배열관리

이혜윤·2024년 1월 22일

JAVA

목록 보기
1/9

1. JVM 메모리구조

JAVA는 개발자가 아닌 GC가 메모리 관리 담당

💡 ***Garbage Collection*** Heap 영역(class 영역 포함)에 생성된 메모리 관리 담당
  • 더 이상 사용되지 않는 객체들을 점검해서 제거
  • 자동적 실행 / CPU가 한가하거나 메모리가 부족하거나?
  • JVM에 의해서 실행
  • System.gc()를 통해 호출은 가능하다. (하지만, 시스템 영향을 주기때문에 하지 않는 것을 추천)

1.0 Class Loader

*.class 파일을 메모리로 읽어옴

1.1-1.3 와 소통

1.1 클래스 영역 = 메소드 영역 = static 영역

클래스와 관련된 정보를 저장하는 영역

클래스 자체에 들어있는 정보 ( ≠ 인스턴스)

설계도만 올라간다 !

1.2 힙 (heap)

인스턴스가 생성되는 공간

실제 객체가 담겨있는 곳

1.3 스택 (stack)

LIFO

메서드가 스택에 쏙쏙쏙 쌓여있는 형태

메서드 수행 시 프레임 할당됨

필요한 변수 or 중간 결과 값 임시 기억

메서드 종료 시 할당 메모리 자동 제거

메소드 자체는 1.1에 저장되어있지만, 실행되는 순간 스택에 공간 할당됨

스택에는 실행 정보가 담기게 됨

2. 객체 생성과 메모리 할당

main이 method를 하나 호출했다면 별개의 영역. 지역변수를 다른데서 접근할 순 없고, 반환값을 넘겨줄순 잇음

문자열은 무조건 힙 영역 내 문자열 풀에 따로 있고, 문자열 변수에 값을 입력하면 그 문자열 풀에 해당 문자열의 참조값을 가져와서 저장함.

2.1 static 특징

2.1.1 로딩 시점

static: 클래스 로딩 시

non-static: 객체 생성 시

2.1.2 메모리 상의 차이

static: 클래스 당 하나의 메모리 공간만 할당

non-static: 인스턴스 당 메모리가 별도로 할당

2.1.3 문법적 특징

static: 클래스 이름으로 접근

non-static: 객체 생성 후 접근

  • 메서드 영역 (클래스 영역, static 영역)에 메모리 할당
  • 인스턴스 생성하기 전에 이미 클래스 로딩 시점에 메모리 할당 됨
  • 모든 인스턴스가 공유하고 있음

2.1.4 static 영역에서는 non-static 영역을 직접 접근이 불가능

non-static은 실행될지 안될지 모르자나

2.1.5 non-static 영역에서는 static 영역에 대한 접근이 가능

어차피 static은 실행 메모리에 할당되어있기 때문에


3. 패키지(package)

PC가 많은 파일을 관리하기 위해 폴더를 이용하는 것처럼,

프로그램의 많은 클래스를 관리하기 위해 패키지를 이용

패키지는 클래스와 관련있는 인터페이스들을 모아두기 위한 이름 공간

패키지의 구분은 .(dot) 연산자 이용

com.ssafy.project_이름.module_이름

3.1 import

다른 패키지에 있는 클래스를 사용하기 위해서는 import 필요

import packlage_name.class_name;

import package_name.*;

이 때, 하위 패키지는 포함되지 않는다.

import java.util.*;
import java.util.logging.Logger;

line1을 선언했어도, line2를 따로 선언해줄 필요가 있다.

JAVA에서는 하위 패키지는 엄연하게 다른 패키지

자바는 사실 하위 패키지 라는 개념이 없다고 보면 된다…!

4. 캡슐화(Encapsulation)

캡슐화 의의1: 데이터의 속성과 행위를 하나로 묶어서 모듈 단위로 작동한다.

캡슐화 의의2: 정보 은닉

아래는 캡슐화 의의2에 관한 내용!

5. 접근 제한자

5.1 접근 제한자의 종류

5.1.1 public

모든 위치에서 접근 가능

ex. 다른 패키지, 다른 클래스, 같은 패키지 내 다른 클래스

5.2.2 protected

같은 패키지에서 접근이 가능. 다른 패키지에서는 접근 불가능

단, 다른 패키지의 클래스와 상속관계가 있을 경우 접근 가능

ex. 같은 패키지O, 다른 패키지X, 다른패키지+상속O

5.2.3 (default)

같은 패키지에서만 접근이 허용됨

다른 패키지에서는 접근X

접근 제한자가 선언이 안 되었을 경우 기본 적용

5.2.4 private

자신 클래스에서만 접근이 허용됨

클래스(외부) 사용가능: public, default 이 두가지만 사용 가능

내부 클래스, 멤버 변수, 메소드: 4가지 모두 사용 가능

클래스 내부동일 패키지다른 패키지 내 하위 클래스다른 패키지
privateO
(default)OO
protectedOOO
publicOOOO
💡

5.2 그 외 제한자

static : 클래스 레벨의 요소 설정

final : 요소를 더 이상 수정할 수 없게 함

abstact: 추상 메서드 및 추상 클래스 작성

6. 접근자(getter) / 설정자(setter)

클래스에서 선언된 변수 중 접근제한에 의해 접근할 수 없는 변소의 경우, 다른 클래스에서 접근할 수 없기 때문에, 접근하기 위한 메서드(설정자와 접근자)를 public으로 선언해 사용

다른 곳에서 값을 변경하지 못하게 함과 동시에 가져다 쓸 수는 있도록! (setter는 변경할 수 있긴 한데.. 합법적으로 변경하는 그런 뉘앙스?)

일단 멤버변수는 접근 못하게 막아놓고, 합법적인 경로는 접근자와 설정자를 통해 접근한다.

private String name;
private int age;
private String hobby;
>> 멤버 변수에는 직접 접근 불가하도록 private 설정

public 반환자료형 get멤버변수명 { return 멤버변수; }

public String getName() {
    	return name;
    }

public void set멤버변수명(자료형 매개 변수){ 멤버변수 = 매개변수값; }

public void setName(String Name) {
    	this.name = Name;
    }

단순 값 할당과는 달리, setter에는 검증 로직 추가 가능

// 단순 값 할당
p.age = -10; 
// 나이에 음수를 할당해도 값이 들어감
public void setAge(int age) {
		if(age<0) {
			System.out.println("나이가 음수가 될 수 없다.");
			return;
		}
		this.age = age;
	}

7. 싱글턴 패턴(Single Pattern)

SW 디자인 패턴에서 싱글턴 패턴(Single pattern)을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나

최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴

하나만 생성해도되는 객체가 있다..!

public class Manager{
	private static Manager manager = new Manager();
	private Manager(){}
	public static Manager getManager(){return manager;}
}

#6 + #7 구현 예시

package modifier06_singleton;

// 싱글톤 패턴을 이용해 구현하라
//스코어를 관리하는 객체
public class ScoreManager {
    
	// 객체의 멤버 변수
	private int score;
	
	// 1. 생성자를 private으로 막아서, 외부에서 생성하지 못하도록 차단!
	private  ScoreManager() {
		// 생성자 이름은 클래스 명과 같도록
	}
	
	// 2. 객체를 단 한 번만 생성해서 갖고 있는다.
	// 5. static으로 만들어야 static으로 접근이 가능하다.
	private static ScoreManager instance = new ScoreManager();
	
	// 3. 외부에서 접근할 수 있는 합법적 통로를 열어준다.
	// 4. static으로 만들어서 객체 생성 없이 접근 가능하도록 해야 한다.
	public static ScoreManager getInstance() {
		return instance;
	}
}
package modifier06_singleton;

public class ScoreTest {
    public static void main(String[] args) {

    	ScoreManager sm1 = ScoreManager.getInstance();
    	
//    	ScoreManager sm2= new ScoreManager(); 
//    	-> 오류
//    	객체를 새로 생성할 수는 없기 때문
    	
    	ScoreManager sm2 = ScoreManager.getInstance();
    	
    	
//    	cf. sm1과 sm2는 같은 주소값을 참조하고 있다. 싱글톤 패턴
    	System.out.println(sm1==sm2);
    }
}

8. 객체 배열 관리

  • 정보 관리 시스템
    • 학사 관리 시스템 - 학생들의 배열은 하나만 있으면 됨. 다른 객체가 또 다른 배열을 만들어서 어떤 배열은 100명, 어떤 배열은 300명 등… 이원화될 필요가 없다! 배열을 관리하는 객체를 하나만 만들겠다.
  • 캡슐화를 이용해 클래스 작성
  • DB대신 배열을 사용해 객체 정보 저장
  • 객체의 조회/추가/수정/삭제 (CRUD) 구현
  • 싱글턴 패턴을 사용해 정보관리 일원화

class 이름 : PascalCase

멤버 변수, 메서드 이름: camelCase

snake_case이면서 대문자인 경우 상수 (ex. MAX_SIZE)

kebab-case : HTML id, class이름 정할 때..

static 객체랑 상관 없이 해당 클래스에 접근할 수 있는

non-static 해당 객체가 유일하게 갖고 있는 필드

회고 (어려웠던 점)

배열의 remove 구현

  1. targetIdx 설정
  2. targetIdx 값이 -1이 아니라면, 타겟을 발견한 것으로 판단
  3. 해당 인덱스에 저장되어 있는 배열 값을 null 로 설정
  4. targetIdx 뒤 인덱스에 저장되어 있는 각각의 값들을 한 칸씩 앞으로 땡겨오기
  5. 가장 마지막 칸은 null로 비워주기
  6. 해당 배열의 길이를 기록하기로한 변수는 size이다. this.size 한 칸 줄이기
public boolean removeRestaurant(int resId) {
		int targetIdx=-1;
		for(int i=0; i<restaurantSize; i++) {
			if(resId==restaurants[i].getResId()) {
				targetIdx = i;
				break;
			}
		}
		if(targetIdx !=-1) {
			restaurants[targetIdx]=null;
			for(int i=targetIdx+1; i<restaurantSize; i++) {
				restaurants[i-1] = restaurants[i];
			}
			if(restaurantSize<MAX_RESTAURANT_SIZE) {
				restaurants[restaurantSize] =null;
			}
			restaurantSize--;
			return true;
		}
		return false;
	}

manager clas의 기본 생성자를 private 처리한 후 getInstance로 받아오기

>> RestaurantManager.java

	// 요구 사항엔 없지만 추가한 코드
	private static RestaurantManager instance = new RestaurantManager();
	private RestaurantManager() {
		
	}
	public static RestaurantManager getInstance() {
		return instance;
	}
>> RestaurantTest.java
public class RestaurantTest {
	public static void main(String[] args) {
		RestaurantManager rm = RestaurantManager.getInstance();
profile
구르미 누나

0개의 댓글