프로그래밍 언어/JAVA

[JAVA] 정적 멤버와 static

김곰댕 2021. 6. 28. 15:23
728x90

정적(static) 멤버란

정적 멤버란 클래스에 고정된 필드와 메소드를 말한다. 이들을 각각 정적 필드, 정적 메소드라고 부른다.

정적 멤버는 클래스에 소속된 멤버로 객체 내부에 존재하지 않고, 메소드 영역에 존재한다.

정적 멤버는 객체를 생성하지 않고 클래스로 바로 접근해서 사용한다.

 

정적 멤버 선언

필드 또는 메소드를 선언할 때 static 키워드를 붙이면 된다.

public class 클래스
{
       //정적 필드
       static 타입 필드 {= 초기값};
       
       //정적 메소드
       static 리턴타입 메소드 ( 매개변수선언, ... ) { ... }
}

 

정적 멤버 사용

클래스 이름과 함께 도트(.) 연산자로 접근할 수 있다.

클래스.필드;
클래스.메소드( 매개값, ... );
publci class Calculator
{
       static double pi = 3.1459;
       static int plus(int x, int y) { ... }
       static int minus(int x, int y) { ... }
}

[바람직한 사용] //정적 멤버는 클래스 이름으로 접근해서 사용하는것이 좋음
double result1 = 10 * 10 * Calculator.pi;
int result2 = Calculator.plus(10, 5);
int result3 = Calculator.minus(10, 5);

 

예제)

package sec10.exam01_static_member;

public class Calculator 
{
	static double pi = 3.14159;
	
	static int puls (int x, int y)
	{
		return x + y;
	}
	
	static int minus (int x, int y)
	{
		return x - y;
	}
}
package sec10.exam01_static_member;

public class CalculatorExample 
{
	public static void main(String[] args) 
	{
		//만들어 놓은 Calculator.pi 대신에 Math.PI 사용해도 됨 (파이의값)
		double result1 = 10 * 10 * Calculator.pi;
		int result2 = Calculator.puls(10, 5);
		int result3 = Calculator.minus(10, 5);
		
		System.out.println("result1 : " + result1);
		System.out.println("result2 : " + result2);
		System.out.println("result3 : " + result3);
	}
}

출력 결과

 

인스턴스 멤버 선언 vs 정적 멤버 선언의 기준

필드

객체 마다 가지고 있어야할 데이터 -> 인스턴스 필드

공용적인 데이터 -> 정적 필드

public class Calculator
{
       String color;                     //계산기 별로 색깔이 다를 수 있다.
       static double pi = 3.14159;  //계산기에서 사용하는 파이값은 동일하다. static으로 만들고 객체들이 공유해서 사용하는것이 더 좋음
}

메소드

인스턴스 필드로 작업해야할 메소드 -> 인스턴스 메소드

인스턴스 필드로 작업하지 않는 메소드 -> 정적 메소드

public Calculator
{
       String color;    //인스턴스 필드
       void setColor(String color) { this color = color; } //인스턴스 필드를 사용하기 때문에 인스턴스 메소드
       static int plus (int x, int y) { return x + y ; }
       static int minus (int x , int y) { return x - y ; }
}

 

정적 초기화 블록

클래스가 메소드 영역으로 로딩 될 때 자동으로 실행하는 블록이다.

정적 필드의 복잡한 초기화 작업과 정적 메소드를 호출할 수 있다.

클래스 내부에 여러개가 선언되어도 상관없다. 선언된 순서대로 진행된다.

[형태]
static
{
       //정적필드 초기화, 정적 메소드 호출 가능
       //인스턴스 필드, 인스턴스 메소드 호출 불가능
}

 

예제)

package sec10.exam02_static_block;

public class Television 
{
	static String company = "Samsung";
	static String model = "LCD";
	static String info;
	static int From1To10Sum;
	
	static
	{
		info = company + "-" + model;
		
		int sum = 0;
		for(int i = 0; i<=10; i++)
		{
			sum += i;
		}
		From1To10Sum = sum;
	}
}
package sec10.exam02_static_block;

public class TelevisionExample 
{
	public static void main(String[] args) 
	{
		System.out.println(Television.info);
		System.out.println(Television.From1To10Sum);
	}
}

출력 결과

 

정적 메소드와 정적 블록 작성시 주의할 점

객체가 없어도 실행할 수 있기 때문에 이들 블록내부에 인스턴스 필드나 인스턴스 메소드를 사용할 수 없다.

객체 자신의 참조인 this를 사용할 수 없다. (객체가 없기 때문에)

main() 메소드도 정적 메소드이다.

 

예제)

package sec10.exam03_be_careful;

public class Car 
{
	int speed; //인스턴스 필드
	
	void run() //인스턴스 메소드
	{
		System.out.println(speed + "으로 달립니다.");
		
	}
	
	public static void main(String[] args)
	{
		Car myCar = new Car();
		myCar.speed = 60;
		myCar.run();
	}
}

출력 결과

 

싱글톤(Singleton)

하나의 애플리케이션 내에서 단 하나만 생성되는 객체를 말한다.

 

싱글톤을 만드는 방법

외부에서 new 연산자로 생성자를 호출할 수 없도록 막는다. (private 접근 제한자를 생성자 앞에 붙인다.)

클래스 자신의 타입으로 정적 필드를 선언하고, 자신의 객체를 생성해 초기화한다. (private 접근 제한자를 붙여 외부에서 필드값을 변경할 수 없도록 막는다.)

외부에서 호출할 수 있는 정적 메소드인 getInstance()를 선언한다. (정적 필드에서 참조하고 있는 자신의 객체를 리턴하도록 한다.)

 

예제)

package sec10.exam04_singleton;

public class Singleton 
{
	private static Singleton singleton = new Singleton(); //정적 필드
	
	private Singleton()
	{
		
	}
	
	static Singleton getInstance()
	{
		return singleton;
	}
}
package sec10.exam04_singleton;

public class SingletonExample 
{
	public static void main(String[] args) 
	{
		Singleton obj1 = Singleton.getInstance();
		Singleton obj2 = Singleton.getInstance();
		
		if(obj1 == obj2)
		{
			System.out.println("같은 Singleton 객체 입니다.");
		}
		else
		{
			System.out.println("다른 Singleton 객체 입니다.");
		}
	}
}

출력 결과

 

728x90