지정자(public, static, void 등)
이번에 자바를 공부하면서 처음에 헷갈렸던 부분이 바로 클래스나 메서드, 변수 할당 등을 할 때 선언하는 지정자였다.
인텔리제이나 이클립스 등에서 그냥 psvm 만 치면 public static void 가 자동으로 떠서 그냥저냥 썼지만, 도저히 왜? 언제? public을 사용하고 언제는 private를 쓰는지 헷갈려서 아래에 정리를 해두는 바이다.
1. 접근 제한자(public, private, protected)
1. public
'public' 은 접근 제한자 중 하나로서, 클래스, 메서드, 변수에 대한 접근 수준을 지정할 수 있다.
접근 제한자는 public, private, protected 로 총 3가지 인데, 그 중 public 은 어느 패키지든지 접근 가능한 접근 제한자를 나타낸다.
예를들어,
public class hello {
public int wow;
}
hello 라는 클래스가 있는데, 해당 클래스는 public 으로서, 어디서든 접근이 가능하며, 다른 패키지나 클래스 내에서 wow도 접근 가능하다.
2. private 및 protected
'private'는 해당 클래스 내에서만 접근 가능하며, 만약 private를 다른 곳에서도 사용하고 싶으면 생성자(constructor)를 이용하여 접근하도록 해야된다.
'protected' 는 해당 클래스 및 동일한 패키지 내의 다른 클래스와 하위 클래스에서 접근 가능하다.
예를들어,
public class MyClass {
private int myPrivateVariable; // 오직 MyClass 내에서만 접근 가능
protected int myProtectedVariable; // MyClass, 동일한 패키지 내의 클래스, 하위 클래스에서 접근 가능
int myDefaultVariable; // 동일한 패키지 내의 클래스에서 접근 가능
}
위의 경우에는 클래스는 public 이지만 myPrivateVariable은 private이므로 다른 클래스 내에서 해당 변수는 접근할 수 없다.
2. 비접근 수식어(static, final, abstract, synchroized, volatile, transient 등)
비접근 수식어는 특정 선언에 대한 속성이나 동작을 지정하거나 변경하기 위해 사용된다. java에서 수식어는 크게 두가지로 분류될 수 있다.
1. 접근 제한자
접근 제한자는 위의 1번에서 설명한 public,private,protected를 말한다. 그리고 default 값도 있는데 이는 명시적인 접근 제한자가 없는 경우에는 동일한 패키지 내에서만 접근 가능하다.
2. 비접근 수식어
- static : 클래스 수준의 맴버(클래스, 메서드, 변수) 를 선언한다. static은 쉽게 설명하자면, 하나의 메모리에 위치하기 때문에 값이 공유가 된다고 생각하면 된다.
예를들면,
public class Student {
private String name;
private static int studentCount = 0; // static 변수
public Student(String name) {
this.name = name;
studentCount++; // 새로운 학생 객체가 생성될 때마다 증가
}
public static int getStudentCount() { // static 메서드
return studentCount;
}
}
public class Main {
public static void main(String[] args) {
Student student1 = new Student("John");
System.out.println(Student.getStudentCount()); // 출력: 1
Student student2 = new Student("Jane");
System.out.println(Student.getStudentCount()); // 출력: 2
Student student3 = new Student("Jake");
System.out.println(Student.getStudentCount()); // 출력: 3
}
}
여기에서, name은 static이 아니고, 생성자를 통해 name은 John, Jane,Jake 라는 3개의 각각 독립된 값을 갖지만, static이 붙은 studentCount는 값이 하나의 메모리에 올라가기 때문에 출력이 1,2,3으로 증가되는 모습이다.
조금만 더 설명하자면,
- static 변수 : 모든 인스턴스가 같은 메모리 위치의 값을 공유한다. 하나의 인스턴스에서 이 변수의 값을 변경하면, 모든 인스턴스에서 변경된 값을 볼 수 있다.
- static 메서드 : 클래스의 인스턴스 없이 호출될 수 있으며 , 인스턴스 변수에 직접적으로 접근할 수 없다.
그래서 static은 아래와 같은 경우에 주로 사용된다.
1) 모든 인스턴스가 공유해야 하는 상수나 설정값
2) 객체를 생성하지 않고도 호출해야 하는 유틸리티나 헬퍼 메서드
3) 클래스 수준에서 관리되어야 하는 카운팅이나 리소스
예를 들자면, 게임을 하는데 전체 플레이어 수를 추적하려면 static 변수를 사용하면 된다. 플레이어 수가 증가할 때마다 static 카운터를 증가시키면 어느 플레이어 객체에서든 플레이어 수를 추적할 수 있다.
3. void
'void' 는 메서드가 반환할 값이 없음을 나타낸다. 만약 반환할 값이 있으면 해당 반환값을 넣으면 된다.