두근두근, 웹개발자로 처음 출근을 했다. 하단 첨부된 사진을 참고하여 게시판을 위한 데이터 구조를 짜라는 업무를 받았다고 가정하자.
여기서 고정된 값은 무엇일까? 질문을 바꾸겠다. 틀이 되는 값은 무엇일까? 글번호, 제목, 날짜가 될 것이다. 틀이되는 값은 클래스로 생성해줘야지. 그리고 객체로 게시글을 만들거야. 우리는 똑똑한 웹개발자니까! 하며 신나게 클래스를 뚝딱뚝딱 만들었다.
/** 하나의 게시물을 표현하기 위한 클래스 */
public class Article {
private int num; // 글 번호
private String title; // 제목
private String regDate; // 날짜
}
자바빈즈의 구조를 위하여 getter, setter 메서드를 추가한 후 자료구조 구성이 완성되었다고 이제 잘했단 소리를 듣겠지?! 하는 희망에 부풀어 있던 찰나, 오더가 내려온다. 전체 게시물 수랑 모든 게시물이 공유하는 카테고리 정보가 있었으면 하는데, 할 수 있겠어? 음, 이것도 클래스에다가 정의하면 되겠지? 싶어서 멤버변수에 추가를 했다. 프라이빗으로 예쁘게 은닉까지 해서.
근데 사실 '전체 게시물 수'란 데이터는 하나만 있어도 족하다. 굳이 객체로 생성된 모든 게시물이 그 데이터를 갖게될 필요가 있을까? 정답은 No다. 게시글이 100개라고 가정했을때, int값으로 한번만 쓰면 될걸 굳이 멤버변수로 지정해서 396바이트나 낭비하는 대참사를 낳게 된다.
메모리는 돈이다. 기업의 존재의 의의는 이윤추구다. 비용이 많이 들면 순수익은 줄어든다. 아, 뭔가 방법이 필요하다. 메모리를 낭비하지 않게 하면서도 포함하게 하는 방법이. 그래서 나타난게 static이다.
/** 하나의 게시물을 표현하기 위한 클래스 */
public class Article {
private static int count; // 전체 글 수
private static String category; // 카테고리
private int num; // 글 번호
private String title; // 제목
private String regDate; // 날짜
}
(고정 영역) - 프로그램이 실행되면 실행파일이 메모리에 로드되면서, 실행파일의 용량만큼 RAM을 사용한다. 실행파일의 크기는 변할 수 없으므로(다운로드 해둔 파일이 갑자기 커지거나 그러진 않듯) 이 영역의 크기는 고정 크기를 갖는다. (식당의 주방. 손님이 있건 없건 주방에 사람은 늘 있다.)
(동적 영역) - 프로그래머가 new 키워드를 사용해서 객체나 배열을 생성하면 사용된다. (힙영역) 또 다른 경우는 메서드가 호출되는 동안 사용될 파라미터와 지역변수가 생성된다. (스택영역), 메서드가 종료되거나 객체가 더이상 사용되지 않으면 생성된 변수나 객체는 메모리에서 사라지므로, 이 영역은 유동적인 크기를 갖게 된다. (식당의 홀. 손님은 유동적이고 왔다갔다하며 움직인다.)
메모리 영역의 차이 떄문에 static 메서드는 동적 메모리 영역의 멤버변수를 사용하거나, static이 아닌 일반 멤버함수를 호출할 수 없다. (고정영역에서 동적영역을 쓰려는 것, 즉 주방 직원이 김철수라는 손님을 컨트롤 하려는건데 김철수 손님이 올지 안올지는 직원 입장에서 어떻게 할 수 있는게 아니다.)
/**
* 하나의 게시물을 표현하기 위한 JavaBeans
* 각각의 게시물들이 독립적으로 표현하고 있는 데이터들을 멤버변수 형태로 선언한다.
*/
public class Article {
/** static은 모든 객체가 공유하는 값이다. static값은 클래스 이름을 통해서
* 접근해야 하며, 객체의 생성 여부에 상관없이 사용이 가능하다.*/
// 전체 게시물의 수를 표현하기 위한 데이터
private static int count = 0;
// 모든 게시물은 하나의 카테고리 안에 존재한다고 가정한다.
// 게시물의 분류를 구별하기 위한 데이터
private static String category;
// 글 번호
private int num;
// 글 제목
private String title;
// 작성일시
private String regDate;
public Article(int num, String title, String regDate) {
super();
this.num = num;
this.title = title;
this.regDate = regDate;
/* 이 클래스에 대한 객체 생성 --> 게시물 신규 등록
* 게시물이 새로 등록될 때 마다, 전체 글 수를 의미하는
* count 변수가 1씩 증가한다.
* 전체 게시물 수는 모든 객체가 공유하는 값이므로,
* static으로 생성되어야 한다.
*/
count++; // 꿀팁, 글이 새로 생길때마다 글번호 추가됨. 메서드 추가 생성 필요 x
}
public static int getCount() {
return count;
}
public static void setCount(int count) {
Article.count = count;
}
public static String getCategory() {
return category;
}
public static void setCategory(String category) {
Article.category = category;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getRegDate() {
return regDate;
}
public void setRegDate(String regDate) {
this.regDate = regDate;
}
@Override
public String toString() {
return "글 분류=" + category + ", 전체 글 수=" + count +
"Article [num=" + num + ", title=" + title + ", regDate=" + regDate + "]";
}
}
public class Main01 {
public static void main(String[] args) {
Article.setCategory("자유게시판");
Article a1 = new Article(1, "첫 번째 글 제목", "2014-01-01");
Article a2 = new Article(2, "두 번째 글 제목", "2015-02-01");
Article a3 = new Article(3, "세 번째 글 제목", "2016-03-01");
// 출력결과에서 모든 객체가 동일한 count값을 갖는다.
System.out.println(a1.toString());
System.out.println(a2.toString());
System.out.println(a3.toString());
System.out.println("----------------");
// static 변수의 값을 변경하면, 모든 객체가 영향을 받는다.
Article.setCategory("공지사항");
System.out.println(a1.toString());
System.out.println(a2.toString());
System.out.println(a3.toString());
}
}
이 포스트는 itpaper.co.kr에서 제공되는 강의자료를 바탕으로 작성되었습니다.