1. 사용제한자(Usage Level modifier)
1) static
- 변수, 메서드에 적용되는 자바의 키워드
- 해당 클래스의 객체 없이도 참조 가능
- static 블록 안에는 static 변수만 사용해야 하고, static 메서드만 호출가능
- 지정된 변수와 메서드를 객체와 무관하게 만들어주기 때문에 this를 가질 수 없음
- non-static 메서드로 재정의될 수 엇음
- 대표적인 static 메서드는 main() 메서드
- static에 단순히 블록({})을 사용한 경우에는 정적 초기화자라고 부름
→ static 변수를 초기화하는 역할을 가지고 클래스가 로딩될 때 main() 메서드가 있더라도 앞서 딱 한 번 실행
2) 정적 변수 (static field)
- 모든 객체들이 공유하는 공유 변수
- 객체 생성 없이 클래스 이름만으로 참조 가능
- 객체를 만들어 참조할 수도 있지만 객체를 만들지 않고도 참조가 가능하기 때문에 이를 클래스 변수라고도 부름
public class Asean {
// 출석 20, 발표 30, 기말 50
public String name;
private int attendanceScore; // 출결점수
private int finalTermScore; // 기말점수
public static int presentationScore; // 29
public Asean(String name, int attendanceScore, int finalTermScore) {
this.name = name;
this.attendanceScore = attendanceScore;
this.finalTermScore = finalTermScore;
}
// static 블록 내부 코드는 프로그램 시작 시 즉시 자동으로 한 번 호출
static {
presentationScore = 29;
}
public void showStudentScore() {
System.out.println("학생명 : " + this.name);
System.out.println("출결점수 : " + this.attendanceScore);
System.out.println("발표점수 : " + presentationScore);
System.out.println("기말점수 : " + this.finalTermScore);
System.out.println("최종점수 : " + (this.attendanceScore + presentationScore + this.finalTermScore));
System.out.println("===========================================");
}
}
public class MainClass {
public static void main(String[] args) {
// 인스턴스생성 전부터 이미 조회 가능한 팀점수
System.out.println(Asean.presentationScore);
// 학생 4명 생성
Asean a1 = new Asean("가", 20, 43);
Asean a2 = new Asean("나", 15, 30);
Asean a3 = new Asean("다", 10, 35);
Asean a4 = new Asean("라", 18, 40);
a1.showStudentScore();
a2.showStudentScore();
a3.showStudentScore();
a4.showStudentScore();
// 어떤 인스턴스를 활용해도 팀 점수 조회 가능
System.out.println(a1.presentationScore);
System.out.println(a2.presentationScore);
System.out.println(a3.presentationScore);
System.out.println(a4.presentationScore);
}
}
위 그림과 같이 static 변수로 지정하면 main() 함수보다 앞서 실행되고, 해당 변수는 객체들이 전체적으로 공유하는 값으로 호출이 가능하다.
즉, 해당 변수는 힙 영역에 있는 것이 아니므로 this 키워드는 사용 불가하다.
위 코드에서 presentationScore가 public으로 선언되어 있으므로 어떤 인스턴스를 활용하더라도 호출이 가능하다.
2) 정적 메서드 (static method)
- 해당 클래스의 객체 생성 없이도 참조 가능
- static 메서드 안에서는 non-static 멤버를 객체 생성 없이 직접 참조 불가
- static 메서드 안에서는 static 변수를 선언할 수 없음
public class Asean {
// 출석 20, 발표 30, 기말 50
public String name;
private int attendanceScore; // 출결점수
private int finalTermScore; // 기말점수
private static int presentationScore; // 29
public Asean(String name, int attendanceScore, int finalTermScore) {
this.name = name;
this.attendanceScore = attendanceScore;
this.finalTermScore = finalTermScore;
}
// static 블록 내부 코드는 프로그램 시작 시 즉시 자동으로 한 번 호출
static {
presentationScore = 29;
}
// 스태틱 메서드도 객체 없이 바로 호출 가능
public static void showPresentationScore() {
System.out.println(presentationScore);
}
}
위 코드에서 presentationScore이 private으로 지정되어 있으므로 객체를 생성하지 않고서는 호출이 불가하다.
→ 스태틱 메서드를 활용하면 호출 가능
public class MainClass {
public static void main(String[] args) {
// 인스턴스생성 전부터 이미 조회 가능한 팀점수
// System.out.println(Asean.presentationScore); // private이므로 호출 불가
// 스태틱 메서드도 스태틱 변수처럼 호출 가능
Asean.showPresentationScore();
}
}
위와 같이 static 메서드를 활용하여 접근 가능하고 private 변수로 선언되어 있어 외부에서 변수의 값 자체를 변경할 수 없다는 장점이 있다.