ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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번

Designed by Tistory.