static 변수
= 클래스 변수, 정적 변수
여러 인스턴스가 하나의 값을 공유하기 위해 만들어졌다. c/c++의 전역변수와 동일하다.
static 변수는 처음 프로그램이 로드될 때 데이터 영역에 한번만 생성된다.
인스턴스의 생성과 상관없이 사용할 수 있으므로 인스턴스 이름이 아니라 클래스이름으로 참조한다.
Student.serialNum = 100;
static변수와 인스턴스 변수
스택 메모리에 위치한 참조 변수들은 static 변수 참조 시 데이터 영역의 동일한 메모리를 참조한다.
static 메서드
=클래스 메서드, 정적 메서드
static 변수를 위한 기능을 제공하는 메걷이다.
static 메서드에서는 인스턴스 변수를 사용할 수 없다. (일반 메서드에서 static 변수 사용은 당연히 가능하다.)
static 변수와 동일하게 클래스 이름을 참조하여 사용하는 메서드이다.
Student.getSerialNum();
변수 유형 정리
Singleton Pattern
단 하나의 인스턴스를 생성하여 그 인스턴스를 계속 사용하는 것.
어플리케이션이 시작될 때 어떤 클래스가 최초 한번만 메모리를 할당하여,
생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 생성 이후에 호출된 생성자는 최소의 생성한 객체를 반환한다.
사용이유
고정된 메모리 영역을 사용하기 때문에 메모리 낭비를 방지할 수 있다.
싱글톤으로 만들어진 클래스 인스턴스는 전역 인스턴스이기 때문에 다른 클래스 인스턴스들이 데이터를 공유하기 쉽다.
자바에서 사용하는 법:
최초 한번만 메모리를 할당하기 위해 static으로 선언하고
생성자를 private으로 선언하여 재생성이 불가능하게 만든 후 getInstance()로 받아쓸 수 있다.
public class Company {
private static Company instance = new Company();
private Company() {}
//외부에서 호출 시 동일한 메서드 호출을 위해 static 사용
public static Company getInsance() {
if(instance == null) {
instance = new Company();
}
return instance;
}
}
import java.util.Calendar;
public class CompanyTest {
public static void main(String[] args) {
Company com1 = Company.getInsance();
Company com2 = Company.getInsance();
System.out.println(com1);
System.out.println(com2);
Calendar calendar = Calendar.getInstance();
//자바 util 사용
//new Calendar 불가능, 유일한 객체를 가져오기 때문
}
}
출력하면 동일한 주소값이 확인된다.
static 변수 응용
static을 사용해서 DB의 auto increment 기능을 구현해보자.
package staticex;
public class Student {
private static int serialNum = 1000;
public static int getSerialNum() {
return serialNum;
}
public static void setSerialNum(int serialNum) {
Student.serialNum = serialNum;
}
}
serialNum을 private static으로 선언해서 전역변수 역할을 하게끔 만들었다.
해당 변수는 private이기 때문에 get/set 없이는 접근이 불가능하다.
그리고 static이기 때문에 인스턴스가 아닌 클래스 자체로 접근한다.
Student 객체가 생성될 때마다 자동으로 serialNum이 증가하게 만들어보자.
package staticex;
public class Student {
private static int serialNum = 1000;
private int studentId;
public String name;
public Student(String name) {
this.name = name;
serialNum++;
studentId = serialNum;
}
public int getStudentId() {
return this.studentId;
}
public static int getSerialNum() {
return serialNum;
}
public static void setSerialNum(int serialNum) {
Student.serialNum = serialNum;
}
}
package staticex;
public class StudentIDTest {
public static void main(String[] args) {
System.out.println(Student.getSerialNum());
//System.out.println(lee.serialNum); 참조 변수가 아닌 클래스로 access
Student lee = new Student("lee");
Student kim = new Student("kim");
System.out.println(lee.getStudentId());
System.out.println(kim.getStudentId());
}
}
출력값을 확인해보면 기존 serialNum 1000에서 인스턴스가 생성될때마다 1씩 증가한 것을 확인할 수 있다.
Singleton 패턴 응용
유일한 카드 회사 객체를 선언하고 이 회사에서 카드를 발급하면 항상 고유번호가 자동으로 생성된다.
10001부터 시작하여 카드가 생성될 때마다 10002, 10003이 되도록 만들자.
먼저 카드 회사를 싱글톤으로 선언한다.
싱글톤으로 만들기 위해 private static으로 선언한다.
package staticex.quiz;
public class CardCompany {
private static CardCompany instance = new CardCompany();
public static CardCompany getInstance() {
if(instance == null) {
instance = new CardCompany();
}
return instance;
}
public Card createCard() {
return new Card();
}
}
이 회사에서 createCard()를 할 때마다 고유 번호가 발급되어야 한다.
autoIncrement를 전역변수로 두고 Card 생성자에서 cardNum이 AI를 받도록 만든다.
package staticex.quiz;
public class Card {
private static int autoIncrement = 10001;
private int cardNumber;
public Card() {
this.cardNumber = Card.autoIncrement;
Card.autoIncrement++;
}
public int getCardNumber() {
return this.cardNumber;
}
}
메인에서 확인가능하다.
package staticex.quiz;
public class CardCompanyTest {
public static void main(String[] args) {
CardCompany com = CardCompany.getInstance();
Card myCard = com.createCard();
Card yourCard = com.createCard();
System.out.println(myCard.getCardNumber());
System.out.println(yourCard.getCardNumber());
}
}
'프로그래밍 언어 > java' 카테고리의 다른 글
[java] 업캐스팅, 타운캐스팅 (0) | 2021.03.10 |
---|---|
[java] 상속, 생성과정 (0) | 2021.03.09 |
[java] this와 참조자료형 (0) | 2021.02.24 |
[java] 접근 제어자, 정보 은닉 (0) | 2021.02.24 |
[java] 클래스 생성자 (0) | 2021.02.24 |
댓글