▸JAVA/기본 문법

내부 클래스 (Inner Class)

코데방 2019. 12. 10.
728x90

[ 내부 클래스란? ]

  • 클래스 또는 메소드 내부에 생성된 클래스
  • 내부 클래스를 포함한 클래스를 외부 클래스(Outer Class)라고 함
  • 하나의 클래스 또는 메소드에서만 사용되는 클래스가 필요할 때 사용

간단히 말하면, C언어에서 특정 함수에서만 필요한 구조체 선언을 굳이 메인 함수가 있는 곳에 하지 않고 해당 함수가 있는 곳에 따로 하는 것과 비슷한 행위입니다. Java에서는 모든 것이 클래스 단위이기 때문에 필요한 부분에다가 클래스 정의를 해주면 됩니다. 메모리 구조가 머릿속에 잘 그려져 있으면 어렵지 않게 사용이 가능합니다.

 


 

[ 인스턴스 멤버 클래스 ]

  • static이 없고, 인스턴스를 생성해줘야 하는 일반 클래스 형태의 내부 클래스

가장 일반적인 형태입니다. static을 붙이지 않았기 때문에 해당 클래스의 코드가 메모리에 올라와 있지 않은 상태입니다. 외부 클래스를 인스턴스화하면 외부 클래스의 코드가 메모리에 올라오게 되고 이 때 내부 클래스의 코드도 메모리에 올라오게 됩니다. 이렇게 코드를 메모리에 올린 이후에야 다시 해당 클래스의 인스턴스를 생성할 수가 있습니다. 물론 내부 클래스는 다른 클래스에서 직접 사용하는 것보다 해당(외부) 클래스에서만 사용하는 것이 일반적이므로, 내부 클래스의 인스턴스를 다른 클래스에서 만드는 경우는 드물 것 같습니다.

 

package study.first;

public class Study {

	public static void main(String[] args) {

		Outer p = new Outer(); // Outer 클래스 인스턴스 생성
		Outer.Inner c = p.new Inner(); // Outer.Inner 클래스 인스턴스 생성
		System.out.println(c.a);
		c.print();
	}
}

class Outer {

	class Inner {

		int a = 1;

		void print() {
			System.out.println(a + " 함수");
		}
	}
}

 


 

[ 정적 멤버 클래스 ]

  • 일반 클래스와 다르게 내부 클래스는 static 선언이 가능
  • static이 선언되어 이미 클래스의 코드가 메모리에 준비된 상태
  • 소속된 외부클래스의 인스턴스 유무와 관계없이 인스턴스 생성 가능

static을 선언하여 이미 내부 클래스의 코드가 메모리에 올라와 있는 상태이기 때문에 바로 인스턴스화를 할 수 있습니다. 이 경우 내부 클래스의 형태로 코드가 작성되어 있지만 사실 내부 클래스가 아닌 일반 클래스와 동일하게 작동한다고 보면 됩니다. 오히려 클래스 코드를 프로그램 실행 내내 메모리에 올려두고 있으므로 꽤 비효율적입니다. 문법상 가능은 하지만 한 클래스의 내부에서만 사용하기 위해 만드는 내부 클래스를 static 형태로 사용할 이유가 없을 것 같습니다.

 

package study.first;

public class Study {

	public static void main(String[] args) {

		Outer.Inner c = new Outer.Inner();
		System.out.println(c.a);
		c.print();

	}
}

class Outer {

	static class Inner {

		int a = 1;

		void print() {
			System.out.println(a + " 함수");
		}
	}
}

 


 

 

[ 로컬 클래스 ]

  • 메소드 내에 포함된 내부 클래스
  • 스택 메모리에 포함되므로 접근제한자 및 static 선언이 불가능함
  • 해당 메소드 실행 외에는 클래스 접근 및 사용 불가

간단히 메소드 안에서만 사용이 가능한 내부 클래스입니다. 메소드 내의 모든 내용은 스택 프레임 안에 생성됐다가 메소드 종료 시 사라지게 되므로, 다른 곳에서는 접근 및 사용 자체가 불가능합니다. 물론 코드 자체는 코드 영역에 생성되고 실제 데이터도 힙 영역에 생성됐다가 사라지겠지만 논리 상 스택 프레임 내에 잠시 생겼다 없어진다고 이해하면 편합니다. 메소드 내에서 인스턴스를 생성한 후 사용하고 메소드 종료와 함께 레퍼런스가 사라지면서 힙 메모리 영역의 실제 데이터도 GC(가비지 컬렉터)에 의해 지워집니다.

 

package study.first;

public class Study {

	public static void main(String[] args) {

		Outer p = new Outer();
		p.print();
	}
}

class Outer {

	void print() {

		class Inner {
			int a = 1;
		}

		Inner c = new Inner();
		System.out.println(c.a);

	}
}

 

728x90

댓글

💲 추천 글