Static 이란?

2022. 11. 27. 18:43자바멘토링

Static은 객체를 생성하지 않아도 메소드를 호출 할 수 있는 메소드이다.

 

Static 메소드는 클래스 변수만 사용할 수 있다는 단점이 있다.

에러 발생

Static이 아닌 변수 이름은 static context에서 참조 x

 

 

문제 해결 방법 :

 

1. static 메소드에 static 을 없애고 객체 생성후 호출하기 

2. 변수에  static 붙히기 

( 인스턴스 변수가 클래스 변수가 된다 , 그럴경우 모든 객체에서 하나의 값을 바라보기 때문에 문제가 발생할 수 있다.)

 

 

Static 블록

 

어떤 클래스의 객체가 생성 되면서 딱 한번만 불려야 하는 코드가 있다 .

" 한번만 호출 되어야 하는 코드" Static 블록 사용하여 구현 가능하다.

 

특징

1. 객체가 생성되기 전에 한번만 호출되고  그 이후에는 호출이 안된다 .

2. 클래스내에 선언이 되어있어야 한다. 메소드 내 에서는 선언 x

3. static블록은 여러개 선언 할 수 있다. 선언 되어 있는 순서가 중요하다.

 

 

static블록 

  package main;
  
  public class StaticBlock { 
	  static int data=1;
  
	  public StaticBlock() {
	  
	  System.out.println("StaticBlock Constructor."); }
	  
	  
	  static {
		  
		  System.out.println("*** First static block.***"); 
            data=3;
	  
	  }
  
	  static { 
		  
		  System.out.println("*** Second static block.***"); 
             data=5;
	  
	  }
  
	  public static int getData() {
	  
		  return data; 
	  } 
	  
  
  }

 

예제1

package main;

public class StaticBlockCheck {
	public static void main(String[]args) {
		StaticBlockCheck check= new StaticBlockCheck();
		 check.makeStaticBlockObject(); 
			/* check.makeStaticBlockObjectWithData(); */
		
	}

	
	  public void makeStaticBlockObject() {
	  
	  System.out.println("Creating block1"); 
	  StaticBlock block1 = new StaticBlock(); //객체생성
      System.out.println("Created block1");
	  System.out.println("---------------------");
	  System.out.println("Creating block2");
	  StaticBlock block2 = new StaticBlock(); //객체생성
	  System.out.println("Created block2");
	  
	  
	  
	  }

 

결과: 객체 처음 생성시  static 블록이 차례대로 실행  , 두번째 객체 생성시는 static 블록이 호출 되지 않음 

 

Creating block1
*** First static block.***
*** Second static block.***
StaticBlock Constructor.
Created block1
---------------------
Creating block2
StaticBlock Constructor.
Created block2
클래스를 초기화 할때 꼭 수행되어야 하는 작업이 있을때 유용하게 사용가능하다.

예제2

package main;

public class StaticBlockCheck {
	public static void main(String[]args) {
		StaticBlockCheck check= new StaticBlockCheck();
		/* check.makeStaticBlockObject(); */
			 check.makeStaticBlockObjectWithData(); 
		
	}



public void makeStaticBlockObjectWithData() {
		
		System.out.println("data=" +StaticBlock.getData());//Static 메소드 객체 생성 없이 호출 
		StaticBlock block1 =new StaticBlock();
		block1.data=1;
		System.out.println("--------------------");
		StaticBlock block2 = new StaticBlock();
		block2.data=2;
		System.out.println("data=" +StaticBlock.getData());
		
	}

 결과:

생성자가 불리지 않더라도, 클래스에 대한 참조가 발생하자마자 호출

Static 변수= Static으로 설정하면 같은 곳의 메모리 주소만을 바라보기 때문에 Static 변수의 값을 공유

*** First static block.***
*** Second static block.***
data=5
StaticBlock Constructor.
--------------------
StaticBlock Constructor.
data=2

 

 

Static 메소드 

 

Static메소드  인스턴스 메소드 
"클래스이름" 쓴다   ex) math.random();  객체 생성 x  인스턴스 생성후 "참조변수" 메소드 이름(); 으로 호출 
인스턴스 멤버(iv,im) 와 관련 없는 작업을 하는 메소드 인스턴스멤버(iv,im)와 관련된 작업을 하는 메소드 
메소드 내에서 인스턴스 변수 (iv)사용 불가  메소드 내에서 인스턴스 변수(iv) 사용가능 

 

 

매개변수 있고 없고 차이 !

package main;

public class MyMath2 {
	long a,b;//인스턴스 변수 (클래스 전체에서 사용 가능 하다)
	
	
	long add() {//인스턴스 메소드 
		
		return a+b;
		
		
	}
	static long add(long a, long b) {//클래스 메소드 (static 메소드)
		
		return a+b;//지역 변수 (선언된 위치부터 메소드 종료 될때 까지만 유효하다)
		
	}
	

}
package main;

public class MathTest2 {
	public static void main(String args[]) {
		System.out.println(MyMath2.add(200L, 100L));//클래스 메소드 호출(객체 생성 없이 호출가능하다)
		MyMath2 mm = new MyMath2();//인스턴스 생성(객체를 만들고 호출해야 한다)
		mm.a =200L;//인스턴스 변수 
	      mm.b=100L;
	    System.out.println(mm.add());//인스턴스 메소드 호출(mm=참조변수) 
	    
	    
	   
		
		
		
	}

}

 클래스 메소드는 객체를 안 만드니 참조변수가 없지만 인스턴스 변수는 객체생성하는 참조변수가 있다.

 

 

 

  • int iv -> 객체 생성후 사용 가능 
  • static int cv -> 언제나 사용 가능
  • 인스턴스 메소드 -> 객체 생성후 호출 가능
  • static메소드 객체 생성 없이 사용 가능 (항상가능 하다보니 , 객체가 있을지 없을지 모른다 )
public class TestClass {
	
	void instanceMethod() {}//인스턴스 메소드 
	static void staticMethod() {}// static메소드 
	
	void instanceMethod2()//인스턴스 메소드 
	{	instanceMethod();//다른 인스턴스 메소드 호출한다
		staticMethod();//static메소드를 호출한다.
		
		
	}
	
	static void staticMethod2()//static메소드
	{
		
		/* instanceMethod(); *///에러!! 인스턴스 메소드를 호출할 수없다
		staticMethod();//static메소드넌 호출 가능하다.
		
		
	}
}
package main;

public class TestClass2 {
	int iv;
	static int cv;
	
	
	void instanceMethod() {// 객체가 생성이 되었기에 호출이 가능 (iv가 있다는 말)
		System.out.println(iv);//인스턴스 변수를 사용할 수 있다.
		System.out.println(cv);// 클래스 변수를 사용할 수 있다.(언제나 사용가능)
		
	}
	static void staticMethod()// static메소드 (언제나 호출 가능)
	{	
		/* System.out.println(iv); *///에러! 인스턴스 변수를 사용 할 수 없다
        ( 객체 생성 없이 사용가능 한데 iv는 객체 생성을 해야 사용할 수 있기에 )
		System.out.println(cv);//클래스 변수는 사용 할 수 있다.
		//클래스 메소드는  언제나 사용가능 
	}
	
	

}
   
   Q.static 메소드? 객체 생성없이 호출 가능한 메소드 , 메소드를 만들었을때 static을 붙힐지 말지 어떻게 아는지?

    답:iv를 사용하지 않을때 static을 붙히면 된다 iv를 사용하면 static 사용 못한다.
      인스턴스 메소드는 iv를 가지고 사용하니 객체가 필요하지만 ,클래스 메소드는 iv가 필요없다 (객체가 필요없다)
    

'자바멘토링' 카테고리의 다른 글

파일디스크립터  (0) 2022.12.18
리플렉션  (0) 2022.12.15
Try - With - Resource  (0) 2022.12.04
추상클래스  (0) 2022.12.03
Weak Reference & Soft reference  (0) 2022.12.03