-
20240816 4일차카테고리 없음 2024. 8. 16. 17:35
[static]
- static 키워드를 통해 static 영역에 할당된 메모리는 모든 객체가 공유하는 메모리임
- static 변수는 class 변수임
- 객체를 생성하지 않고도 static 자원에 접근 가능 (객체가 생성되기 전에 이미 할당됨)
[생성자]
- 원래는 class에 하나 이상의 생성자를 선언해야하지만, 선언하지 않아도 new 키워드를 통해 객체 생성이 가능함
- 컴파일러가 생성자가 하나도 없을 때 기본 생성자를 추가해줌
[클래스 선언과 객체 생성]
- class에 선언된 field는 해당 field 데이터타입의 기본값으로 초기화 됨
- 2개 이상의 클래스를 하나의 파일로 선언하는 경우, 하나의 클래스만 public으로 선언할 수 있고, 해당 클래스 이름은 소스파일 이름과 동일해야 함
클래스 변수 (static 변수)
- 클래스 변수는 static 변수라고도 하며, 클래스가 메모리에 로딩될 때 한번만 메모리에 할당됨
- JVM 영역 중 Method 영역에 로드됨
- 모든 클래스의 객체가 공통된 변수를 공유함!!!
- 이미 메모리에 올라가 있기 때문에 클래스의 객체를 생성하지 않고도 사용 가능함static 메서드 유의사항
- 객체와 관련된 인스턴스 변수를 사용할 수 없음
- 객체와 관련된 인스턴스 메서드를 호출할 수 없음
- 객체 자신을 가리키는 this 키워드를 사용할 수 없음* 모든 클래스의 객체가 공유하는 변수이므로, 어떤 객체인지 모르니까 객체와 관련된 인스턴스 변수/메서드를 사용할 수 없는게 당연함
인스턴스 변수
- 클래스의 객체를 생성할 때 만들어짐
- JVM 영역 중 Heap 영역에 로드됨
- 클래스의 객체마다 독립적인 값을 가질 수 있음
지역 변수
- 메서드/블럭 내에서 선언된 변수로, 메서드 호출 시 생성되고 메서드 종료 시 해제됨
- JVM 영역 중 Stack 영역에 로드됨변수 종류 영역 static 변수 (정적 변수, 클래스 변수) Method Area - 모든 객체가 공유함
- 클래스 로더가 클래스를 Method 영역에 적재할 때 생성인스턴스 변수 Heap Area - 객체마다 서로 다른 값을 가짐
- 객체를 생성할 때 인스턴스 변수가 생성되고, 객체가 소멸할 때 자동으로 소멸됨지역 변수 [자바의 메모리 구조]
PC Register
- 현재 수행중인 JVM 명령어 저장
JVM stack
- 호출된 메서드의 매개변수, 지역변수, 리턴 정보 저장
Native Method Stack
- Java 외의 언어 (C, C++)로 구현된 정보 저장
Heap
- runtime 중 생성되는 객체들이 저장
- Garbage Collector 대상 O
Method(Static)
- 전역변수, static 변수, 메서드 정보, 생성자 저장
- Garbage Collector 대상 X
- 프로그램이 종료될 때 해제됨
[this]
- 클래스 내부에서 현재 객체의 참조를 나타냄
- 주로 클래스의 인스턴스 메서드와 생성자 내에서 사용함
- 해당 메서드나 생성자가 호출된 객체를 가리킴
- 같은 클래스 내의 다른 생성자를 호출할 때 사용됨 (constructor chaining)
* 생성자 오버로딩으로 인한 코드 중복 방지
- method chaining을 위해 현재 객체를 반환
- inner class에서 outer class의 instance를 참조할 때 사용
UML (Unified Modeling Language)
[생성자]
- 역할: 객체를 생성하는 시점에서 field를 다양하게 초기화
- 선언: [Class Name] (...) {...}
* 생성자 이름 == 클래스 이름
* 일반적으로 public으로 선언됨
* 리턴 타입은 없다
* new 연산자와 함께 사용함
* 오버로딩이 가능함
* 만약 생성자가 이미 존재하면, 컴파일러는 default 생성자를 만들지 않음!
default 생성자
- 모든 클래스는 최소한 하나의 생성자가 있음
- 생성자를 선언하지 않으면, 컴파일러가 자동으로 디폴트 생성자를 추가함
생성자 체이닝
- 상위 클래스 생성자는 하위 클래스에서 상속될 수 없음
- this 키워드 또는 super 키워드는 생성자의 첫 번째 라인에 작성해야 함
- 생성자에서 this 키워드와 super 키워드 둘 다 사용할 수 없음
- 생성자 호출과 실행은 반대로 동작함
- 생성자에 super()를 추가하지 않은 경우 JVM은 super 키워드를 생성자에 암시적으로 추가합니다.
- 생성자 이름을 직접 호출할 수 없음
메서드 체이닝
- 하나의 객체에서 여러 메서드를 연속적으로 호출하는 프로그래밍 기법
- 각 메서드가 호출된 객체를 반환하는 방식으로 작동함
- Setter를 변경해서 사용가능
* return type: Class type
* return this; 추가
- 사용법: [객체].(메서드1).(메서드2).(메서드3) ...
정적 멤버의 활용
- 클래스이름.정적변수이름
ex) Math.PI
- 클래스이름.정적메서드이름
ex) Integer.parseInt()
[Object 클래스]
- 자바에서 모든 클래스의 최상위 부모 클래스
- 명시적으로 부모를 extends 하지 않은 클래스들의 묵시적 부모
숙제! Object 클래스의 3개 메소드 읽어보기
* hashCode()- 객체의 해시 코드를 반환
- 해시 코드는 객체를 해시 기반 컬렉션(예: HashMap, HashSet)에서 식별하거나 저장할 때 사용됨
1) 해시 코드의 기본 개념
해시 코드는 객체를 식별하는 데 사용되는 정수 값
이 값은 객체의 메모리 주소에 기반할 수 있지만, 구체적인 구현은 JVM에 따라 다를 수 있음
해시 코드는 객체의 hashCode() 메서드를 호출할 때 반환됨
2) 기본 구현
객체의 메모리 주소를 기반으로 한 해시 코드를 반환함
기본 구현은 객체의 참조 값에서 해시 코드를 생성함
이 기본 구현은 객체가 동일한 메모리 주소를 참조할 때마다 같은 해시 코드를 반환함
3) 오버라이딩
오버라이딩 시, equals() 메서드와 일관되게 hashCode()를 구현해야 함
즉, 두 객체가 equals() 메서드에 의해 동일하다고 평가되면, 이 두 객체의 hashCode() 값도 동일해야 함
4) 해시 코드와 equals() 메서드의 관계
equals()와 hashCode()의 계약: 두 객체가 equals() 메서드에 의해 동일하다고 평가되면, 두 객체의 hashCode() 값도 같아야 함
해시 기반 컬렉션(HashMap, HashSet 등)은 이 계약을 사용하여 객체를 비교하고, 같은 해시 코드를 가진 객체를 빠르게 찾을 수 있음5) 예제
public class MyClass { private int id; private String name; public MyClass(int id, String name) { this.id = id; this.name = name; } @Override public int hashCode() { int result = 17; // 임의의 시작 값 result = 31 * result + id; // id의 해시 값을 포함 result = 31 * result + (name != null ? name.hashCode() : 0); // name의 해시 값을 포함 return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; MyClass myClass = (MyClass) obj; return id == myClass.id && (name != null ? name.equals(myClass.name) : myClass.name == null); } }
* toString()
- 객체를 문자열로 표현하는 데 사용됨
- 객체를 사람이 읽을 수 있는 형태로 반환함
- 디버깅, 로깅에 유용
1) 기본 구현
- 객체의 클래스 이름과 해시 코드의 16진수 표현을 포함한 문자열을 반환함
- 다음과 같은 형태를 반환함
getClass().getName() + '@' + Integer.toHexString(hashCode()); // MyClass@1a2b3c4d
2) 오버라이딩
- 보통 사용자 정의 클래스에서 오버라이드하여 객체의 중요한 정보를 포함하는 문자열을 반환하도록 함
- 오버라이딩 시, 객체의 상태를 나타내는 정보를 포함시켜서 객체의 내용이 무엇인지 쉽게 이해할 수 있도록 함
3) 예제
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } public static void main(String[] args) { Person person = new Person("Alice", 30); System.out.println(person.toString()); // Person{name='Alice', age=30} } }
* equals()
- 두 객체가 동일한지 비교하는 데 사용함- 기본 구현은 객체의 참조(즉, 메모리 주소)를 비교하지만, 일반적으로는 객체의 내용이 같은지 비교하도록 오버라이드하여 사용함
1) 기본 구현
- 두 객체의 참조를 비교함
- 즉, 두 객체가 동일한 메모리 위치를 참조하는 경우에만 true를 반환함
public boolean equals(Object obj) { return (this == obj); }
2) 오버라이딩
- equals() 메서드를 오버라이드하여 객체의 내용이 동일한지 비교하도록 할 수 있음
* null 안전: x.equals(null)은 항상 false를 반환해야 함
- 오버라이딩 예제
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object obj) { if (this == obj) return true; // 자기 자신과 비교 if (obj == null || getClass() != obj.getClass()) return false; // 클래스 타입 확인 Person person = (Person) obj; // 타입 캐스팅 return age == person.age && name.equals(person.name); // 필드 비교 } @Override public int hashCode() { int result = 17; result = 31 * result + name.hashCode(); result = 31 * result + age; return result; } public static void main(String[] args) { Person p1 = new Person("Alice", 30); Person p2 = new Person("Alice", 30); Person p3 = new Person("Bob", 25); System.out.println(p1.equals(p2)); // true System.out.println(p1.equals(p3)); // false } }
3) 사용 예시
- 컬렉션 프레임워크: HashSet, HashMap 등에서 객체의 동등성을 확인할 때 사용됨. 예를 들어, HashSet은 equals() 메서드를 사용하여 객체의 중복 여부를 결정함
- 검색 및 비교: 객체의 내용이 같은지 비교할 때 사용됨
숙제! 상속 예습하기 (이것이 자바다 7.1 ~ 7.4강)
[싱글톤 패턴]
- 어플리케이션 전체에서 단 1개의 객체만 생성해서 사용하는 것
[IntelliJ 단축키]
모든 항목을 검색할 수 있는 검색 상자: Shift 2번