반응형

접근 제한자

접근 제한자 (Access Modifier)란?

  • 클래스, 변수, 메소드를 선언할 때 사용하는 것으로 해당 클래스, 변수, 메소드의 접근을 제한할 때 사용
  • 접근 제한자를 통해 해당 정보를 외부 접근으로부터 보호할 수 있음

접근 제한자의 종류

  • public : 어디에서나 접근가능
  • protected : 동일 클래스, 패키지에서 접근가능 + 해당 클래스를 상속받은 외부 패키지의 클래스에서 접근가능
  • default(안 써주는것) : 동일 클래스, 패키지에서만 접근가능
  • private : 동일 클래스에서만 접근가능
  • public > protected > default > private 순으로 접근 범위가 넓음
  • 변수와 메소드는 모든 접근 제한자를 사용할 수 있지만, 클래스는 public과 default만 사용 가능함

Class에서의 접근 제한자 예시

  • 위와 같이 package a, b가 있고 각각 Car class가 있는 상황
  • Class에는 public과 default만 사용할 수 있는데 a 패키지의 Car은 public이든 default이든 상관없이 CarTest에서 접근이 가능함
  • 하지만 b 패키지의 Car은 public인 경우에만 접근이 가능하고 default라면 다른 패키지인 CarTest에서 접근이 불가능함
  • 우리는 보통 객체를 생성할 때 Car aCar = new Car(); 와 같이 생성함
  • 그런데 a패키지의 Car, b패키지의 Car이 서로 이름이 같기 때문에, 이 상황에서 저런식으로 생성하면 어떤 Car을 뜻하는지 알 수 없음
  • 따라서 저런 상황에서는 아래와 같이 pakage.class 식으로 표현해 주면 됨
a.Car a = new a.Car();
b.Car b = new b.Car();

변수, 메소드에서의 접근 제한자 예시

  • a패키지의 Car, b패키지의 Car에 아래와 같이 4개의 변수 생성 (메소드도 동일)
public class Car {
    public int info1;
    protected int info2;
    int info3;
    private int info4;
}
  • CarTest 클래스에서 a.Car, b.Car 객체를 생성하고 각각의 변수에 접근하려면 어디까지 접근이 가능할까?
  • a.Car에서는 info1, 2, 3 까지 접근이 가능
  • b.Car에서는 info1만 접근 가능
  • private인 info4에 접근하기 위해서는 아래와 같이 getter, setter 생성 후, getter, setter로 접근
    • 개발 툴에서는 보통 Getter, Setter을 자동 생성해주는 기능 존재
    • IntelliJ/Mac => Command + N, IntelliJ/Window => Alt + Insert
public int getInfo4() {
    return info4;
}

public void setInfo4(int info4) {
    this.info4 = info4;
}
  • 이와 같이 private 접근 제한자를 사용해서 다른 클래스에서 접근하지 못하게 하는 것을 "정보은닉" 이라고 함

Static

Static 생성 방식

  • static은 Heap영역에 생성되는 다른 instance들과는 달리 class와 같이 Method Area 영역에 생성됨
  • class와 같이 생성되기 때문에 접근 방식과 범위가 다름

Static 변수 (정적 변수 = 클래스 변수 = 공용 변수), 메소드도 동일

public class Test {
    public static void main(String[] args) {
        Car a = new Car();
        Car b = new Car();
        Car c = new Car();
        System.out.println("생성된 차 개수 : " + Car.carCnt);     // 3 출력
    }
}
class Car {
    static int carCnt = 0;

    Car() {
        carCnt ++;
    }
}
  • 만약 carCnt 변수가 static이 아니였다면 Car a, b, c에 속하는 변수로 생성 => a.carCnt로 접근
  • 하지만 static을 붙임으로서 a.carCnt로는 접근이 불가능하고 Car class의 공용 변수로써 사용됨
    • Car.carCnt로 접근
public class Test {
    static int x = 100;
    int y = 100;

    public static void main(String[] args) {
        System.out.println(x);
        System.out.println(y);  // 에러 발생
    }
}
  • main 메소드 바깥족에서 변수를 생성했을 때, static으로 선언하면 Test Class와 같이 Method Area 영역에 올라가기 때문에 main 메소드에서도 사용할 수 있음

Static 클래스

public class Test {

    public static void main(String[] args) {
        A a = new A();  // 에러 발생
        B b = new B();
        C c = new C();
    }
    class A { }
    static class B { }
}
class C { }
  • class는 public class 바깥쪽에 생성해 외부 클래스 인스턴스를 생성하여 사용
  • 하지만 static class는 외부 클래스 인스턴스 생성 없이 사용 가능
  • 아래와 같이 C class는 Test class 외부에 생성되서 사용 가능하지만 B class는 내부에 생성됨

public static void main(String[] args)

  • Java 파일을 실행하기 위해서 반드시 필요한 public static void main (psvm)
  • 위의 내용들을 이해하면 psvm의 의미를 알 수 있음
  1. JVM이 java 파일을 실행할 때, main을 가장 먼저 찾아 들어가야 함
    • static은 인스턴스 생성과 상관없이 제일 먼저 호출되는 메소드이기 때문에 main은 static이여야 함
  2. public을 써주는 이유는 외부(JVM)에서도 main에 접근이 가능해야 하기 때문
  3. void를 써주는 이유는 main 함수는 return 값이 없기 때문
  4. String[] args는 java 파일을 실행할 때, 외부에서 값을 전달할 수도 있는데 이 때 필요함. 미사용해도 되지만 써주기는 해야됨
반응형

↓ 클릭시 이동

복사했습니다!