본 포스트는 카카오 테크 캠퍼스 1기에서 제공하는 패스트캠퍼스 강의에서 배운 내용을 토대로 정리하였습니다.
public class Person {
String name;
int age;
public Person() {
//여기에 어떠한 로직이 들어가면 안된다는 의미
// => 인스턴스가 아직 완성되지 않았기 떄문
this("이름없음", 1);
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
인스턴스 변수처럼 객체가 new(인스턴스화) 될때 생성되는 변수가 아닌,
프로세스가 메모리에 로드되는 순간 데이터 영역에 생성되는 변수이고,
이는 프로세스가 끝날때까지 메모리에 상주하게 되는 변수이다.
따라서 인스턴스의 생성과 상관 없이 사용할 수 있는 변수이며, 여러번 생성되는 변수가 아닌 한번만 생성되는 변수이다.
클래스 변수, 정적변수라고도 한다.
인스턴스 생성과 상관 없이 사용 가능하므로 클래스 이름으로 직접 참조
static 사용 고려 상황 예시
여러 인스턴스가 공유하는 기준 값이 필요한 경우
학생마다 새로운 학번 생성
카드회사에서 카드를 새로 발급할때마다 새로운 카드 번호를 부여
회사에 사원이 입사할때 마다 새로운 사번이 필요한 경우
Employee.java
public class Employee {
public static int serialNum = 1000;
//static 변수 선언
private int employeeId;
private String employeeName;
private String department;
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;
}
}
EmployeeTest.java
public class EmployeeTest {
public static void main(String[] args) {
Employee employeeLee = new Employee();
employeeLee.setEmployeeName("이순신");
System.out.println(employeeLee.serialNum);
Employee employeeKim = new Employee();
employeeKim.setEmployeeName("김유신");
employeeKim.serialNum++;
System.out.println(employeeLee.serialNum);
System.out.println(employeeKim.serialNum);
}
}
출력 결과
두 인스턴스 employeeLee 와 employeeKim 이 serialNum 변수를 공유함을 알 수 있다.
여기서는 공유함을 보여주기 위해 인스턴스로부터 참조해서 접근했지만 그냥
Employee.serialNum 으로 클래스로부터 바로 접근 가능하다.
변수와 마찬가지로 메서드의 반환 값 앞에 static키워드가 붙은 메서드가 static 메서드 이다.
주로 static 변수에 대한 기능을 제공하는데 사용하지만, 인스턴스가 생성되지 않더라도 호출이 필요한 메서드는 static으로 선언한다.
역시 인스턴스 생성과 무관하게 클래스 이름으로 호출하여 사용할수 있으므로 클래스 메서드라고도 한다.
serialNum 변수를 private으로 선언하고 getter/setter 구현
private static int serialNum = 1000;
...
public static int getSerialNum() {
return serialNum;
}
public static void setSerialNum(int serialNum) {
Employee.serialNum = serialNum;
}
클래스 이름으로 호출 가능 ( 클래스 메서드, 정적 메서드 )
System.out.println(Employee.getSerialNum());
static 메서드(클래스 메서드)에서는 인스턴스 변수를 사용할 수 없다.
static 메서드는 인스턴스 생성과 무관하게 클래스 이름으로 호출 될 수 있음
인스턴스 생성 전에 호출 될 수 있으므로 static 메서드 내부에서는 인스턴스 변수를 사용할 수 없음
당연하지만 static 메서드 안에서 지역변수가 사용되는건 가능하다. 어차피 지역변수는 스택에 쌓이고 함수호출끝나면 사라지기 때문.
인스턴스 메서드 에서는 static변수 사용 가능하다
어차피 인스턴스 메서드는 반드시 인스턴스가 생성되고 쓰이는 메서드이고, static 변수는 인스터스 만들어지기도 전에 data영역에 할당돼있기 때문
즉, 메모리적으로 이슈가 없기때문에 사용가능하다.
정리
private Company() {}
private static Company instance = new Company();
public static Company getInstance() {
if( instance == null) {
instance = new Company();
}
return instance;
}
CompanyTest.java
public class CompanyTest {
public static void main(String[] args) {
Company company1 = Company.getInstance();
Company company2 = Company.getInstance();
System.out.println(company1);
System.out.println(company2);
}
}
두 출력 모두 같은 주소값을 출력한다.