Java/정석

static, instance 메소드

hs_developer 2022. 5. 29. 21:03

메소드 앞에  static이 붙어 있으면 클래스 메소드이고, 그렇지 않으면 인스턴스 메소드이다.

 

어느 경우에 어떤 메소드를 정의해야 할까?

 

클래스는 데이터(변수)와 관련된 메소드의 집합이므로 같은 클래스 내에 있는 메소드와 멤버변수는 아주 밀접한 관련이 있다.

 

인스턴스 메소드는 메소드의 작업을 수행하는데 인스턴스 변수를 필요로 하는 메소드이다. 인스턴스 메소드도 인스턴스를 생성해야만 호출할 수 있다.

 

반면에, 인스턴스와 관계 없는 메소드를 클래스 메소드로 정의한다.

 

클래스 영역에 선언된 변수를 멤버변수라 한다.
멤버 변수는 인스턴스 변수와 클래스 변수를 모두 통칭한다.

 

1. 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다

생성된 각 인스턴스는 서로 독립적이기 때문에 각 인스턴스 변수는 서로 다른 값을 유지한다. 반면에 모든 인스턴스에서 같은 값이 유지되어야 하는 변수는 클래스 변수로 정의한다.


2. 클래스 변수는 인스턴스를 생성하지 않아도 사용할 수 있다.

클래스 변수는 클래스가 메모리에 올라갈 때 이미 자동적으로 생성된다.


3. 클래스 메소드는 인스턴스 변수를 사용할 수 없다.

클래스 메소드는 인스턴스 없이 클래스를 호출할 수 있다. 그래서 클래스 메소드에서 인스턴스 변수 사용을 금지한다. 반면에, 인스턴스 메소드에서는 static 멤버를 사용 가능하다.


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

메소드 내에서 인스턴스 변수를 필요로 한다면, static을 붙일 수 없지만 그렇지 않으면 static을 붙인다.

 

 

 

300
100
20000
2.0

300
100
20000
2.0
class Math
{
	long a, b;
	
	// 인스턴스 변수 a, b만을 이용하므로 매개변수가 필요 없다
	long add()
	{
		return a+b; // 인스턴스 변수
	}
	long substract()
	{
		return a-b;
	}
	long multiply()
	{
		return a*b;
	}
	double divide()
	{
		return a/b;
	}
	
	// 인스턴스 변수와 관계 없이 매개 변수만으로 작업이 가능하다
	static long add(long a, long b)
	{
		return a+b; // 지역변수
	}
	static long substract(long a, long b)
	{
		return a-b;
	}
	static long multiply(long a, long b)
	{
		return a*b;
	}
	static double divide(double a, double b)
	{
		return a/b;
	}

}

public class test {
	
	public static void main(String[] args) {
		
		// 클래스 메소드 호출, 인스턴스 생성 없이 호출 가능
		System.out.println(Math.add(200L, 100L));
		System.out.println(Math.substract(200L, 100L));
		System.out.println(Math.multiply(200L, 100L));
		System.out.println(Math.divide(200.0, 100.0));
		
		
		// 인스턴스 생성
		Math mm = new Math();
		mm.a = 200L;
		mm.b = 100L;
		
		// 인스턴스 메소드는 객체 생성 후에만 호출 가능 함
		System.out.println(mm.add());
		System.out.println(mm.substract());
		System.out.println(mm.multiply());
		System.out.println(mm.divide());
		
	}
}

 

 

add(long a, long b), substract(long a, long b) 등은 인스턴스 변수 없이 매개변수만으로 작업을 수행하기 때문에 static을 붙여서 클래스 메소드로 선언하였다.

 

그래서 main 메소드를 보면, 클래스 메소드는 객체 생성 없이 바로 호출이 가능했고, 인스턴스 메소드는 Math 클래스의 인스턴스를 생성한 후에야 호출이 가능했다.

 

 

 

클래스 멤버와 인스턴스 멤버간의 참조와 호출

 

같은 클래스에 속한 멤버들 간에는 별도의 인스턴스를 생성하지 않고도 서로 참조 또는 호출이 가능하다. 단, 클래스 멤버가 인스턴스 멤버를 참조 또는 호출하는 경우에는 인스턴스를 생성해야 한다.

 

클래스 멤버가 존재하는 시점에 인스턴스 멤버가 존재하지 않을 수 있기 때문이다.

 

인스턴스 멤버란 인스턴스 변수와 인스턴스 메소드를 뜻한다.

 

 

	void instanceMethod()
	{
		// 인스턴스 메소드
	}
	
	static void staticMethod()
	{
		// static 메소드
	}
	
	void instanceMethod2() // 인스턴스 메소드
	{
		instanceMethod(); // 다른 인스턴스 메소드를 호출한다
		staticMethod(); // static 메소드를 호출한다
	}
	
	static void staticMethod2() // static 메소드
	{
		staticMethod(); // static 메소드를 호출한다
		
		instanceMethod(); // Error! 인스턴스 메소드를 호출할 수 없다
		
		test c = new test();
		c.instanceMethod(); // 인스턴스(객체)를 생성한 후에야 호출할 수 있다
		
	}
	int iv;
	static int cv;
	
	void instanceMethod() // 인스턴스 메소드
	{
		System.out.println(iv); // 인스턴스 변수 사용한다
		System.out.println(cv); // static 변수 사용한다
	}
	
	static void staticMethod() // static 메소드
	{
		System.out.println(iv); // Error! 인스턴스 변수 사용할 수 없다
		System.out.println(cv); // static 변수 사용한다
	}