Language/JAVA

[JAVA] 인스턴스 멤버와 정적 멤버

IT수정 2024. 9. 4. 14:50

필드와 메서드는 선언 방법에 따라 인스턴스 멤버와 정적 멤버로 구분할 수 있다. 인스턴스 멤버로 선언되면 객체 생성 후 사용할 수 있고, 정적 멤버로 선언되면 객체 생성 없이도 사용할 수 있다.

구분 설명
인스턴스(Instance) 멤버 객체에 소속된 멤버
(객체를 생성해야만 사용할 수 있는 멤버)
정적(static) 멤버 클래스에 고정된 멤버
(객체 없이도 사용할 수 있는 멤버)

 

인스턴스 멤버 선언 및 사용

인스턴스 멤버는 객체에 소속된 멤버이다. 따라서 객체가 있어야만 사용할 수 있는 멤버다. 다음과 같이 Car 클래스에 gas 필드와 setSpeed() 메서드를 선언하면 인스턴스 멤버가 된다.

public class Car {
	int gas;
    void setSpeed(int speed) {...}
    }

 

gas 필드와 setSpeed() 메서드는 인스턴스 멤버이기 때문에 외부 클래스에서 사용하기 위해서는 Car 객체를 먼저 생성하고 참조 변수로 접근해서 사용해야 한다.

Car myCar = new Car();
myCar.gas = 10;
myCar.setSpeed(60);

 

여기서 우리는 '객체에 소속된'을 '객체에 포함된'이라고 해석하면 안 된다. 메서드는 코드 덩어리이므로 객체마다 저장한다면 중복 저장으로 인해 메모리 효율이 떨어진다. 메서드 코드는 메서드 영역에 두고 공유해서 사용한다.

 

this 키워드

객체 내부에서는 인스턴스 멤버에 접근하기 위해 this를 사용할 수 있다. 우리가 자신을 '나'라고 하듯이, 객체는 자신을 'this'라고 한다. 생성자와 메서드의 매개변수명이 인스턴스 멤버인 필드명과 동일한 경우, 인스턴스 필드임을 강조하고자 할 때 this를 주로 사용한다.

 

정적 멤버

자바는 클래스 로더를 이용해서 클래스를 메서드 영역에 저장하고 사용한다. 정적 멤버란 메서드 영역의 클래스에 고정적으로 위치하는 멤버를 말한다. 그렇기 때문에 정적 멤버는 객체를 생성할 필요 없이 클래스를 통해 바로 사용이 가능하다.

 

정적 멤버 선언

필드와 메서드는 모두 정적 멤버가 될 수 있다. 정적 필드와 정적 메서드로 선언하려면 다음과 같이 static 키워드를 추가하면 된다.

public class 클래스 {
	static 타입 필드 [= 초기값];
    static 리턴타입 메서드(매개변수, ...) {...}
    }

 

객체마다 가지고 있을 필요성이 없는 공용적인 필드는 정적 필드로 선언하는 것이 좋다. 예를 들어 원의 넓이나 둘레를 구할 때 필요한 파이는 정적 필드로 선언하는 것이 좋다.

public class Calculator {
	String color;
    static double pi = 3.14159;
    }

 

인스턴스 필드를 이용하지 않는 메서드는 정적 메서드로 선언하는 것이 좋다. 다음 코드처럼 외부에서 주어진 매개값을 가지고 처리하는 메서드는 정적 메서드로 선언하는 것이 좋다.

public class Caculator {
	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;
        }

 

정적 멤버 사용

클래스가 메모리로 로딩되면 정적 멤버를 바로 사용할 수 있는데, 클래스 이름과 함께 도트(.) 연산자로 접근하면 된다. 예를 들어 Calculator 클래스가 다음과 같이 작성되었다면,

public class Calculator {
	static double pi = 3.14159;
    static int plus(int x, int y) {...}
    static int minus(int x, int y) {...}
    }

 

정적 필드 pi와 정적 메서드 plus(), minus() 는 다음과 같이 사용할 수 있다.

double result1 = 10 * 10 * Calculator.pi;
int result2 = Calculator.plus(10, 5);
int result3 = Calculator.minus(10, 5);

 

정적 필드와 정적 메서드는 다음과 같이 객체 참조 변수로도 접근이 가능하다.

Calculator myCal = new Calculator();
double result1 = 10 * 10 * myCal.pi;
int result2 = myCal.plus(10, 5);
int result3 = myCal.minus(10, 5);

 

하지만 정적 요소는 클래스 이름으로 접근하는 것이 정석이다. 이클립스에서는 정적 멤버를 객체 참조 변수로 접근했을 경우, 경고 표시가 뜬다.

 

정적 블록

정적 필드는 다음과 같이 필드 선언과 동시에 초기값을 주는 것이 일반적이다.

static double pi = 3.14159;

 

하지만 복잡한 초기화 작업이 필요하다면 정적 블록을 이용해야 한다. 정적 블록은 정적 블록이 클래스 내부에 여러 개가 선언되어 있을 경우에는 선언된 순서대로 실행된다.

static {
	...
    }

 

인스턴스 멤버 사용 불가

정적 메서드와 정적 블록은 객체가 없어도 실행된다는 특징 때문에 내부에 인스턴스 필드나 인스턴스 메서드를 사용할 수 없다. 또한 객체 자신의 참조인 this도 사용할 수 없다. 정적 메서드와 정적 블록에서 인스턴스 멤버를 사용하고 싶다면 다음과 같이 객체를 먼저 생성하고 참조변수로 접근해야 한다.

static void method() {
	ClassName obj = new ClassName();
   	obj.field1 = 10;
    obj.method1();
    }

 

main() 메서드도 동일한 규칙이 적용된다. main() 메서드도 정적 메서드이므로 객체 생성 없이 인스턴스 필드와 인스턴스 메서드를 바로 사용할 수 없다.

'Language > JAVA' 카테고리의 다른 글

[JAVA] 패키지  (0) 2024.09.04
[JAVA] final 필드와 상수  (0) 2024.09.04
[JAVA] 메서드  (0) 2024.09.04
[JAVA] 생성자  (2) 2024.09.04
[JAVA] 필드  (0) 2024.09.04