static 변수
공통으로 사용하는 변수가 필요한 경우
● 여러 인스턴스가 공유하는 기준 값이 필요한 경우
● 학생마다 새로운 학번 생성
● 카드회사에서 카드를 새로 발급할때마다 새로운 카드 번호를 부여
● 회사에 사원이 입사할때 마다 새로운 사번이 필요한
● 은행에서 대기표를 뽑을 경우(2대 이상)


static 변수 선언과 사용하기
● 선언 방법 - static int serialNum;
● 인스턴스가 생성될 때 만들어지는 변수가 아닌, 처음 프로그램이 메모리에 로딩될 때 메모리를 할당
● 클래스 변수, 정적변수라고도 함
● 인스턴스 생성과 상관 없이 사용 가능하므로 클래스 이름으로 직접 참조
● 사용방법 - Student.serialNum = 100;

static을 활용한 예제
클래스
package ch08;
public class NumberPrinter {
private int id;
private static int waitNumber = 1; // 선언과 동시에 초기화
public NumberPrinter(int id) {
this.id = id;
}
// 번호표를 출력 합니다.
public void printwaitNumber() {
System.out.println(id + " 기기의 대기 순번은 " + waitNumber);
waitNumber++;
}
}
객체
package ch08;
public class NumberPrinterMainTest {
public static void main(String[] args) {
NumberPrinter numberPrinter1 = new NumberPrinter(1);
NumberPrinter numberPrinter2 = new NumberPrinter(2);
numberPrinter1.printwaitNumber();
numberPrinter1.printwaitNumber();
numberPrinter1.printwaitNumber();
numberPrinter1.printwaitNumber();
numberPrinter2.printwaitNumber();
numberPrinter2.printwaitNumber();
numberPrinter2.printwaitNumber();
}
}
결과
waitNumber 앞에 static을 쓰니까 연결되어 번호가 나오고 있다
1 기기의 대기 순번은 1
1 기기의 대기 순번은 2
1 기기의 대기 순번은 3
1 기기의 대기 순번은 4
2 기기의 대기 순번은 5
2 기기의 대기 순번은 6
2 기기의 대기 순번은 7
static을 활용한 예제2
클래스
package ch08;
public class Student {
int studentNumber;
private static int Number = 1;
public Student(int studentNumber) {
this.studentNumber = studentNumber;
}
public void studentNumber() {
System.out.println(studentNumber + "의 번호는 " + Number);
Number++;
}
}
객체
package ch08;
public class StudentMainTest {
public static void main(String[] args) {
Student student1 = new Student(20163159);
Student student2 = new Student(20163171);
student1.studentNumber();
student1.studentNumber();
student1.studentNumber();
student2.studentNumber();
student2.studentNumber();
student2.studentNumber();
student2.studentNumber();
}
}
결과
20163159의 번호는 1
20163159의 번호는 2
20163159의 번호는 3
20163171의 번호는 4
20163171의 번호는 5
20163171의 번호는 6
20163171의 번호는 7
static3
클래스
public class Calculator {
// 멤버 변수
int sum = 0;
// 두 정수를 더하는 static 메서드 만들기
public static int add(int a, int b) {
// 멤버 변수를 활용할 수 없는 이유는 뭘까?
// sum = a + b;
return a + b;
}
// 두 정수를 빼는 메서드
public static int subtract(int a, int b) {
return a - b;
}
// 두 정수를 곱하는 메서드
public static int multiply(int a, int b) {
return a * b;
}
// 두 정수를 나누는 메서드
public static int divide(int a, int b) {
if(b == 0) {
System.out.println("Error : Division by zero is not allowed");
return 0;
}
return a / b;
}
// 잠시 자리를 빌려서 static 함수를 작성할 수 있다.
public static void main(String[] args) {
// 과제 Calculator를 인스턴스화 시키지 말고
// 동작들을 실행시켜서 확인해 보세요
// System.out.println(add(4, 2));
// System.out.println(subtract(4, 2));
// System.out.println(multiply(4, 2));
// System.out.println(divide(4, 2));
}
}
객체
public class CalculatorMainTest {
public static void main(String[] args) {
// Calculator에 더하느 기능을 호출해서 결과를 확인하세요
// 단 Calculator를 인스턴스화 시키지 마세요
// static 를 활용할 때 클래스이름.xxx 를 사용할 수 있다.
int result1 = Calculator.add(1, 10);
System.out.println(result1);
int result2 = Calculator.divide(10, 0);
System.out.println(result2);
// 인스턴스화
// Calculator a = new Calculator();
// System.out.println(a.add(4, 2));
// System.out.println(a.subtract(4, 2));
// System.out.println(a.multiply(4, 2));
// System.out.println(a.divide(4, 2));
}
}
결과
11
Error : Division by zero is not allowed
0
static3
alt + shift + s 생성자 자동생성
getter setter, using field
public class Employee {
//잠시 공간을 빌려서 코드를 작성한다
private static int serialNum = 1000;
private int employeeId;
private String employeeName;
private String department;
public Employee(String employeeName) {
this.employeeName = employeeName;
this.employeeId = serialNum;
serialNum++;
}
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
// serialNum 상태값을 반환하는 기능을 만들어 보자.
public static int getSerialNum() {
// 고민 ! - 객체 메모리에 올라간 상태
// serialNum++;
// static 메서드 안에서는 멤버변수를 사용할 수 없다
// department = "개발부서";
return serialNum;
}
// 1. 멤버 변수
// 2. 지역 변수
// 3. static 변수
// 결론 : 어느 메모리 위치에 있느냐에 따라 이름을 구분지어
// 말할 수 있다
}
public class EmployeeMainTest {
public static void main(String[] args) {
// static은 먼저 메모리에 올라가는 녀석이다.
// 클래스 이름으로 접근할 수 있다.
// int number = Employee.serialNum;
// System.out.println(number);
// 만약 객체가 생성되기 전에 serialNum 값을 알고 싶다면
System.out.println(Employee.getSerialNum());
Employee employeeKim = new Employee("김길동");
Employee employeeLee = new Employee("이순신");
Employee employee티모 = new Employee("티모");
System.out.println(employeeKim.getEmployeeId());
System.out.println(employeeLee.getEmployeeId());
System.out.println(employee티모.getEmployeeId());
// serialNum이 public이면 외부에서 static 변수에 접근해서 값을 변경할 수 있는 상태이다.
// Employee.serialNum = 100;
}
}
결과
1000
1000
1001
1002
싱글톤 패턴이란?
● 프로그램에서 인스턴스가 단 한 개만 생성되어야 하는 경우 사용하는 디자인 패턴
● static 변수, 메서드를 활용하여 구현 할 수 있음
싱글톤 패턴으로 회사 객체 구현하기
1. 생성자는 private으로 선언
2. 클래스 내부에 유일한 private 인스턴스(객체) 생성
3. 외부에서 유일한 인스턴스를 참조할 수 있는 public 메서드 제공
싱글톤 예제
객체
public class Company {
// 싱글톤 패턴으로 설계 하는 방법
// heap 메모리에 오직 객체가 하나만 존재해야 될 경우 사용 가능 하다.
// 1. 생성자는 private로 선언해야 한다.
private Company() {}
// 2. 클래스 내부에 유일한 private 인스턴스 객체를 생성
private static Company instance = new Company(); // 선언과 동시에 초기화
// 3. 외부에서 유일한 instance 변수에 접근할 수 있는 메서드를 제공해야 한다.
public static Company getinstance() {
if (instance == null) {
instance = new Company();
}
return instance;
}
}
클래스
public class CompanyMainTest {
public static void main(String[] args) {
// 1.
// 생성자를 private로 선언했기 때문에
// 기본 생성자로 호출할 수 없다
// Company company = new Company();
// 2.
// Company.instance 접근 제어 지시자가 private다
// 3
// 외부에서 유일하게 Company 객체 주소값에 접근할 수있는 메서드
Company naver = Company.getinstance();
Company tenco = Company.getinstance();
System.out.println(naver);
System.out.println(tenco);
Company mata = Company.getinstance();
System.out.println(mata);
}
}
결과
ch08.Company@7c30a502
ch08.Company@7c30a502
ch08.Company@7c30a502
주의사항
※ static 변수는 인스턴스 변수가 아니므로 클래스 이름으로 직접 참조
▶ System.out.println(Employee.serialNum);