클래스 내에 선언되는 클래스. 두 클래스가 서로 긴밀한 관계에 있을 때 주로 사용한다.
class Outer{
...
class Inner{
...
}
...
}
내부 클래스 | 특징 |
---|---|
인스턴트 클래스 | 외부 클래스의 인스턴스 멤버처럼 다루어진다. 주로 외부 클래스의 인스턴스멤버 관련 작업에 사용된다. |
스태틱 클래스 | 외부 클래스의 static 멤버처럼 다루어진다. 주로 외부 클래스의 static 멤버, 특히 static 메소드에 사용된다. |
지역 클래스 | 외부 클래스의 메서드 또는 초기화블럭 안에서 선언되고 사용된다. |
익명 클래스 | 클래스의 선언 및 객체 생성을 동시에 하는 일회용 클래스. |
내부 클래스 중 스태틱 클래스만이 static 멤버를 가질 수 있다.
final static 멤버는 상수이기 때문에 모든 종류의 내부 클래스에서 사용 가능하다.
인스턴스 클래스는 외부 클래스의 인스턴스멤버를 객체생성 없이 바로 사용 가능하다.
스태틱 클래스는 외부 클래스의 인스턴스멤버를 객체생성 없이 사용 불가능하다.
외부 클래스가 아닌 다른 클래스에서 내부 클래스를 생성하고 내부 클래스에 접근할 수도 있다. 그러나 이런 경우가 발생한다면 내부 클래스로 선언하면 안 되는 클래스를 내부 클래스로 선언했다는 것을 뜻한다.
이 글을 쓰게 된 주 원인이 다음 코드다.
"hello-api"라는 get 요청에 대해 hello 객체를 response로 리턴해주고 있다. (이는 Jackson 등의 라이브러리를 통해 json 형태로 클라이언트에게 전송된다.)
Controller의 내부 클래스로 작성된 Hello 클래스는 static 클래스다. 나는 여기서 3가지 의문이 들었다.
공부 결과 그 답은 다음과 같았다.
1번 질문에 대한 답변
2번 질문에 대한 답변
Hello 클래스는 static이지만, setName 메소드는 static이 아니다. 따라서 Hello 클래스의 인스턴스 객체가 요구된다. 만약 setName 메소드 역시 static이라면
Hello.setName(name);
과 같이 사용이 가능할 것이다.
3번 질문에 대한 답변
controller에서는 결국 mapping으로 받은 request에 대한 response를 리턴해주어야 한다. 그 리턴을 객체로 하기 위해서는 결국 클래스의 객체 생성은 필수적이다.