JAVA/정리한 것

[ JAVA ] 정적( Static )

따갓 2022. 5. 16. 23:33

정적(Static)

>> 정적 필드와 정적 메소드 객체(인스턴스)에 소속된 멤버가 아니라 클래스에 고정된 멤버이다. 그러므로 클래스를 로딩해서 메소드 메모리 영역에 적재할때 클래스별로 관리된다. 따라서 클래스의 로딩이 끝나는 즉시 바로 사용할 수 있다.

class Temp{
	static int add( int i , int j ){ return 100; }
}
public class Main{
	public static void main( String[] args ){
		int r = Temp.add(10 , 20 );
		System.out.println( r );
	}
}
  • static이 붙은 멤버함수는? '인스턴스 없이' 클래스명, 함수명으로 호출이 가능하다. (참조형 변수도 불필요)
  • 클래스 안에서 선언하면서 멤버함수,변수와 구별되도록 static 이라는 키워드를 사용한다 

 

class Temp {	
	static {	// static initializer
		System.out.println("static");
	}
	
	Temp() {
		System.out.println("생성");
	}
}
public class Main {
	public static void main( String[] args ) {
		new Temp();
		new Temp();
		new Temp();		
	}
}
/* 실행결과
static
생성
생성
생성
*/

 

  • (static{}) 영역 : static initializer 라고 한다.  이 영역은 인스턴스 생성 이전에 딱 한번 호출된다. '클래스가 메모리에 로딩되는 시점에 JVM에 의해 호출된다.' 
  • 인스턴스를 아무리 많이 만들어도 클래스는 딱 한번만 인스턴스 생성 이전에 로딩된다. 인스턴스를 만들 때 멤버변수와 멤버함수를 가리키는 함수포인터는 메모리를 할당받게 된다.
  • 즉 클래스가 로딩되는 시점에서는 멤버함수와 멤버변수를 호출할 수 없다.( 존재하지 않으므로 )

[ CASE ]

class Temp{
	static { // 얼마든지 OK
		Temp t = new Temp();
		t.print();		
	}	
	static void print2() {
		// print(); << 에러
		
	}
	void print(){
		System.out.println("dd");
	}
}
public class Main{
	public static void main( String[] args ){
		new Temp();
	}
}
  • 에러메세지 : non-static method print() cannot be referenced from a static context
  • >> static 이 언급된 멤버변수와 함수가 생성되는 시점은 class 로딩할 때 이다. 근데 이 때는 non-static한 멤버들이 존재하기 전이다. 그러므로 static한 멤버 안에서 non-static 한 멤버는 직접 사용힐 수 없다.

[ CASE ]

interface ITemp{
	//	public static void print();  <<  에러
}
  • 인터페이스는 오버라이딩을 전제로 하는 함수여야 하고 오버라이딩은 함수포인터 형태로 운용되어야 하며, 그러려면 인스턴스에 함수포인터가 있어야하고 그러려면 non-static 해야한다. 
  • 그러므로 인터페이스 안에서는 non-static한 메소드를 써야 한다.

[ Singletone Pattern ]

class Temp {
	private Temp() {	// #1. 생성자 앞에 private 붙으면 Temp 밖에서는 생성자를 호출할 수 없다. 즉 인스턴스 생성도 안된다.
	}
    
	// # 2. uniq 변수는 jvm 안에 유일하게 존재한다.
	private static Temp uniq = null;
    
	// #3. static initializer 안에서 uniq로 인스턴스를 가리키게 하라.
	static{ 
		uniq = new Temp();   //클래스 '안'에서 private한 것을 이용할 수 있다.
	}
    
	// #4. public static synchronized 하게 uniq를 제공하는 getInstance 함수를 선언한다.
	public static synchronized Temp getInstance(){
		return uniq;
	}
} 
public class Main {
	public static void main( String[] args ) {
		// new Temp();  << 에러 발생  #1
		
		Temp a = Temp.getInstance() ;
		Temp b = Temp.getInstance() ;
		System.out.println( a == b );  //하나의 인스턴스가 재활용되고 있고 공유되고 있음!!!
		
	}
}
  • JAVA에서 static을 이용해 인스턴스를 딱 하나만 jvm 상에 존재하게 할 수 있다.
  • 이런 식으로 설계하는 설계패턴을 Singletone Pattern 이라고 한다.

'JAVA > 정리한 것' 카테고리의 다른 글

[ JAVA ] 어노테이션( Annotation )  (0) 2022.05.19
[ JAVA ] class.forName()  (0) 2022.05.18
[ JAVA ] 익명 클래스 ( Anonymous Class )  (0) 2022.05.16
[ JAVA ] 제너릭( Generic )  (0) 2022.05.16
[ JAVA ] Abstract 와 Interface  (0) 2022.05.15