IT박스

Java에서 익명의 내부 클래스를 정적으로 만들 수 있습니까?

itboxs 2020. 7. 17. 21:11
반응형

Java에서 익명의 내부 클래스를 정적으로 만들 수 있습니까?


Java에서 중첩 클래스는 둘 중 하나 일 수 있습니다 static. 이 경우 static포함하는 인스턴스의 포인터에 대한 참조를 포함하지 않습니다 (더 이상 내부 클래스라고도하지 않고 중첩 클래스라고 함).

static참조가 필요하지 않을 때 중첩 클래스를 작성 하지 않으면 가비지 콜렉션 또는 이스케이프 분석에 문제가 발생할 수 있습니다.

익명의 내부 클래스 static만들 수 있습니까? 아니면 컴파일러가 이것을 자동으로 알아 냅니까 (서브 클래스가 없기 때문에 가능합니까)?

예를 들어, 익명 비교기를 만들면 외부에 대한 참조가 거의 필요하지 않습니다.

  Collections.sort(list, new Comparator<String>(){
       int compare(String a, String b){
          return a.toUpperCase().compareTo(b.toUpperCase());
       }
  }

아니요, 컴파일러는 그것을 알아낼 수 없습니다. 그렇기 때문에 FindBugs static는 암시 적 this참조를 사용하지 않는 경우 익명 내부 클래스를 명명 된 중첩 클래스 로 변경하도록 항상 제안 합니다.

편집 : Tom Hawtin-tackline은 익명 클래스가 정적 컨텍스트 (예 : main메소드)에서 생성되면 실제로 익명 클래스 라고 말합니다 static. 그러나 JLS는 동의하지 않습니다 .

익명 클래스는 절대로 적용되지 않습니다 abstract(§8.1.1.1). 익명 클래스는 항상 내부 클래스입니다 (§8.1.3). 결코 static그렇지 않습니다 (§8.1.1, §8.5.1). 익명 클래스는 항상 암시 적입니다 final(§8.1.1.2).

Roedy Green의 Java Glossary 정적 컨텍스트에서 익명 클래스가 허용된다는 사실은 구현에 따라 다릅니다.

코드를 유지 관리하는 사람들을 방해하고 싶다면 언어 사양에 익명 클래스가 결코 없다고 말하더라도 wags는 init 코드 및 메소드 javac.exe내에서 익명 클래스를 허용 합니다. 물론 이러한 익명 클래스는 객체의 인스턴스 필드에 액세스 할 수 없습니다. 나는 이것을하지 않는 것이 좋습니다. 기능 은 언제든지 가져올 수 있습니다.staticstaticstatic

편집 2 : JLS는 실제로 §15.9.2 에서 정적 컨텍스트를 더 명확하게 다루고 있습니다 .

하자 C는 인스턴스화하는 클래스, 그리고하자 내가 인스턴스가 생성되는 수. 경우 C는 내부 클래스 다음 직접 둘러싸 인스턴스를 가질 수있다. i를 즉시 둘러싸는 인스턴스 (8.1.3)는 다음과 같이 결정됩니다.

  • 경우 C는 다음 익명 클래스입니다 :
    • 클래스 인스턴스 생성 식 정적 콘텍스트 (§8.1.3)에서 발생한다면, 에는 즉시 인스턴스를 둘러싸는 없다.
    • 그렇지 않으면, i를 즉시 둘러싸는 인스턴스는 입니다 this.

따라서 정적 컨텍스트의 익명 클래스는 static기술적으로 static클래스가 아니지만 엔 클로징 클래스에 대한 참조를 유지하지 않는다는 점에서 중첩 클래스 와 거의 같습니다 .


거의. 정적 메소드로 작성된 익명의 내부 클래스는 외부에 대한 소스가 없기 때문에 분명히 정적입니다.

정적 컨텍스트의 내부 클래스와 정적 중첩 클래스에는 기술적 인 차이가 있습니다. 관심이 있으시면 JLS 3rd Ed를 읽으십시오.


나는 여기의 명명법에 약간의 혼란이 있다고 생각하는데, 이것은 너무 어리 석고 혼란 스럽습니다.

무엇을 호출하든, 이러한 패턴 (및 가시성이 다른 몇 가지 변형)은 모두 정상적이고 합법적 인 Java입니다.

public class MyClass {
  class MyClassInside {
  }
}

public class MyClass {
  public static class MyClassInside {
  }
}

public class MyClass {
  public void method() {
    JComponent jc = new JComponent() {
      ...
    }
  }
}

public class MyClass {
  public static void myStaticMethod() {
    JComponent jc = new JComponent() {
      ...
    }
  }
}

They are catered for in the language spec (if you're really bothered, see section 15.9.5.1 for the one inside the static method).

But this quote is just plain wrong:

javac.exe will permit anonymous classes inside static init code and static methods, even though the language spec says than anonymous classes are never static

I think the quoted author is confusing the static keyword with static context. (Admittedly, the JLS is also a bit confusing in this respect.)

Honestly, all of the patterns above are fine (whatever you call them "nested", "inner", "anonymous" whatever...). Really, nobody is going to suddenly remove this functionality in the next release of Java. Honestly!


Inner classes can't be static - a static nested class is not an inner class. The Java tutorial talks about it here.


anonymous inner classes are never static (they can't declare static methods or non final static fields),but if they're defined in a static context (static method or static field) they behave as static in the sense that they can't access non-static (i.e. instance) members of the enclosing class (like everything else from a static context)


On the note of making an anonymous inner class static by calling them within a static method.

This doesn't actually remove the reference. You can test this by trying to serialize the anonymous class and not making the enclosing class serializable.

참고URL : https://stackoverflow.com/questions/758570/is-it-possible-to-make-anonymous-inner-classes-in-java-static

반응형