2013-04-22 6 views
19

Java 클래스에 내부 클래스가 있습니다.Java로 내부 클래스를 정적으로 만드는 이점은 무엇입니까?

enter image description here

내가 find bugs를 실행하면 권장 (경고)는이 정적으로 확인합니다.

enter image description here

이 경고의 점은 무엇입니까? 내부 클래스를 정적으로 만드는 이점은 무엇입니까?

+0

의 중복 가능성 http://stackoverflow.com/questions/70324/java-inner-에서 찾을 수있다 class-and-static-nested-class) – andyb

+0

링크 된 질문은 중복되지 않습니다 * 내부 클래스를 정적으로 만드는 장점이나 단점을 나타내지는 않습니다. – Perception

+0

가능한 중복 [Java에서 정적 중첩 클래스, 왜?] (http://stackoverflow.com/questions/253492/static-nested-class-in-java-why) – fglez

답변

19

중첩 된 클래스가 포함 된 클래스의 변수에 액세스하지 않으면 정적으로 만들 수 있습니다. 이것의 장점은 중첩 클래스를 사용하기 위해 외부 클래스의 둘러싼 인스턴스가 필요 없다는 것입니다.

+0

+1 방금이 문제가 발생하여 마나 물약은 포션 클래스에 있지만 새로운 마나 포션을 선언하는 것은 불가능합니다(). – arynaq

+1

@arynaq - 상속은 'ManaPotion'이 '포션'의 내부 클래스가 아니어야한다는 강력한 지표입니다. 좋은 예는 Map.Entry 인스턴스를 사용하여 항목을 보유하는'Map'입니다. 'Potion'은'Potion.ManaPotion'을 사용할 것인가? 이것은 정적 내부 클래스에도 적용됩니다. –

+0

사실, 중첩 된 클래스를 사용하는 유일한 방법은 테스트를위한 것이 었습니다. – arynaq

2

정적이 아닌 내부 클래스에는 외부 클래스에 대한 암시 적 참조가 있습니다. 클래스를 정적으로 만들면 메모리와 코드를 절약 할 수 있습니다.

7

기본적으로 내부 클래스에는 외부 클래스의 개체에 대한 암시 적 참조가 있습니다. 외부 클래스의 코드에서이 객체를 인스턴스화하면이 작업이 모두 완료됩니다. 그렇지 않으면 직접 개체를 제공해야합니다.

정적 내부 클래스에는이 속성이 없습니다.

즉, 외부 클래스 객체의 범위 외부에서 인스턴스화 될 수 있음을 의미합니다. 또한 내부 클래스의 인스턴스를 '내보낼'경우 현재 개체를 수집 할 수 없습니다.

기본적으로 내부 클래스가 외부 클래스에 액세스 할 이유가없는 경우 기본적으로 정적으로 설정해야합니다.

+0

나는 기본 규칙을 좋아한다. 그것은 당신이 정의한 것이다. – roottraveller

2

정적 내부 클래스는 의미 론적으로 간단한 것입니다. 가시성을위한 더 많은 옵션 (예 : 비공개로 설정할 수 있음)을 제외하고는 최상위 클래스와 같습니다.

정적이 아닌 내부 클래스를 피하는 중요한 이유는 더 복잡하다는 것입니다. 외부 클래스에 대한 숨겨진 참조가 있습니다 (어쩌면 하나 이상). 그리고 내부 클래스의 메서드에서 간단한 이름은 이제 세 가지 중 하나가 될 수 있습니다 : 로컬, 필드 또는 외부 클래스의 필드.

외부 클래스에 대한 숨겨진 참조로 인해 메모리 누수가 발생할 수있는 아티팩트가 있습니다. 내부 클래스가 리스너이고 정적 내부 클래스가 될 수 있다고 가정합니다. 청취자가 등록되어있는 한, 외부 클래스의 인스턴스에 대한 참조를 보유합니다. 그러면 외부 클래스의 인스턴스가 많은 양의 메모리를 보유하게됩니다. 리스너를 정적으로 만들면 외부 인스턴스가 가비지 수집 될 수 있습니다.

0

우리는 이미 여기에 좋은 답변을 내 5 센트 :

정적 및 우리가 아직 방법과 외부 클래스의 변수를 사용하여 논리적 기능을 분리 할 필요가있을 때 내부 클래스를 사용하는 비 정적 둘. 두 내부 클래스 모두 외부 클래스의 전용 변수에 액세스 할 수 있습니다.정적 내부 클래스

장점 : 1) 외부 클래스에서 정적 변수에 액세스 할 수있는 정적 클래스 2 정적 클래스 독립적 클래스처럼 취급 될 수있다)

비 정적 내부 클래스 : 1)를 사용할 수 없습니다

: 외부 클래스 2)의 고정 부재가 외측으로부터 내측 정적 및 비 정적 내부 클래스 액세스 독립적 클래스

public class NestedClassDemo { 
    private int a = 100; 
    int b = 200; 
    private static int c = 500; 

    public NestedClassDemo() { 
     TestInnerStatic teststat = new TestInnerStatic(); 
     System.out.println("const of NestedClassDemo, a is:"+a+", b is:"+b+".."+teststat.teststat_a); 
    } 

    public String getTask1(){ 
     return new TestInnerClass().getTask1(); 
    } 

    public String getTask2(){ 
     return getTask1(); 
    } 


    class TestInnerClass{ 
     int test_a = 10; 

     TestInnerClass() { 
      System.out.println("const of testinner private member of outerlcass"+a+"..."+c); 
     } 
     String getTask1(){ 
      return "task1 from inner:"+test_a+","+a; 
     } 
    } 

    static class TestInnerStatic{ 
     int teststat_a = 20; 

     public TestInnerStatic() { 
      System.out.println("const of testinnerstat:"+teststat_a+" member of outer:"+c); 
     } 

     String getTask1stat(){ 
      return "task1 from inner stat:"+teststat_a+","+c; 
     } 
    } 

    public static void main(String[] args){ 
     TestInnerStatic teststat = new TestInnerStatic(); 
     System.out.println(teststat.teststat_a); 
     NestedClassDemo nestdemo = new NestedClassDemo(); 
     System.out.println(nestdemo.getTask1()+"...."+nestdemo.getTask2()); 
    } 
} 

처럼 취급 될 수 없다 516,

public class TestClass { 
    public static void main(String[] args){ 
     NestedClassDemo.TestInnerClass a = new NestedClassDemo().new TestInnerClass(); 
     NestedClassDemo.TestInnerStatic b = new NestedClassDemo.TestInnerStatic(); 
    } 
} 

정적 내부 클래스 공식 문서가 자바 https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

[내부 자바 클래스 및 정적 중첩 클래스 (