1. 속성: getter 및 setter

수십 명의 프로그래머가 동시에 대규모 프로젝트를 개발할 때 클래스 필드에 저장된 데이터를 다르게 처리하면 문제가 자주 발생합니다.

사람들이 수업 문서를 자세히 공부하지 못하거나 모든 사례를 설명하지 않을 수도 있습니다. 결과적으로 개체의 내부 데이터가 "손상"되어 개체가 무효화되는 상황이 자주 발생합니다.

이러한 상황을 피하기 위해 Java에서 모든 클래스 필드를 비공개로 만드는 것이 일반적입니다 . 클래스의 메서드만 클래스의 변수를 수정할 수 있습니다. 다른 클래스의 메서드는 변수에 직접 액세스할 수 없습니다.

다른 클래스가 클래스의 개체 내부에 있는 데이터를 가져오거나 변경할 수 있도록 하려면 클래스에 get 메서드와 set 메서드라는 두 가지 메서드를 추가해야 합니다. 예:

암호 메모
class Person
{
   private String name;

   public Person(String name)
   {
      this.name = name;
   }

   public String getName()
   {
      return name;
   }

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


private이름 필드



생성자를 통한 필드 초기화


getName()— 이 메서드는 이름 필드의 값을 반환합니다




setName()— 이 메서드는 이름 필드의 값을 변경합니다

다른 클래스는 이름 필드의 값을 직접 변경할 수 없습니다. getName() 누군가 이름 필드의 값을 가져와야 하는 경우 개체 에서 메서드를 호출해야 합니다 Person. setName() 일부 코드가 이름 필드의 값을 변경하려는 경우 개체 에서 메서드를 호출해야 합니다 Person.

이 메서드는 " 이름 필드에 대한 gettergetName() " 라고도 하며 이 메서드는 " 이름 필드에 대한 setter " 라고 합니다 .setName()

이것은 매우 일반적인 접근 방식입니다. 모든 Java 코드의 80-90%에서는 클래스에서 공용 변수를 볼 수 없습니다. private대신 선언 (또는 ) 되며 protected각 변수에는 공개 getter 및 setter가 있습니다.

이 접근 방식은 코드를 더 길지만 더 안정적으로 만듭니다.

클래스 변수에 직접 액세스하는 것은 이중 노란색 선을 통해 자동차를 돌리는 것과 같습니다 . 더 쉽고 빠르지만 모든 사람이 그렇게 하면 모든 사람에게 상황이 악화됩니다.

x점( , ) 을 설명하는 클래스를 만들고 싶다고 가정해 보겠습니다 y. 초보자 프로그래머가 수행하는 방법은 다음과 같습니다.

class Point
{
   public int x;
   public int y;
}

숙련된 Java 프로그래머가 수행하는 방법은 다음과 같습니다.

암호
class Point {
   private int x;
   private int y;

   public Point(int x, int y) {
      this.x = x;
      this.y = y;
   }

   public int getX() {
      return x;
   }

   public void setX(int x) {
      this.x = x;
   }

   public int getY() {
      return y;
   }

   public void setY(int y) {
      this.y = y;
   }
}

코드가 더 긴가요? 의심할 여지 없이.

그러나 getter 및 setter에 매개변수 유효성 검사를 추가할 수 있습니다. x예를 들어 및 가 y항상 0보다 큰지(또는 0보다 작지 않은지) 확인할 수 있습니다 . 예:

암호 메모
class Point {
   private int x;
   private int y;

   public Point(int x, int y) {
      this.x = x < 0 ? 0 : x;
      this.y = y < 0 ? 0 : y;
   }

   public int getX() {
      return x;
   }

   public void setX(int x) {
      this.x = x < 0 ?  0 : x;
   }

   public int getY() {
      return y;
   }

   public void setY(int y) {
      this.y = y < 0 ? 0 : y;
   }
}


2. 개체 수명

연산자 를 사용하여 개체가 생성된다는 것은 이미 알고 new있지만 개체는 어떻게 삭제됩니까? 그들은 영원히 존재하지 않습니다. 메모리가 부족합니다.

C++와 같은 많은 프로그래밍 언어에는 개체를 삭제하기 위한 특수 연산자가 있습니다 delete. 그러나 이것은 Java에서 어떻게 작동합니까?

Java에서는 모든 것이 약간 다르게 배열됩니다. Java에는 삭제 연산자가 없습니다. 이것은 객체가 Java에서 삭제되지 않는다는 것을 의미합니까? 아니요, 물론 삭제됩니다. 그렇지 않으면 Java 응용 프로그램의 메모리가 빠르게 부족해지고 몇 달 동안 중단 없이 실행되는 프로그램에 대한 이야기가 없을 것입니다.

Java에서는 개체 삭제가 완전히 자동화됩니다. Java 시스템 자체에서 개체 삭제를 처리합니다. 이 프로세스를 가비지 수집이라고 하며, 가비지를 수집하는 메커니즘을 가비지 수집기 ( GC ) 라고 합니다 .

그렇다면 자바 머신은 언제 객체를 삭제해야 하는지 어떻게 알 수 있을까요?

가비지 컬렉터는 모든 객체를 "도달 가능"과 "도달 불가"로 나눕니다. 객체에 대한 참조가 하나 이상 있으면 도달 가능한 것으로 간주됩니다. 개체를 참조하는 변수가 없으면 해당 개체는 도달할 수 없는 것으로 간주되고 삭제할 수 있음을 의미하는 쓰레기로 선언됩니다.

Java에서는 기존 개체에 대한 참조를 만들 수 없습니다. 이미 가지고 있는 참조만 할당할 수 있습니다. 개체에 대한 모든 참조를 지우면 영원히 손실됩니다.

순환 참조

그 논리는 우리가 간단한 반례에 도달할 때까지 훌륭하게 들립니다: 서로를 참조하는 두 개의 개체가 있다고 가정합니다(서로에 대한 참조 저장). 다른 개체는 이러한 개체에 대한 참조를 저장하지 않습니다.

이러한 개체는 코드에서 액세스할 수 없지만 여전히 참조됩니다.

이것이 가비지 컬렉터가 객체를 "참조된" 객체와 "참조되지 않은 객체"가 아닌 도달 가능한 객체와 도달 불가능한 객체로 나누는 이유입니다.

도달 가능한 개체

먼저 100% 살아 있는 개체를 도달 가능한 목록에 추가합니다. 예를 들어, 현재 스레드( Thread.current()) 또는 콘솔 InputStream( System.in).

그런 다음 연결 가능한 개체 목록이 확장되어 초기 연결 가능한 개체 집합에서 참조하는 개체를 포함합니다. 그런 다음 이 확장된 집합에서 참조하는 개체를 포함하도록 다시 확장됩니다.

즉, 서로 참조만 하는 개체가 있지만 도달 가능한 개체에서 접근할 수 있는 방법이 없는 경우 해당 개체는 가비지로 간주되어 삭제됩니다.


3. 쓰레기 수거

메모리 단편화

객체 삭제와 관련된 또 다른 중요한 점은 메모리 조각화입니다. 지속적으로 개체를 만들고 삭제하면 곧 메모리가 심하게 조각화됩니다. 점유된 메모리 영역과 비어 있는 메모리 영역이 산재해 있습니다.

결과적으로 사용 가능한 메모리가 많지 않기 때문에 큰 객체(예: 백만 개의 요소가 있는 배열)를 만들 수 없는 상황에 쉽게 빠질 수 있습니다. 즉, 사용 가능한 메모리가 많더라도 연속적으로 사용 가능한 메모리 블록이 크지 않을 수 있습니다.

메모리 최적화(조각 모음)

Java 머신은 특정 방식으로 이 문제를 해결합니다. 다음과 같이 보입니다.

메모리는 두 부분으로 나뉩니다. 모든 개체는 절반의 메모리에서만 생성(및 삭제)됩니다. 메모리의 구멍을 정리할 시간이 되면 전반부의 모든 객체가 후반부에 복사됩니다. 그러나 그들은 구멍이 없도록 서로 바로 옆에 복사됩니다.

프로세스는 대략 다음과 같습니다.

1단계: 개체 생성 후

Java의 가비지 컬렉션

2단계: "구멍" 모양

Java 2의 가비지 컬렉션

3단계: "구멍" 제거

Java 3의 가비지 컬렉션

따라서 개체를 삭제할 필요가 없습니다. Java 머신은 도달 가능한 모든 개체를 새 위치에 복사하고 개체가 저장되었던 전체 메모리 영역을 해제합니다.