Coding/Java

Java Inner Class(내부 클래스)

heyoon2j 2020. 9. 18. 00:13

■ Java Inner Class (내부 클래스)

 - Outer(Class, Method) 내부에 선언하는 클래스로 중첩 클래스(Nested Class)라고도 부름

 - 보통 해당 Outer(Class, Method)에서만 사용하기 위해서 사용된다.

 

• Inner Class Type

 - Instance Inner Class

 - Static Inner Class

 - Local Inner Class

 - Anonymous Inner Class

 

• Compile 시, Class Name

  • Instance, Static Inner Class : {OuterClass}${InnerClass}.class
  • Local Inner Class : {OuterClass}$1{InnerClass}.class (1은 해당 Class 번호를 얘기한다)

 


1. Static Class에 대한 고찰

• 기본적으로 작성하는 Class(Outer Class)는 Static Class이다.

- 그렇기 때문에, 바로 Class 생성이 가능하다(Class 참조 값을 알 수 있다)

 

• Static Class에만 바로 접근이 가능하다는 의미이지, 해당 Class의 멤버 변수, 멤버 함수에 접근이 가능하다는 의미가 아니다.

 

• Inner Class vs Static Inner Class

 1) Inner Class 인 경우   a. Outer Class의 Instance에 대한 외부 참조 값을 가진다.   b. 생성 시 : OuterClassInstance.new InnerClass();

 

 2) Static Inner Class 인 경우   a. Outer Class의 Instance에 대한 외부 참조 값이 없다.

   b. 생성 시 : new OuterClass.InnerClass();

 


2. Instance Inner Class

- 클래스 내부에 static 키워드 없이 선언된 클래스

- 외부 클래스의 객체를 통해서만 생성 및 접근 가능

- static 멤버 변수는 사용할 수 없으나, static final은 허용한다.

  * static final은 상수 풀(constant pool)을 가리키게 된다.

class OutClass{
    private int outNum = 10;
    private static int sOutNum = 20;
    private InClass inClass;

    public OutClass(){
        inClass = new InClass();    // 일반적으로 Inner Class는 Constructor에서 생성함
    }

    class InClass {
        int iNum = 100;
//        static int sInNum = 200;
        static final int fInNum = 500;
        void inMethod(){
            System.out.println(outNum);
            System.out.println(sOutNum);
            System.out.println(iNum);
            usingInner();
        }
    }

    public void usingInner(){
        inClass.inMethod();
    }
}

public class InnerClass {
	public static void main(String[] args) {
		OutClass outClass = new OutClass();
		outClass.usingInner();
		OutClass.InClass myInClass = outClass.new InClass();
	}
}

 

• 외부 클래스의 멤버 변수와 이름이 겹치는 경우, this 활용

class Outer {
    class InstanceInner {
        int var = 1;

        void innerMethod() {
        	int var = 0;
            System.out.println(var);	// 0
            System.out.println(this.var);	// 1
            System.out.println(Outer.this.var);	// 2
        }
    }

  private int var = 2;

  public static void main(String[] args) {
      Outer outer = new Outer();
      InstanceInner inner = outer.new InstanceInner();
      inner.innerMethod();
  }
}

 


3. Static Inner Class

- 클래스 내부에 static 키워드와 함께 선언된 클래스

- 외부 클래스의 객체가 없어도 생성 및 접근 가능

class OutClass{
    private int outNum = 10;
    private static int sOutNum = 20;
    private InClass inClass;

    public OutClass(){
        inClass = new InClass();    // 일반적으로 Inner Class는 Constructor에서 생성함
    }
    
        public void usingInner(){
        inClass.inMethod();
    }

    static class InStaticClass{
        int inNUm = 100;
        static int sInNum = 200;

        void inTest(){
//            System.out.println(outNUm);
            System.out.println(sOutNum);
            System.out.println(inNUm);
            System.out.println(sInNum);
        }
        static void sTest(){
//            System.out.println(outNUm);
            System.out.println(sOutNum);
//            System.out.println(inNum);
            System.out.println(sInNum);
//            usingInner();
        }
    }
}


public class InnerClass {
    public static void main(String[] args) {
         OutClass.InStaticClass sInClass = new OutClass.InStaticClass();
        OutClass.InStaticClass.sTest();
//        OutClass.InStaticClass.inNum;
    }
}

 


4. Local Inner Class

- 로컬 영역에 선언된 클래스

- static 멤버 변수는 사용할 수 없으나, static final은 허용한다.

- Java 1.8부터 로컬 변수와 파라미터가 final로 간주되어 복사된다.

class OuterClass{
    int outNum = 100;
    static int sOutNum=200;

    Runnable getRunnable(int i){
        int num = 100;

        // LocalClass
        class MyRunnable implements Runnable{
            @Override
            public void run() {
//                num += 10;        // num, i는 Local 변수이기 때문에, 함수가 종료되면 사라지기 때문에 사용불가
//                i = 200;          // 그렇기 때문에, Java에서는 Local 변수를 final로 자동으로 변경하고, 복사하여 LocalClass 내부에도 저장한다.
                System.out.println(num);
                System.out.println(i);

                System.out.println(outNum);     // Possible
                System.out.println(sOutNum);    // Possible
            }
        }
        return new MyRunnable();
	}
}

 


5. Anonymous Inner Class

- 로컬 내부 클래스와 동일하나, 이름이 없고 선언 즉시 한 번 사용 가능

- 추상 클래스나 인터페이스의 구현에 많이 사용

class OuterClass{
    int outNum = 100;
    static int sOutNum=200;

    Runnable getRunnable(int i){
        int num = 100;

        // Anonymous Object
        return new Runnable(){
            int i = 10;
//            static int j = 20;
            @Override
            public void run() {
                System.out.println(num);
                System.out.println(i);

                System.out.println(outNum);
                System.out.println(sOutNum);
            }
        };
    }

    // Anonymous Object
    Runnable runner = new Runnable() {
        @Override
        public void run() {
            System.out.println();
        }
    };
}

 

 

 

'Coding > Java' 카테고리의 다른 글

Java Comparator & Comparable  (0) 2020.09.22
Java Lambda Expression(람다식)  (0) 2020.09.18
Java Handling Exception(예외 처리)  (0) 2020.09.17
Java Generic(제네릭)  (0) 2020.09.17
Java Enumeration(열거형)  (0) 2020.09.17