Home [Java] 제어자
Post
Cancel

[Java] 제어자

제어자(modifier)

클래스, 변수, 메서드의 선언부에 함께 사용되어 부가적인 의미를 부여한다.

접근제어자 : public, protected, default, private

그 외 : static, final, abstract, native, transient, synchronized, volatile, strictfp

  • 하나의 대상에 대해서 여러 제어자를 조합하여 사용하는 것이 가능하다.
  • 접근제어자는 네가지 중 하나만 사용할 수 있다.
  • 제어자 간의 순서는 관계없지만 주로 접근제어자를 제일 왼쪽에 놓는 경향이 있다.

static

클래스의, 공통적인 이라는 의미를 가지고 있다.

대상의미
멤버변수- 모든 인스턴스에 공통적으로 사용되는 클래스변수가 된다.
- 클래스변수는 인스턴스를 생성하지 않고도 사용 가능하다.
- 클래스가 메모리에 로드될 때 생성된다.
메서드- 인스턴스를 생성하지 않고도 호출 가능한 static 메서드가 된다.
- static메서드 내에서는 인스턴스 멤버들을 직접 사용할 수 없다.
초기화블럭- 클래스가 메모리에 로드될 때 단 한 번만 수행된다.
- 주로 클래스변수(static 변수)를 초기화하는 데 사용된다.

final

마지막의, 변경될 수 없는 이라는 의미를 가지고 있다.

대상의미
클래스- 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다.
- 그래서 final로 지정된 클래스는 다른 클래스의 조상이 될 수 없다.
메서드- 변경될 수 없는 메서드가 된다.
- final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없다.
멤버변수
지역변수
- 변수 앞에 final이 붙으면, 값을 변경할 수 없는 상수가 된다.
  • 멤버변수가 final일 경우 선언과 함께 초기화하지 않고 생성자에서 단 한번 초기화할 수 있다.
1
2
3
4
5
6
7
8
9
class Item {
  final int PRICE;
  final String NAME;
  
  Item(int price, String name) {
    PRICE = price;
    NAME = name;
  }
}

abstract

추상의, 미완성의 라는 의미를 가지고 있다.

대상의미
클래스클래스 내의 추상 메서드가 선언되어 있음을 의미한다. (추상 클래스)
메서드선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알린다.
1
2
3
abstract class AbstractClass {	// 추상 클래스 (추상 메서드를 포함한 클래스)
  abstract void move();		// 추상 메서드 (구현부가 없는 메서드)
}
  • 추상 메서드가 없는 클래스에 abstract를 붙여서 추상 클래스로 만드는 경우도 있다.
    • 메서드의 구현부에 아무 내용이 없어서 인스턴스를 생성해도 할 수 있는 게 없어서 인스턴스를 생성하지 못하게 붙여놓은 것이다.
    • 다른 클래스가 이 클래스를 상속받아서 일부의 원하는 메서드만 오버라이딩해도 된다는 장점이 있다.

접근제어자 (access modifier)

멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할을 한다.

object

  • 사용될 수 있는 곳 : 클래스, 멤버변수, 메서드, 생성자
  • 접근 범위 : public > protected > default > private
  • public은 접근 제한이 전혀 없다.
  • protected는 패키지에 관계없이 다른 패키지의 자손클래스에서 접근할 수 있도록 하는 것이 제한목적이지만 같은패키지 내에서도 접근할 수 있다. 그래서 protected가 default보다 접근범위가 더 넓다.
  • 접근 제어자가 지정되어 있지 않으면 접근제어자가 default임을 뜻한다.
대상사용 가능한 접근 제어자
클래스public, (default)
메서드
멤버변수
public, protected, (default), private
지역변수없음

접근제어자를 사용하는 이유

  • 외부로부터 데이터를 보호하기 위해서
  • 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서

👉 둘 다 객체지향의 캡슐화에 해당하는 내용이다.

생성자의 접근제어자

사용할 수 있는 인스턴스의 개수를 제한하는 방법

  1. 생성자의 접근제어자를 private로 설정 (외부에서 생성자에 접근하지 못하도록)
  2. 대신 인스턴스를 생성해서 반환해주는 public static 메서드를 제공하여 외부에서 이 클래스의 인스턴스를 사용할 수 있도록 한다.
1
2
3
4
5
6
7
8
9
10
11
class Singleton {
  // getInstance()에서 사용될 수 있도록 인스턴스가 미리 생성되어야 하므로 static 이어야 한다.
  private static Singleton s = new Singleton();
  private Singleton() {
    // ...
  }
  // 인스턴스를 생성하지 않고도 호출할 수 있어야 하므로 static이어야 한다.
  public static Singleton getInstance() {
    return s;
  }
}

상속할 수 없는 클래스라는 것을 알리는 방법

  1. 생성자의 접근 제어자를 private으로 설정 (자손 클래스에서 호출하지 못하도록)
  2. 클래스 앞에 final을 추가하여 상속할 수 없는 클래스라는 것을 알린다.
1
2
3
class final class Math {
  private Math() {}
}

⭐ 제어자의 조합

대상사용가능한 제어자
클래스public, (default), final, abstract
메서드모든 접근 제어자, final, abstract, static
멤버변수모든 접근 제어자, final, static
지역변수final

제어자를 조합할 때 주의 사항

  1. 메서드에 staticabstract를 함께 사용할 수 없다. static 메서드는 인스턴스가 없어도 메서드 호출을 할 수 있는데 abstract는 구현부가 없기 때문이다.
  2. 클래스에 abstractfinal을 동시에 사용할 수 없다. 클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미이고 abstract는 상속을 통해 완성되어야 한다는 의미이므로 서로 모순되기 때문이다.
  3. abstract 메서드의 접근제어자가 private일 수 없다. abstract 메서드에서는 자손 클래스에서 구현해주어야 하는데 접근 제어자가 private이면 자손클래스에서 접근할 수 없기 때문이다.
  4. 메서드에 privatefinal을 같이 사용할 필요는 없다. 접근 제어자가 private인 메서드는 오버라이딩 될 수 없기 때문이다. 둘 중 하나만 사용해도 의미가 충분하다.

출처📎

  • 자바의 정석
This post is licensed under CC BY 4.0 by the author.