ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • static
    Java 2023. 2. 13. 13:20
    학습 목표

    static 변수
    static 함수
    인스턴스들 끼리 공유 해야 하는 값이 필요하다면 static 을 사용하면 된다.
    static 활용

     

     

    static이란?

    static이라는 의미는 '정적인, 움직이지 않는다'라는 뜻이다.

    메모리에서 고정되기 때문에 붙은 이름이지만 , 실제 소스에서 static을 사용한다는 의미는

    모든 객체가 '공유' 한다는 의미이다.

     

    언제 사용하는가?

    예를 들어서 은행 번호표를 뽑는다고 가정해보자.

    기계가 2대가 있는데 기계마다 데이터를 공유하지 않고 번호표를 뽑으면 따로 번호표가 찍혀 나온다.

    기계가 2대이더라도 데이터를 공유함으로서 번호가 따로 나오지 않고 순차적으로 나오게 된다.

     

    static 변수

     

    은행 번호표를 예시로 소스코드를 보면서 이해하자

     

    package ch08;
    
    public class NumberPrinter {
    	
    	private int id;
    	//private int waitNumber;
    	//private static int waitNumber;
    	public  int waitNumber;
    	// 생성자는 맨 먼저 실행되고 한번만 수행이 된다.
    	public NumberPrinter(int id) {
    		this.id = id;
    		this.waitNumber = 1;
    	}
    	
    	//번호표를 출력합니다
    	public void printwaitNumber() {
    			System.out.println(" 대기순번 " + waitNumber);
    			waitNumber++;
    	}
    }
    package ch08;
    
    public class MainTest1 {
    	
    	// 메인함수 - 코드의 시작점!
    	public static void main(String[] args) {
    	
    		NumberPrinter numberPrinter1 = new NumberPrinter(1);
    		NumberPrinter numberPrinter2 = new NumberPrinter(2);
    		
    		numberPrinter1.printwaitNumber(); //누군가가
    		numberPrinter1.printwaitNumber();//다른 누군가가
    		numberPrinter1.printwaitNumber();//또 다른 누군가가
    		
    		System.out.println("===============================");
    		
    		numberPrinter2.printwaitNumber(); //누군가가
    		numberPrinter2.printwaitNumber();//다른 누군가가
    		numberPrinter2.printwaitNumber();//또 다른 누군가가
    	
    	}//end of main
    
    }//end of class
    출력값

    대기순번 1
    대기순번 2
    대기순번 3
    ===============================
    대기순번 1
    대기순번 2
    대기순번 3
    위의 예시를 통해 번호표를 뽑는 소스코드를 작성해보았다. 하지만 데이터를 공유하지 않아 객체마다 번호표가 다르게 출력되는것을 볼수있다. 

     

    여기에서 int 변수 데이터 타입을 가진 waitnumber 변수 앞에 static 을 선언해보자.

     

    public static int waitNumber;
    출력값

    대기순번 1
    대기순번 2
    대기순번 3
    ===============================
    대기순번 4
    대기순번 5
    대기순번 6
    데이터를 공유함으로서 순번이 따로 뜨지 않고 이어서 출력되는것을 확인할수 있다.

     

    static 함수

     

    static 메서드 안에서는 멤버변수를 활용할수 없다.

     

    소스코드를 보면서 이해하자

     

    package ch08;
    
    public class NumberPrinter2 {
    	
    	private  int id;
    	
    	public static int waitNumber;
    
    	// 생성자는 맨 먼저 실행되고 한번만 수행이 된다.
    	public NumberPrinter2(int id) {
    		this.id = id;
    		//this.waitNumber = 1;
    	}
    	
    	//번호표를 출력합니다
    	public void printwaitNumber() {
    			System.out.println(" 대기순번 " + waitNumber);
    			waitNumber++;
    	}
    	//static 붙으면 더이상 메서드가 아닌 static함수라고 생각하자
    	//static 안에서는 멤버변수를 활용할 수 없다.
    	//객체가 메모리에 올라 갔다는 보장을 하지 못하기 때문이다.
    	public static int getWaitNumber() {
    		// id = 100;
    		return waitNumber;
    	}
    	
    
    }

     

    여기에서 static 메서드안에 id 라는 변수를 넣을려고 하니 에러가 뜨는것을 확인할 수 있다.

     

     

    즉 static 메서드안에서 멤버변수를 활용할려면 그 변수도 static 멤버변수이어야 하며 static 변수가 아닌 멤버변수는 활용할수 없다.

     

    그러면 static 변수와 멤버 변수를 어떻게 활용할까?

     

    static 변수를 사용할 때, 각각 객체가 가지는 상태 값을 저장해야 한다면 멤버 변수를 활용해서 사용해야 한다.

    소스코드를 보면서 이해하자.

     

    package ch08;
    
    /**
     * 
     * @author static 변수와 멤버 변수에 활용 !!
     *
     */
    public class Employee {
    	
    	public static int serialNum;
    	private int employeeId;
    	private String name;
    	private String department;
    	
    	//생성자를 호출 한다든 것은 ?
    	public Employee() {
    		serialNum++;
    		employeeId = serialNum;
    	}
    	
    	// get, set 만들기
    
    	public int getEmploteeId() {
    		return employeeId;
    	}
    
    	public void setEmploteeId(int emploteeId) {
    		this.employeeId = emploteeId;
    	}
    
    	public static int getSerialNum() {
    		return serialNum;
    	}
    
    	public static void setSerialNum(int serialNum) {
    		Employee.serialNum = serialNum;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public String getDepartment() {
    		return department;
    	}
    
    	public void setDepartment(String department) {
    		this.department = department;
    	}
    	
    	
    
    	
    }
    package ch08;
    
    public class EmployeeMainTest {
    
    	public static void main(String[] args) {
    	
    		Employee employee1 = new Employee();
    		employee1.setName("이순신");
    		System.out.println(employee1.serialNum);
    		
    		Employee employee2 = new Employee();
    		employee1.setName("홍길동");
    		
    		Employee employee3 = new Employee();
    		employee1.setName("티모");
    		
    		// static 변수만 사용을 하면
    		// 각 각에 객체가 가지는 상태값을 저장해야 한다면
    		// 멤버 변수를 활용해서 사용해야 한다.
    		System.out.println(Employee.serialNum);
    		
    		//이순신 사원번호 확인 가능
    		System.out.println(employee1.getEmploteeId());
    		//홍길동 사원번호 확인 가능
    		System.out.println(employee2.getEmploteeId());
    		//티모에 사원번호 확인 가능
    		System.out.println(employee3.getEmploteeId());
    		
    		
    	}
    
    }
    위의 소스코드를 보면 이순신,홍길동,티모 각각의 객체가 가지는 상태값을 저장하기 위해서 멤버변수를 활용해서 코드를 작성하여 각각의 객체가 가지는 상태값(사원번호)를 출력한것을 볼수있다.

     

     

    싱글톤 패턴이란?

    객체의 인스턴스가 오직 1개만 생성되는 패턴

     

    이번에도 소스코드를 보면서 이해하자

     

    package ch08;
    
    //디자인 패턴
    //싱글톤 패턴 --> 객체 생성하는 코드에 사례
    public class Company {
    
    	//1.생성자를 private 선언한다.
    	private Company() {
    	}
    	//2.	private + static 자기자신에 데이터 타입을 선언 해 준다.
    	private static Company company;
    	
    	//3.외부에서 접근 가능한 static 메서드를 만들어 둔다.
    	public static Company getInstance() {
    		//코드 구현하기
    		if (company == null) {
    			company = new Company();
    		}
    		return company;
    	}
    	
    	
    }
    package ch08;
    
    public class CompanyMainTest {
    
    	public static void main(String[] args) {
    		
    		//alt+shift+ s -> get set 단축키
    		//Company company = new Company(); 사용 불가
    		Company company = Company.getInstance();
    		System.out.println(company);
    		Company company2 = Company.getInstance();
    		Company company3 = Company.getInstance();
    		System.out.println(company2);
    		System.out.println(company3);
    		
    		
    	}// end of main
    
    }//end of class
    출력값

    ch08.Company@7c30a502
    ch08.Company@7c30a502
    ch08.Company@7c30a502
    위의 소스코드를 보면 Company company = new company(); 라고 선언할때 오류가 뜨는것을 확인할수 있다.
    즉, 다른 class에  객체의 인스턴스가 1개만 생성이 된다.
    다른 class에 접근 가능한 getInstance 메서드를 만들어주고 객체를 여러개 생성하여 출력값을 보면 동일한 주소값을 가리키고 있는것을 볼수있다. 

    그렇다면 장점은 무엇일까?
    인스턴스가 1개만 존재하기 때문에 고정된 메모리 영역을 얻으면서 메모리 낭비를 방지할수 있게된다.
    객체를 여러개 생성할때 설정 값이 변경될 위험을 없앨 수 있다.

    'Java' 카테고리의 다른 글

    상속  (1) 2023.02.18
    배열  (2) 2023.02.18
    this  (0) 2023.02.13
    접근 제어 지시자  (0) 2023.02.13
    객체와 객체간에 상호작용  (0) 2023.02.12
Designed by Tistory.