JAVA는 개발자가 아닌 GC가 메모리 관리 담당
💡 ***Garbage Collection*** Heap 영역(class 영역 포함)에 생성된 메모리 관리 담당*.class 파일을 메모리로 읽어옴
1.1-1.3 와 소통
클래스와 관련된 정보를 저장하는 영역
클래스 자체에 들어있는 정보 ( ≠ 인스턴스)
설계도만 올라간다 !
인스턴스가 생성되는 공간
실제 객체가 담겨있는 곳
LIFO
메서드가 스택에 쏙쏙쏙 쌓여있는 형태
메서드 수행 시 프레임 할당됨
필요한 변수 or 중간 결과 값 임시 기억
메서드 종료 시 할당 메모리 자동 제거
메소드 자체는 1.1에 저장되어있지만, 실행되는 순간 스택에 공간 할당됨
스택에는 실행 정보가 담기게 됨

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

문자열은 무조건 힙 영역 내 문자열 풀에 따로 있고, 문자열 변수에 값을 입력하면 그 문자열 풀에 해당 문자열의 참조값을 가져와서 저장함.
2.1.1 로딩 시점
static: 클래스 로딩 시
non-static: 객체 생성 시
2.1.2 메모리 상의 차이
static: 클래스 당 하나의 메모리 공간만 할당
non-static: 인스턴스 당 메모리가 별도로 할당
2.1.3 문법적 특징
static: 클래스 이름으로 접근
non-static: 객체 생성 후 접근
2.1.4 static 영역에서는 non-static 영역을 직접 접근이 불가능
non-static은 실행될지 안될지 모르자나
2.1.5 non-static 영역에서는 static 영역에 대한 접근이 가능
어차피 static은 실행 메모리에 할당되어있기 때문에
PC가 많은 파일을 관리하기 위해 폴더를 이용하는 것처럼,
프로그램의 많은 클래스를 관리하기 위해 패키지를 이용
패키지는 클래스와 관련있는 인터페이스들을 모아두기 위한 이름 공간
패키지의 구분은 .(dot) 연산자 이용
com.ssafy.project_이름.module_이름

다른 패키지에 있는 클래스를 사용하기 위해서는 import 필요
import packlage_name.class_name;
import package_name.*;
이 때, 하위 패키지는 포함되지 않는다.
import java.util.*;
import java.util.logging.Logger;
line1을 선언했어도, line2를 따로 선언해줄 필요가 있다.
JAVA에서는 하위 패키지는 엄연하게 다른 패키지
자바는 사실 하위 패키지 라는 개념이 없다고 보면 된다…!
캡슐화 의의1: 데이터의 속성과 행위를 하나로 묶어서 모듈 단위로 작동한다.
캡슐화 의의2: 정보 은닉
아래는 캡슐화 의의2에 관한 내용!
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가지 모두 사용 가능
| 클래스 내부 | 동일 패키지 | 다른 패키지 내 하위 클래스 | 다른 패키지 | |
|---|---|---|---|---|
| private | O | |||
| (default) | O | O | ||
| protected | O | O | O | |
| public | O | O | O | O |

static : 클래스 레벨의 요소 설정
final : 요소를 더 이상 수정할 수 없게 함
abstact: 추상 메서드 및 추상 클래스 작성
클래스에서 선언된 변수 중 접근제한에 의해 접근할 수 없는 변소의 경우, 다른 클래스에서 접근할 수 없기 때문에, 접근하기 위한 메서드(설정자와 접근자)를 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;
}
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);
}
}
class 이름 : PascalCase
멤버 변수, 메서드 이름: camelCase
snake_case이면서 대문자인 경우 상수 (ex. MAX_SIZE)
kebab-case : HTML id, class이름 정할 때..
static 객체랑 상관 없이 해당 클래스에 접근할 수 있는
non-static 해당 객체가 유일하게 갖고 있는 필드
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;
}
>> 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();