Back-end/JAVA,Spring

Java static 이란? 개념/사용법

cheersHena 2018. 11. 19. 23:40
반응형

Java static 이란?

 - 변수나 메소드의 특성을 바꾸는 키워드

 

Static 특징 

- 메모리에 한 번만 할당 된다.

- 즉, Static 변수나 메소드는 전역적으로 공유되는 특성을 가짐. 

 

1) Static Class 변수 

   - 해당 클래스의 모든 객체들이 값을 공유 

2) Static Class 메소드 

  - 객체를 생성하지 않아도 호출 가능 

 

source code) 

class Test{
	//static 변수 
	static String name = "None";
    String age;
    
    Test(String name, String type){ // 생성자 
        this.name = name;
        this.age= age;
    }
    
    public void printTest(){
    	System.out.println("=====static=====");
    	System.out.println("name:::" + name);
        System.out.println("age:::" + age);
    }
    
    //static 메소드
    public static void getName(){
    	/*static메소드 내에서 사용하는 변수도 static 변수여야 한다. 
        static 선언시 객체가 생성되기 전부터 메모리에 올라가기 때문에
        당연히 사용하려는 변수도 메모리에 올라가 있어야 하기 때문 */ 
    	System.out.println("Test name:" + name);
    }

	public calss Main{
    	//static 메소드 선언을 해줬기 때문에 Main메소드에서 객체 생성없이 바로 클래스에서 호출(Test.get )가능 
    	Test.getName(); //결과 == Test name: None 
        
        Test test_1 = new Test("hena","25");
        Test test_2 = new Test("bin","30");
        Test test_3 = new Test("nemo","29");
        
        test_1.printTest();
        test_2.printTest();
        test_3.printTest();
       
       /* 결과는????
            =====static=====
	name::: nemo
            age::: 25
            =====static=====
            name::: nemo
            age::: 30
            =====static=====
            name::: nemo
            age::: 29
        */

    }
}

마지막 결과와 같이 age는 일반변수이지만, name은 static변수이기 때문에 각 객체를 새로 생성하지 않고 하나의 static변수로 공유 된다. 때문에 마지막으로 test_3에서 넣어준 nemo 값으로 모두 공유된다. 

 

사용법

1.클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통적으로 사용해야하는 것에 static을 붙인다.

 - 인스턴스를 생성하면, 각 인스턴스들은 서로 독립적이기 때문에 서로 다른 값을 유지한다.

    경우에 따라서는 각 인스턴스들이 공통적으로 같은 값이 유지되어야 하는 경우 static을 붙인다.

 

 2. static이 붙은 멤버변수는 인스턴스를 생성하지 않아도 사용할 수 있다.

 - static이 붙은 멤버변수(클래스변수)는 클래스가 메모리에 올라갈때 이미 자동적으로 생성되기 때문이다.

 

3. static이 붙은 메서드(함수)에서는 인스턴스 변수를 사용할 수 없다.

 - static이 붙은 메서드는 인스턴스 생성 없이 호출가능한 반면, 인스턴스 변수는 인스턴스를 생성해야만 존재하기 때문에... static이 붙은 메서드(클래스메서드)를 호출할 때 인스턴스가 생성되어있을수도 그렇지 않을 수도 있어서 static이 붙은 메서드에서 인스턴스변수의 사용을 허용하지 않는다.

    (반대로, 인스턴스변수나 인스턴스메서드에서는 static이 붙은 멤버들을 사용하는 것이 언제나 가능하다. 인스턴스변수가 존재한다는 것은 static이 붙은 변수가 이미 메모리에 존재한다는 것을 의미하기 때문이다.)

 

4. 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.

 - 메서드의 작업내용중에서 인스턴스 변수를 필요로 한다면, static을 붙일 수 없다. 반대로 인스턴스변수를 필요로 하지 않는다면, 가능하면 static을 붙이는 것이 좋다. 메서드 호출시간이 짧아지기 때문에 효율이 높아진다.

    (static을 안붙인 메서드는 실행시 호출되어야할 메서드를 찾는 과정이 추가적으로 필요하기 때문에 시간이 더 걸린다.)

 

5. 클래스 설계시 static의 사용지침

 - 먼저 클래스의 멤버변수중 모든 인스턴스에 공통된 값을 유지해야하는 것이 있는지 살펴보고 있으면, static을 붙여준다.

 - 작성한 메서드 중에서 인스턴스 변수를 사용하지 않는 메서드에 대해서 static을 붙일 것을 고려한다.

일반적으로 인스턴스변수와 관련된 작업을 하는 메서드는 인스턴스메서드(static이 안붙은 메서드)이고 static변수(클래스변수)와 관련된 작업을 하는 메서드는 클래스메서드(static이 붙은 메서드)라고 보면 된다.

 

 

 

 

 

클래스변수(static 변수)와 인스턴스변수의 차이를 이해하기 위한 예로 카드 게임에 사용되는 카드를 클래스로 정의해보자. 

 

 

카드 클래스를 작성하기 위해서는 먼저 카드를 분석해서 속성과 기능을 알아 내야한다. 속성으로는 카드의 무늬, 숫자, 폭, 높이 정도를 생각할 수 있을 것이다. 이 중에서 어떤 속성을 클래스 변수로 선언할 것이며, 또 어떤 속성들을 인스턴스 변수로 선언할 것인지 생각해보자. 

 

 class Card { 
        String kind ; // 카드의 무늬 - 인스턴스 변수 
        int number; // 카드의 숫자 - 인스턴스 변수 
        static int width = 100 ; // 카드의 폭 - 클래스 변수 (static 변수) 
        static int height = 250 ; // 카드의 높이 - 클래스 변수 (static 변수)
  }

 

각 Card인스턴스는 자신만의 무늬(kind)와 숫자(number)를 유지하고 있어야 하므로 이들을 인스턴스변수로 선언하였고, 각 카드들의 폭(width)과 높이(height)는 모든 인스턴스가 공통적으로 같은 값을 유지해야하므로 클래스변수로 선언하였다. 


만일 카드의 폭을 변경해야할 필요가 있을 때는 모든 카드의 width값을 변경하지 않고, 한 카드의 width값만 변경해도 모든 카드의 width값이 변경되는 셈이다. 

 

 

 

 

 

반응형