JAVA/자바 이론 / / 2021. 4. 15. 10:55

Java | 4-3 클래스와 객체

09. 객체의 소멸과 garbage collection

10. 멤버 접근 지정자

11. static 멤버와 non-static 멤버

 

# 객체의 소멸과 Garbage Collection

º 객체 소멸

- new에 의해 생성된 객체에 할당되었던 메모리를 JVM에게 되돌려 주는 것

- 가용 메모리에 포함시킴

º 자바는 객체 삭제 기능 없음

- 개발자에게는 매우 다행스러운 것

   -> C/C++에서는 할당받은 객체를 개발자가 프로그램 내에서 삭제해야 함

º Garbage Collection

- 객체에 대한 레퍼런스가 없어지면 객체는 가비지(garbage)가 됨

- JVM의 grbage collector가 garbage를 반환

 

#Garbage Collection

º 자동 실행

- JVM에 포함된 가비지 컬렉터(garbage collector)가 자동으로 실행

º 개발자가 강제로 실행하려는 경우

- System 또는 Runtime 객체의 gc() 메소드를 호출한다.

System.gc();   //가비지 컬렉션 작동 요청

º 그러나 garbage collection 시점은 JVM이 전적으로 판단한다.

 

# 클래스 접근 지정자

º 클래스 앞에 올 수 있는 접근 지정자

- public 접근 지정자

public class Person {}

-> 다른 모든 클래스가 접근 가능

º 접근 지정자 생량 (default 접근 지정자)

class Person {}

-> 또는 package-private라고도 함

-> 같은 패키지 내에 있는 클래스에서만 접근 가능 ( 동일한 폴더 속에 있는 클래스끼리 접근 가능)

 

# 멤버 접근 지정자

default (package-private) 같은 패키지 내에서 접근 가능
public 패키지 내부, 외부 클래스에서 접근 가능
private 정의된 클래스 내에서만 접근 가능
상속 받은 하위 클래스에서도 접근 불가
protected 같은 패키지 내에서 접근 가능
다른 패키지에서 접근은 불가하나 상속을 받은 경우 하위 클
래스에서는 접근 가능
  멤버의 접근 지정자
멤버에 접근하는 클래스 default private protected public
같은 패키지의 클래스 O X O O
다른 패키지의 클래스 X X X O

 

ex) 다음의 소스를 컴파일 해보고 오류가 난 이유를 설명하고 오류를 수정하시오.

pulibc class Sample {
	public int a;
    private int b;
    int c;
}

public class AccessDemo1 {
	public static void main(String[] args) {
    	Sample aClass = new Sample();
        aClass.a = 10;
        aClass.b = 10;   //오류 발생
        aClass.c = 10;
    }
}

º 오류 수정된 코드

class Sample {
	pubilc int a;
    private int b;
    int c;
    public int getB() {
    	return b;
    }
    public void setB(int value) {
    	b = value;
    }
}
public class AccessDemo1 {
	public static void main(String[] args) {
    	Sample aClass = new Sample();
        aClass.a = 10;
        aClass.setB(10);
        aClass.c = 10;
    }
}

- Sample 클래스의 a와 c는 각각 public, default 지정자로 선언이 되었으므로 같은 패키지에 속한 AccessEx 클래스에서 접근이 가능

- b는 private으로 선언이 되었으므로 AccessEx 클래스에서는 접근이 불가능

- private 접근 지정자를 갖는 멤버는 클래스 내부에 get/set 메소드를 만들어서 접근

 

# 데이터 보호와 캡슐화

º 데이터 참조나 메소드의 호출을 제한할 때는 접근 제어자를 이용

º 클래스의 캡슐화 : 변수 앞에 private를 사용해서 변수에 직접 참조하는 것을 막고, public 메소드를 통해서만 참조하고 메소드를 통해서만 데이터가 변경이 되도록 하는 것. 접근자(getters), 설정자(setters)가 있음

- getter 메소드 : 변수의 값을 제공하는 메소드, getName( )

- setter 메소드 : 변수에 값을 설정하는 메소드, setName( )

º 정보 은닉 : 구현의 세부 사항을 클래스 안에 감추는 것으로 클래스 안의 데이터를 외부에서 마음대로 변경하지 못하게 하는 것

º 클래스 안에 변수를 선언시 private를 붙이는 것이 좋음

 

# 접근자(getter)와 설정자(setter)

º 변수는 private으로 처리하고 getter/setter 메소드를 통해서만 변수를 변경하는 예제

public class Person {
	private String name;   //변수는 외부에서 직접 참조가 불가능하도록 private 적용
    private int age;
    
    /* 변수에 값의 변경이나 반환을 위한 setter/getter 메소드는 public으로 정의해서 
    외부에서 접근이 가능하도록 정의 */
    
    public String getName() {
    	return name;
    }
    
    public void setName(String name) {
    	this.name = name
    }
    
    public int getAge() {
    	return age;
    }
    
    public void setAge(int age) {
    	this.age = age;
    }
    
    public void tell() {
    	System.out.println("안녕하세요?" + age + "살" + name + "입니다!");
     }
}

º private 필드에는 접근자와 설정자를 이용하여 접근 가능

public class PersonEx {
	public static void main(String[] args) {
    	Person person = new Person();
        
        //person.name = "김ㅇㅇ";  //name 변수에 직접 참조는 불가능
        person.setName("김ㅇㅇ");  //setter 메소드를 이용하여 변수에 참조 가능
        //person.Age = 20;        //age 변수에 직접 참조는 불가능
        person.setAge(20);        //setter 메소드를 이용하여 변수에 참조 가능
        person.tell();
        
        person.getName();         //getter 메소드를 이용하여 name 변수 값 제공
        person.getAge();          //getter 메소드를 이용하여 age 변수 값 제공
    }
}

# 접근자와 설정자의 사용 이유

º 접근자와 설정자를 사용하여 필드를 간접적으로 접근하는 이점

- 접근자와 설정자를 사용해야만 나중에 클래스를 업그레이드 할 때 편리함

- 접근자에서 매개 변수를 통하여 잘못된 값이 넘어오는 경우 사전에 차단 가능

- 필요할 때마다 필드값을 계산해서 반환 가능

- 접근자만을 제공하면 자동적으로 읽기만 가능한 필드를 만들 수 있음

-> 가능하다면 항상 접근자와 설정자를 사용하는 게 좋음!

 

# static 멤버와 non-static 멤버

º non-static 멤버 (인스턴스 멤버)

- 객체마다 독립적으로 존재

- 각 필드와 메소드는 객체가 생성된 후에 사용할 수 있음

º static 멤버 (클래스  멤버)

- 클래스에 하나만 생성

- 클래스가 로딩될 때 공간을 할당 받음

- 동일한 클래스의 모든 객체에 의해 공유

public class StaticSample {
	int n;               //non-static 필드
    void g() { }         //non-static 메소드
    static int m;        //static 필드
    static void f() { }  //static 메소드

# static의 활용

º 전역 변수와 전역 함수를 만들 때 활용

- 자바에서의 캡슐화 원칙

-> 다른 모든 클래스에서 공유하는 전역 변수나 전역 함수도 클래스 내부에만 정의

º java.lang.Math 클래스

- JDK와 함께 배포되는 java.lang.Math 클래스

- 모든 메소드가 static으로 정의되어 다른 모든 클래스에서 사용됨

- 객체를 생성하지 않고 바로 호출할 수 있는 상수와 메소드 제공

 

# static 메소드의 제약 조건

º static 메소드는 오직 static 멤버만 접근 가능

- 객체가 생성되지 않은 상황에서도 사용이 가능하므로 객체에 속한 인스턴스 메소드, 인스턴스 변수 등 사용 불가

- 인스턴스 메소드는 static 멤버들을 모두 사용 가능

º static 메소드에서는 this 키워드를 사용할 수 없음

- 객체가 생성되지 않은 상황에서도 호출이 가능하기 때문에 현재 실행중인 객체를 가리키는 this 레퍼런스를 사용할 수 없음

 

# final

º final 클래스 - 더 이상 클래스 상속 불가능

final class FinalClass {
        ...
}
class DerivedClass extends FinalClass {   //컴파일 오류 발생
        ...
}

º final 메소드 - 더 이상 오버라이딩 불가능

public class SuperClass {
	protected final int finalMethod() { ... }
}

class DerivedClass extends SuperClass {
	protected int finalMethod() { ... }
    						///컴파일 오류, 오버라이딩 할 수 없음
}

º final 필드, 상수 정의

- 선언시에 초기값을 지정하며 값을 변경할 수 없다.

public class FinalFieldClass {
	final int ROWS = 10; //상수 정의, 이때 초기 값(10)을 반드시 설정
    final int COLS;      //컴파일 오류, 초기값을 지정하지 않았음
    void f() {
    	int [] intArray = new int [ROWS];  //상수 활용
        ROWS = 30;  //컴파일 오류, final 필드 값을 변경할 수 없다.
    }
}

 

# 요약

  •  객체 지향 언어에서는 실세계를 모델링하여 객체, 객체 간의 관계, 객체 간의 상호작용을 나타내는 언어로 캡슐화, 상속, 다형성의 특징을 가짐.
  •  클래스는 객체를 생성하기 위한 설계도 또는 틀이라고 하며, 객체는 설계도 또는 틀로써 찍어낸 실체이며, 객체는 실체를 뜻하는 인스턴스라고도 부름.
  • 클래스는 객체들의 특성과 행동에 대한 절차나 방법을 구현하며, class 키워드를 사용하여 선언
  • 클래스는 필드(멤버 변수)와 메소드(멤버 함수)로 구성
  •  자바에서는 반드시 new 키워드를 사용하여 객체를 생성함.
  •  객체의 배열에서 배열의 원소는 객체가 아니며 객체에 대한 레퍼런스로서 객체 배열 생성 후 다시 원소의 개수만큼 객체를 생성해서 배열의 각 원소에 지정해야 함.
  • 자바의 메소드 호출 시 기본 타입은 '값에 의한 호출(call by valu)'로 전달되고, 객체나 배여을 인자로 전달할 때는 객체나 배열의 레퍼런스만 전달됨.
  • 메소드 오버로딩은 한 클래스 내에서 이름은 같지만 매개변수의 개수나 타입이 다른 여러 개의 메소드를 작성하는 것을 뜻함.
  •  this는 현재 객체를 가리키는 레퍼런스
  •  생성자는 new를 통해 객체를 생성할 때 호출되며 주로 객체의 필드를 초기화함.
  •  this()는 생성자에서 다른 생성자를 호출하는 문장이며, 생성자의 첫 번째 코드로만 사용할 수 있음.
  •  더 이상 참조되지 않는 객체를 가비지라 하며, 가용 메모리가 일정 수준이하로 줄어들면 가비지 컬렉션이 자동으로 실행됨.
  • 클래스 접근 지정자로는 public 과 default가 사용됨.
  •  멤버 접근 지정자로는 private, protected, default, public이 있음.
  • 객체를 생성하지 않고도 사용할 수 있는 필드, 메소드를 static 필드, static 메소드라고 하며 동일한 클래스의 객체들 사이에 공유됨.
  • 클래스의 static 멤버들은 클래스 당 하나만 생성되며, 프로그램이 시작될 때 이미 생성되어 객체를 생성하지 않고도 사용할 수 있음.
  • final로 선언된 클래스는 상속되지 않으며, final 메소드는 더 이상 오버라이딩 할 수 없음.
  •  final로 선언된 필드는 상수로서 초기화 이후 값을 수정할 수 없음.

 

 

'JAVA > 자바 이론' 카테고리의 다른 글

Java | 5-2 상속과 다형성  (0) 2021.05.25
Java | 5-1 상속과 다형성  (0) 2021.05.25
Java | 4-2 클래스와 객체  (0) 2021.04.14
Java | 4-1 클래스와 객체  (0) 2021.04.14
Java | 3-2 예외 처리  (0) 2021.04.12
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유