IT이야기

Java에서 inner 클래스와 static nested 클래스의 주요 차이점은 무엇입니까?

cyworld 2022. 7. 2. 13:28
반응형

Java 내부 클래스 및 정적 중첩 클래스

Java에서 inner 클래스와 static nested 클래스의 주요 차이점은 무엇입니까?설계/도입이 이들 중 하나를 선택하는 데 중요한 역할을 합니까?

Java 튜토리얼에서:

네스트 클래스는 스태틱과 비 스태틱의 두 가지 카테고리로 나뉩니다.스태틱으로 선언된 중첩 클래스는 단순히 스태틱 중첩 클래스라고 불립니다.스태틱하지 않은 네스트 클래스는 내부 클래스라고 불립니다.

스태틱 네스트클래스에 액세스 하려면 , 다음의 클래스명을 사용합니다.

OuterClass.StaticNestedClass

예를 들어, 스태틱네스트 클래스의 오브젝트를 작성하려면 다음 구문을 사용합니다.

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

내부 클래스의 인스턴스인 객체는 외부 클래스의 인스턴스 내에 존재합니다.다음 클래스를 고려합니다.

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

InnerClass 인스턴스는 OuterClass 인스턴스 내에만 존재할 수 있으며 해당 인스턴스의 메서드 및 필드에 직접 액세스할 수 있습니다.

내부 클래스를 인스턴스화하려면 먼저 외부 클래스를 인스턴스화해야 합니다.그런 다음 다음 다음 구문을 사용하여 외부 개체 내에 내부 개체를 만듭니다.

OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

참고 항목: Java 튜토리얼 - 중첩된 클래스

완전성을 위해 동봉된 인스턴스가 없는 내부 클래스도 있다는 점에 유의사항)가 없는 내부 클래스(inner class)도 있습니다.

class A {
  int t() { return 1; }
  static A a =  new A() { int t() { return 2; } };
}

서서,,new A() { ... }스태틱 컨텍스트에서 정의된 내부 클래스이며, 둘러싸인 인스턴스는 없습니다.

Java 튜토리얼에는 다음과 같이 기재되어 있습니다.

용어:네스트 클래스는 스태틱과 비 스태틱의 두 가지 카테고리로 나뉩니다.스태틱으로 선언된 중첩 클래스는 단순히 스태틱 중첩 클래스라고 불립니다.스태틱하지 않은 네스트 클래스는 내부 클래스라고 불립니다.

일반적으로 "내포"와 "내포"라는 용어는 대부분의 프로그래머에 의해 서로 바꿔서 사용되지만, "내포"와 "내포"를 모두 포함하는 올바른 "내포 클래스"를 사용합니다.

클래스는 nested ad ininitum으로 할 수 있습니다.예를 들어 클래스 A는 클래스 D를 포함하는 클래스 C를 포함할 수 있습니다.그러나 클래스 중첩 수준은 일반적으로 잘못된 설계이므로 두 개 이상의 클래스 중첩 수준은 거의 없습니다.

네스트된 클래스를 만드는 이유는 다음 세 가지가 있습니다.

  • organization: 클래스를 다른 클래스의 네임스페이스로 정렬하는 것이 가장 현명한 것처럼 보일 수 있습니다.특히 다른 컨텍스트에서 사용되지 않을 경우
  • access: 네스트된 클래스는 포함하는 클래스의 변수/필드에 대한 특별한 접근권을 가집니다(내부 또는 스태틱에 관계없이 네스트된 클래스의 종류에 따라 변수/필드가 달라집니다).
  • 편리성: 새로운 타입마다 새로운 파일을 작성해야 하는 번거로움, 특히 그 타입이 하나의 컨텍스트에서만 사용되는 경우

Java에는 네 가지 종류의 중첩 클래스가 있습니다.요약하면 다음과 같습니다.

  • static 클래스: 다른 클래스의 스태틱멤버로 선언됨
  • inner 클래스: 다른 클래스의 인스턴스 멤버로 선언됨
  • 로컬 내부 클래스: 다른 클래스의 인스턴스 메서드 내에서 선언됨
  • 익명의 내부 클래스: 로컬 내부 클래스와 비슷하지만 일회성 객체를 반환하는 표현으로 작성됨

좀 더 자세히 설명해 드릴게요.


스태틱 클래스

스태틱 클래스는 포함하는 클래스의 인스턴스와 무관하므로 이해하기 가장 쉬운 종류입니다.

스태틱 클래스는 다른 클래스의 스태틱멤버로 선언된 클래스입니다다른 정적 멤버와 마찬가지로 이러한 클래스는 포함 클래스를 네임스페이스로 사용하는 행거에 불과합니다.를 들어 패키지 피자에서 코뿔소의 정적 멤버로 선언된 클래스 피자라는 이름으로 알려져 있습니다.코뿔소.고양이.

package pizza;

public class Rhino {

    ...

    public static class Goat {
        ...
    }
}

솔직히 말하면 정적 클래스는 패키지에 의해 이미 네임스페이스로 분할되어 있기 때문에 가치가 없는 기능입니다.스태틱 클래스를 만드는 유일한 진짜 이유는 이러한 클래스가 포함된 클래스의 프라이빗 스태틱멤버에 액세스할 수 있기 때문입니다만, 이것은 스태틱클래스 기능이 존재하는 것에 대한 매우 어설픈 이유라고 생각합니다.


내부 클래스

내부 클래스는 다른 클래스의 비스타틱멤버로 선언된 클래스입니다

package pizza;

public class Rhino {

    public class Goat {
        ...
    }

    private void jerry() {
        Goat g = new Goat();
    }
}

정적 클래스와 마찬가지로 내부 클래스는 포함된 클래스 이름인 피자에 의해 적격으로 알려져 있습니다.Rhino.Goat, 그러나 포함된 클래스 내에서는 간단한 이름으로 알 수 있습니다.그러나 내부 클래스의 모든 인스턴스는 포함된 클래스의 특정 인스턴스에 연결됩니다. 위의 gotjerry에서 작성된 Rhino 인스턴스에 암묵적으로 연결되어 있습니다.그렇지 않으면 Got를 인스턴스화할 때 연관된 Rhino 인스턴스를 명시합니다.

Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();

(기묘한 새로운 구문에서는 내부 타입을 Got이라고 부릅니다.Java는 코뿔소 부분에서 포함 타입을 추론합니다.그리고, 네, 새로운 코뿔소.Got()는 나에게도 더 의미가 있었을 것이다.)

그럼 이게 무슨 이득이죠?내부 클래스 인스턴스는 포함된 클래스 인스턴스의 인스턴스 멤버에 액세스할 수 있습니다.이러한 엔클로징인스턴스 멤버는 단순한 이름만으로 inner 클래스 내에서 참조됩니다(inner 클래스에서는 internal 클래스인스턴스가 아닌 inner 클래스인스턴스를 참조합니다).

public class Rhino {

    private String barry;

    public class Goat {
        public void colin() {
            System.out.println(barry);
        }
    }
}

내부 클래스에서는 포함 클래스의 이 클래스를 Rhino.this라고 부르고, 이 클래스를 사용하여 해당 멤버(예: Rhino.this.barry)를 참조할 수 있습니다.


로컬 내부 클래스

로컬 내부 클래스는 메서드 본문에 선언된 클래스입니다.이러한 클래스는 포함 메서드 내에서만 알려져 있기 때문에 인스턴스화 및 해당 멤버에게 포함 메서드 내에서만 액세스할 수 있습니다.로컬 내부 클래스 인스턴스가 포함된 메서드의 최종 로컬 변수에 연결되어 액세스할 수 있다는 것이 이득입니다.인스턴스가 포함 메서드의 최종 로컬을 사용하는 경우 변수가 범위를 벗어났더라도 변수는 인스턴스 생성 시 유지된 값을 유지합니다(이것은 사실상 Java의 조잡하고 제한된 버전의 폐쇄입니다).

로컬 내부 클래스는 클래스 또는 패키지의 멤버가 아니기 때문에 액세스레벨로 선언되지 않습니다(단, 그 멤버는 일반 클래스와 같은 액세스레벨을 가지고 있습니다).

인스턴스 메서드에서 로컬 내부 클래스가 선언되면 인스턴스 생성 시 포함 메서드에 의해 유지되는 인스턴스에 내부 클래스의 인스턴스화가 연결되므로 포함 클래스의 인스턴스 멤버는 인스턴스 내부 클래스와 동일하게 액세스할 수 있습니다.로컬 내부 클래스는 이름만으로 인스턴스화됩니다.예를 들어 로컬 내부 클래스 Cat은 새로운 것이 아니라 새로운 Cat()으로 인스턴스화됩니다.예상대로 Cat()입니다.


익명 내부 클래스

익명의 내부 클래스는 구문적으로 편리한 로컬 내부 클래스 작성 방법입니다.일반적으로 로컬 내부 클래스는 포함 메서드가 실행될 때마다 최대 한 번만 인스턴스화됩니다.따라서 로컬 내부 클래스 정의와 단일 인스턴스화를 하나의 편리한 구문 형식으로 결합할 수 있다면 좋을 것입니다.클래스의 이름을 생각해내지 않아도 좋습니다(코드에 포함되어 있는 도움이 되지 않는 이름이 적을수록 좋습니다).익명 내부 클래스는 다음 두 가지를 모두 허용합니다.

new *ParentClassName*(*constructorArgs*) {*members*}

이것은 ParentClassName을 확장하는 이름 없는 클래스의 새 인스턴스를 반환하는 식입니다.자체 생성자를 지정할 수 없습니다. 대신 단순히 슈퍼 생성자를 호출하는 생성자가 암묵적으로 제공되므로 제공된 인수가 슈퍼 생성자에 맞아야 합니다.(부모에 복수의 컨스트럭터가 있는 경우, 「심플한」컨스트럭터를 「심플한」컨스트럭터라고 부릅니다.상세하게 배울 필요가 없는 복잡한 룰에 의해서 결정됩니다.NetBeans 또는 Eclipse가 전하는 내용에 주의해 주세요).

또는, 실장하는 인터페이스를 지정할 수도 있습니다.

new *InterfaceName*() {*members*}

이러한 선언에 의해 오브젝트를 확장하고 InterfaceName을 구현하는 이름 없는 클래스의 새 인스턴스가 생성됩니다.이 경우에도 자체 컨스트럭터를 지정할 수 없습니다.이 경우 Java는 암묵적으로 no-arg, do-nothing 컨스트럭터를 제공합니다(따라서 컨스트럭터 인수는 존재하지 않습니다).

익명 내부 클래스에 생성자를 지정할 수는 없지만 이니셜라이저 블록(메서드 외부에 배치된 {} 블록)을 사용하여 원하는 설정을 수행할 수 있습니다.

익명의 내부 클래스는 단순히 하나의 인스턴스로 로컬 내부 클래스를 만드는 덜 유연한 방법임을 명확히 합니다.여러 인터페이스를 구현하거나 오브젝트 이외의 클래스를 확장하면서 인터페이스를 구현하거나 자체 생성자를 지정하는 로컬 내부 클래스를 만드는 경우 로컬 내부 클래스를 생성할 수 없습니다.

위의 답변에서는 실제 차이가 명확해지지 않았다고 생각합니다.

먼저 용어를 올바르게 이해해야 합니다.

  • 중첩 클래스는 소스 코드 수준의 다른 클래스에 Java 내부 클래스 및 정적 중첩 클래스포함된 클래스입니다.
  • 스태틱 수식자를 사용하여 선언하면 스태틱합니다.
  • 스태틱하지 않은 네스트클래스는 inner 클래스라고 불립니다.(Non-Static Nested 클래스를 사용합니다).

마틴의 대답은 지금까지 옳다.그러나 실제 질문은 다음과 같습니다.네스트된 클래스를 static으로 선언하는 목적은 무엇입니까?

클래스가 토폴로지적으로 함께 속해 있는 경우 또는 네스트된 클래스가 둘러싸인 클래스에서 배타적으로 사용되는 경우만 클래스를 함께 유지하려는 경우 정적 네스트된 클래스를 사용합니다.스태틱 네스트클래스와 다른 모든 클래스 사이에는 의미상의 차이는 없습니다.

비정적 네스트 클래스는 다른 짐승입니다.익명 내부 클래스와 마찬가지로 이러한 중첩 클래스는 사실상 폐쇄입니다.즉, 주변 범위와 주변 인스턴스를 캡처하여 액세스할 수 있도록 합니다.아마도 하나의 예가 그것을 명확하게 할 것이다.컨테이너의 다음 스터브를 참조하십시오.

public class Container {
    public class Item{
        Object data;
        public Container getContainer(){
            return Container.this;
        }
        public Item(Object data) {
            super();
            this.data = data;
        }

    }

    public static Item create(Object data){
        // does not compile since no instance of Container is available
        return new Item(data);
    }
    public Item createSubItem(Object data){
        // compiles, since 'this' Container is available
        return new Item(data);
    }
}

이 경우 하위 항목에서 상위 컨테이너에 대한 참조를 가질 수 있습니다.비 스태틱 네스트클래스를 사용하면, 이것은 작업 없이 동작합니다.에는 구문을 할 수 .Container.this.

자세한 설명은 다음과 같습니다.

컴파일러가 (비정적) 네스트클래스에 대해 생성하는 Java 바이트 코드를 보면 더 명확해질 수 있습니다.

// class version 49.0 (49)
// access flags 33
public class Container$Item {

  // compiled from: Container.java
  // access flags 1
  public INNERCLASS Container$Item Container Item

  // access flags 0
  Object data

  // access flags 4112
  final Container this$0

  // access flags 1
  public getContainer() : Container
   L0
    LINENUMBER 7 L0
    ALOAD 0: this
    GETFIELD Container$Item.this$0 : Container
    ARETURN
   L1
    LOCALVARIABLE this Container$Item L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 1
  public <init>(Container,Object) : void
   L0
    LINENUMBER 12 L0
    ALOAD 0: this
    ALOAD 1
    PUTFIELD Container$Item.this$0 : Container
   L1
    LINENUMBER 10 L1
    ALOAD 0: this
    INVOKESPECIAL Object.<init>() : void
   L2
    LINENUMBER 11 L2
    ALOAD 0: this
    ALOAD 2: data
    PUTFIELD Container$Item.data : Object
    RETURN
   L3
    LOCALVARIABLE this Container$Item L0 L3 0
    LOCALVARIABLE data Object L0 L3 2
    MAXSTACK = 2
    MAXLOCALS = 3
}

필드를 .Container this$0컨스트럭터에서 설정됩니다.컨테이너 타입의 추가 파라미터가 있어 인클로징인 인스턴스를 지정합니다.이 파라미터는 소스에 표시되지 않지만 컴파일러는 내포된 클래스에 대해 암묵적으로 생성합니다.

마틴의 예

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

(바이트 코드 단위)와 같은 호출로 컴파일됩니다.

new InnerClass(outerObject)

완전성을 위해:

어나니머스 클래스는 이름만 관련되어 있지 않아 나중에 참조할 수 없는 비정적 중첩 클래스의 완벽한 예입니다.

위의 답변 중 어느 것도 응용 프로그램 설계 측면에서 중첩 클래스와 정적 중첩 클래스의 실제 차이를 설명하지 못한다고 생각합니다.

개요

네스트된 클래스는 스태틱 또는 스태틱이 될 수 있으며, 어느 경우든 다른 클래스 내에서 정의된 클래스입니다.네스트된 클래스는 엔클로징된 클래스에만 존재해야 합니다.네스트된 클래스가 다른 클래스(엔클로징된 클래스뿐 아니라)에서 유용한 경우 최상위 클래스로 선언해야 합니다.

차이

Nonstatic Nested class : 포함된 클래스의 포함된 인스턴스와 암묵적으로 관련되어 있습니다.즉, 포함된 인스턴스의 메서드와 액세스 변수를 호출할 수 있습니다.nonstatic nested 클래스의 일반적인 용도는 어댑터 클래스를 정의하는 것입니다.

Static Nested Class : 엔클로징 클래스인스턴스에 액세스하여 메서드를 호출할 수 없습니다.따라서 네스트된 클래스가 엔클로징 클래스의 인스턴스에 액세스할 필요가 없을 때 사용해야 합니다.스태틱 네스트클래스의 일반적인 용도는 외부 객체의 컴포넌트를 구현하는 것입니다.

결론

따라서 설계 관점에서 두 가지 주요 차이점은 nonstatic nested 클래스는 컨테이너 클래스의 인스턴스에 액세스할있지만 static은 액세스할 수 없다는 것입니다.

간단히 말하면 Java는 폐쇄 기능을 제공하지 않기 때문에 기본적으로 중첩된 클래스가 필요합니다.

중첩된 클래스는 다른 둘러싸인 클래스의 본문 내부에 정의된 클래스입니다.스태틱과 비 스태틱의 두 가지 유형이 있습니다.

중 할 수 .이러한 지정자는 4개입니다.private, package, protected, public의 클래스에서는 수 클래스에서는, 「라고 에 선언할 수 없습니다.public패키지 프라이빗

내부 클래스(일명 Non-stack 클래스)는 private로 선언된 경우에도 최상위 클래스의 다른 멤버에 액세스할 수 있지만 Static nested 클래스는 최상위 클래스의 다른 멤버에 액세스할 수 없습니다.

public class OuterClass {
    public static class Inner1 {
    }
    public class Inner2 {
    }
}

Inner1입니다.또, 「inner class」는, 「 class 입니다.Inner2정적이지 않은 내면의 계층입니다.으로는 '만들다'는 수 .Inner2에서는 Outer를 할 수 .Inner1독립적으로 반대합니다.

이너 클래스는 언제 이용하실 건가요?

를 들어, '우리'가 '우리'가 되는 상황을 생각해 보세요.Class A ★★★★★★★★★★★★★★★★★」Class B이 있다, 관계가 있습니다.Class BClass A """ "" " " " " " " " " " "Class B와만 관련이 있다.Class A내부 계층이 등장합니다.

내부 클래스의 인스턴스를 만들려면 외부 클래스의 인스턴스를 만들어야 합니다.

OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();

또는

OuterClass.Inner2 inner = new OuterClass().new Inner2();

정적 내부 클래스는 언제 사용하시겠습니까?

static inner class는 둘러싸는 클래스/top class의 인스턴스와 관계가 없음을 알고 있는 경우 정의합니다.내부 클래스에서 외부 클래스의 메서드나 필드를 사용하지 않으면 공간 낭비일 뿐이므로 정적 상태로 만드십시오.

예를 들어, 스태틱네스트 클래스의 오브젝트를 작성하려면 다음 구문을 사용합니다.

OuterClass.Inner1 nestedObject = new OuterClass.Inner1();

스태틱 네스트클래스의 장점은 포함하는 클래스/톱 클래스의 오브젝트가 동작하지 않아도 된다는 것입니다.이를 통해 응용 프로그램에서 런타임에 생성하는 개체 수를 줄일 수 있습니다.

Java inner 클래스와 static nested 클래스의 주요 차이점과 유사점을 다음에 나타냅니다.

도움이 됐으면 좋겠다!

내부 클래스

  • 인스턴스정적 메서드 및 필드 모두에 외부 클래스에 액세스할 수 있습니다.
  • 클래스가 포함된 인스턴스와 관련되어 있으므로 먼저 클래스를 인스턴스화하려면 외부 클래스의 인스턴스가 필요합니다(새로운 키워드 place에 주의).

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
    
  • 정적 멤버 자체를 정의할 수 없습니다.

  • 클래스 또는 인터페이스 선언을 가질 수 없습니다.

스태틱 네스트 클래스

  • 외부 클래스 인스턴스 메서드 또는 필드에 액세스할 수 없습니다.

  • 클래스 인스턴스(instance of class)와 연관되지 않음(instance of class)을 인스턴스화하려면:

    OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
    

유사점들

  • 양쪽 내부 클래스는 외부 클래스의 개인 필드 및 메서드에도 액세스할 수 있습니다.
  • 또한 Outer 클래스는 내부 클래스의 개인 필드 및 메서드에 액세스할 수 있습니다.
  • 두 클래스 모두 개인, 보호됨 또는 공용 액세스 수식자를 가질 수 있습니다.

네스트된 클래스를 사용하는 이유

Oracle 문서에는 다음과 같은 몇 가지 이유가 있습니다(전체 문서).

  • 이는 한 곳에서만 사용되는 클래스를 논리적으로 그룹화하는 방법입니다.클래스가 다른 클래스에만 유용한 경우 해당 클래스에 포함시키고 두 클래스를 함께 유지하는 것이 논리적입니다.이러한 「헬퍼 클래스」를 네스트 하면, 패키지의 효율이 향상됩니다.

  • 캡슐화가 향상됩니다.A와 B의 두 가지 최상위 클래스(A와 B)를 고려합니다. 여기서 B는 A의 멤버에 액세스해야 하며, 그렇지 않으면 비공개로 선언될 수 있습니다.클래스 A 내에서 클래스 B를 숨김으로써 A의 멤버를 비공개로 선언하고 B를 액세스 할 수 있습니다.또, B 자체를 외부로부터 숨길 수 있다.

  • 보다 읽기 쉽고 유지보수가 용이한 코드로 이어질 수 있습니다.최상위 클래스 내에 작은 클래스를 중첩하면 코드가 사용되는 위치에 더 가깝게 배치됩니다.

나는 일반적으로 다음과 같은 관례를 따르고 있다고 생각한다.

  • 최상위 클래스 내의 정적 클래스는 중첩된 클래스입니다.
  • 최상위 클래스 내의 non static 클래스는 내부 클래스이며, 다음 두 가지 형식이 더 있습니다.
    • 로컬 클래스 - 메서드 또는 컨스트럭터 본문과 같이 블록 내에서 선언된 명명된 클래스
    • anonymous class - 식과 문에 인스턴스가 생성되는 이름 없는 클래스

밖에 기억해야 할 은 다음과 같습니다.

  • 상위 수준 클래스와 정적 중첩 클래스는 정적 중첩 클래스의 경우 Outer [parent]클래스의 개인 정적 필드/메서드를 스태틱하게 참조할 수 있다는 점을 제외하고 의미론적으로 동일합니다.

  • 내부 클래스는 Outer [parent]클래스의 둘러싸인 인스턴스의 인스턴스 변수에 액세스할 수 있습니다.단, 모든 inner 클래스에 둘러싸인 인스턴스가 있는 것은 아닙니다.예를 들어 스태틱인테셜라이저 블록에서 사용되는 어나니머스 클래스 등 스태틱콘텍스트의 inner 클래스는 그렇지 않습니다.

  • 기본적으로 어나니머스 클래스는 부모 클래스를 확장하거나 부모 인터페이스를 구현합니다.다른 클래스를 확장하거나 인터페이스를 구현하는 추가 구문은 없습니다.그렇게,

    • new YourClass(){};「」를 의미합니다.class [Anonymous] extends YourClass {}
    • new YourInterface(){};「」를 의미합니다.class [Anonymous] implements YourInterface {}

어떤 질문을 언제 사용할지 아직 미해결인 것 같습니다.그건 주로 어떤 시나리오를 다루느냐에 따라 다르지만, @jrudolph의 답변을 읽으면 어떤 결정을 내리는 데 도움이 될 수 있습니다.

중첩 클래스: 클래스 내부

종류:

  1. 스태틱 네스트 클래스
  2. Non-static nested 클래스 [Inner 클래스]

차이점:

Non-static nested 클래스 [Inner 클래스]

non-static nested 클래스에서는 inner 클래스의 객체가 outer 클래스의 객체 내에 존재합니다.따라서 외부 클래스의 데이터 멤버는 내부 클래스에 액세스할 수 있습니다.그래서 내부 클래스의 오브젝트를 만들려면 먼저 외부 클래스의 오브젝트를 만들어야 합니다.

outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass(); 

스태틱 네스트 클래스

정적 중첩 클래스 개체에서는 "static"이라는 단어가 개체를 만들 필요가 없음을 나타내기 때문에 내부 클래스의 개체가 필요하지 않습니다.

class outerclass A {
    static class nestedclass B {
        static int x = 10;
    }
}

x 에 액세스 하려면 , 다음의 inside 메서드를 써 주세요.

  outerclass.nestedclass.x;  i.e. System.out.prinltn( outerclass.nestedclass.x);

내부 클래스의 인스턴스는 외부 클래스의 인스턴스를 만들 때 생성됩니다.따라서 내부 클래스의 멤버 및 메서드는 외부 클래스의 인스턴스(개체) 멤버 및 메서드에 액세스할 수 있습니다.외부 클래스의 인스턴스가 범위를 벗어나면 내부 클래스의 인스턴스도 더 이상 존재하지 않습니다.

정적 중첩 클래스에 구체적인 인스턴스가 없습니다.처음 사용할 때만 로드됩니다(정적인 방식과 같음).완전히 독립된 엔티티로 메서드와 변수는 외부 클래스의 인스턴스에 액세스할 수 없습니다.

스태틱 네스트 클래스는 외부 객체와 결합되지 않으며 더 빠르고 힙/스택 메모리를 사용하지 않습니다. 이러한 클래스의 인스턴스를 만들 필요가 없기 때문입니다.따라서 경험의 법칙은 가능한 한 제한된 범위(private > = class > = protected > = public)로 스태틱네스트 클래스를 정의한 후 ("static" 식별자를 제거하여) 내부 클래스로 변환하고 필요한 경우 스코프를 느슨하게 하는 것입니다.

그 용어들은 서로 바꿔서 사용된다.이 클래스에 대해 매우 현학적인 설명을 원하는 경우 "nasted class"를 정의하여 둘러싸인 인스턴스가 없는 정적 내부 클래스를 참조할 수 있습니다.코드에는 다음과 같은 것이 있습니다.

public class Outer {
    public class Inner {}

    public static class Nested {}
}

하지만 그것은 널리 받아들여지는 정의는 아니다.

네스트된 스태틱클래스의 사용에 대해서는, 특정의 상황에서 도움이 되는 미묘한 점이 있습니다.

정적 속성은 클래스가 생성자를 통해 인스턴스화되기 전에 인스턴스화되는 반면 중첩된 정적 클래스 내부의 정적 속성은 클래스 생성자가 호출될 때까지 인스턴스화되지 않습니다. 적어도 속성이 '최종'으로 표시되더라도 속성이 처음 참조될 때까지 인스턴스화되지 않습니다.

다음 예를 생각해 보겠습니다.

public class C0 {

    static C0 instance = null;

    // Uncomment the following line and a null pointer exception will be
    // generated before anything gets printed.
    //public static final String outerItem = instance.makeString(98.6);

    public C0() {
        instance = this;
    }

    public String makeString(int i) {
        return ((new Integer(i)).toString());
    }

    public String makeString(double d) {
        return ((new Double(d)).toString());
    }

    public static final class nested {
        public static final String innerItem = instance.makeString(42);
    }

    static public void main(String[] argv) {
        System.out.println("start");
        // Comment out this line and a null pointer exception will be
        // generated after "start" prints and before the following
        // try/catch block even gets entered.
        new C0();
        try {
            System.out.println("retrieve item: " + nested.innerItem);
        }
        catch (Exception e) {
            System.out.println("failed to retrieve item: " + e.toString());
        }
        System.out.println("finish");
    }
}

비록 'nated'와 'internal'이 있더라도Item'은 둘 다 'static final'로 선언됩니다.nested.innerItem 설정은 클래스가 인스턴스화될 때까지(또는 적어도 네스트된 정적 항목이 처음 참조될 때까지) 수행되지 않습니다. 이는 위에서 언급한 행에 대한 주석 및 주석 해제를 통해 확인할 수 있습니다.'외부'에 대해서도 마찬가지입니다.아이템'

적어도 Java 6.0에서는 이렇게 볼 수 있습니다.

인스턴스를 만드는 경우 비 스태틱 내부 클래스의 인스턴스는 정의된 외부 클래스의 개체를 참조하여 생성됩니다.즉, 예를 들어 설명하겠습니다.그러나 정적 내부 클래스의 인스턴스는 외부 클래스의 객체가 아닌 외부 클래스의 참조를 사용하여 생성됩니다.이것은 그것이 포함시킬 만한 예가 없다는 것을 의미합니다.

예를 들어 다음과 같습니다.

class A
{
  class B
  {
    // static int x; not allowed here…..    
  }
  static class C
  {
    static int x; // allowed here
  }
}

class Test
{
  public static void main(String… str)
  {
    A o=new A();
    A.B obj1 =o.new B();//need of inclosing instance

    A.C obj2 =new A.C();

    // not need of reference of object of outer class….
  }
}

여기에 덧붙일 것은 별로 없다고 생각합니다만, 대부분의 답변은 정적 중첩 클래스와 내부 클래스의 차이를 완벽하게 설명하고 있습니다.그러나 중첩된 클래스와 내부 클래스를 사용할 때는 다음 문제를 고려하십시오.몇 가지 답변에서 설명한 바와 같이 내부 클래스는 인클로징 클래스의 인스턴스와 그 인클로징 클래스의 인스턴스가 없으면 인스턴스화할 수 없습니다.즉, 인클로징 클래스의 인스턴스에 대한 포인터를 보유하는 것을 의미합니다.이는 GC가 인클로징 클래스를 가비지할 수 없기 때문에 메모리 오버플로우 또는 스택오버플로우 예외를 초래할 수 있습니다.y는 더 이상 사용되지 않습니다.이를 명확히 하기 위해 다음 코드를 확인합니다.

public class Outer {


    public  class Inner {

    }


    public Inner inner(){
        return new Inner();
    }

    @Override
    protected void finalize() throws Throwable {
    // as you know finalize is called by the garbage collector due to destroying an object instance
        System.out.println("I am destroyed !");
    }
}


public static void main(String arg[]) {

    Outer outer = new Outer();
    Outer.Inner inner = outer.new Inner();

    // out instance is no more used and should be garbage collected !!!
    // However this will not happen as inner instance is still alive i.e used, not null !
    // and outer will be kept in memory until inner is destroyed
    outer = null;

    //
    // inner = null;

    //kick out garbage collector
    System.gc();

}

// inner = null;이 프로그램은 "는 파괴되었다!"라고 외치겠지만, 이 코멘트를 계속 달면 그렇게 되지 않을 것이다.
그 이유는 흰색 내부 인스턴스가 아직 참조되고 있기 때문에 GC가 이를 수집할 수 없고 외부 인스턴스를 참조(포인터 있음)하기 때문에 수집되지 않기 때문입니다.프로젝트에 이러한 오브젝트가 충분히 있어 메모리가 부족할 수 있습니다.
인스턴스 관련이 아니라 클래스 관련이기 때문에 내부 클래스 인스턴스에 대한 포인트를 보유하지 않는 정적 내부 클래스와 비교합니다.위의 프로그램은 Inner 클래스를 정적으로 만들고 다음을 사용하여 인스턴스화하면 "I destrove!"를 인쇄할 수 있습니다.Outer.Inner i = new Outer.Inner();

중첩 클래스는 매우 일반적인 용어입니다. 최상위 수준이 아닌 모든 클래스는 중첩된 클래스입니다.내부 클래스는 비 스태틱네스트 클래스입니다Joseph Darcy는 Nested, Inner, MemberTop-Level Class에 대한 매우 좋은 설명을 썼습니다.

음... 내부 클래스는 중첩된 클래스입니다...익명의 수업과 내부 수업을 말하는 건가요?

편집: 실제로 내부 vs 익명성을 의미했다면...내부 클래스는 다음과 같은 클래스 내에서 정의된 클래스입니다.

public class A {
    public class B {
    }
}

반면 익명 클래스는 익명으로 정의된 클래스의 확장이므로 다음과 같이 실제 "클래스"는 정의되지 않습니다.

public class A {
}

A anon = new A() { /* you could change behavior of A here */ };

추가 편집:

위키피디아는 자바에 차이가 있다고 주장하지만, 저는 자바와 8년 동안 일했습니다.그런 차이는 처음 듣습니다.그 주장을 뒷받침할 언급이 없다는 것은 말할 것도 없고...마지막으로 inner 클래스는 클래스 내에서 정의된 클래스(스태틱 여부에 관계없이)이며, nested는 같은 것을 의미하는 다른 용어일 뿐입니다.

정적 중첩 클래스와 비정적 중첩 클래스 사이에는 미묘한 차이가 있습니다.기본적으로 non-static inner class는 instance 필드 및 엔클로징 클래스의 메서드에 암묵적으로 액세스할 수 있습니다(이러한 클래스는 정적 컨텍스트에서 구성할 수 없으며 컴파일러 오류가 됩니다).한편, 스태틱네스트 클래스는 인스턴스 필드 및 메서드에 암묵적으로 액세스할 수 없으며 정적 컨텍스트에서 구성할 수 있습니다.

Java 및/또는 Nested Class에 초보자 대상 학습자

중 하나입니다.
클래스1 스태틱 네스트 클래스
2. Non Static Nested 클래스.(일명 이너 클래스) => 꼭 기억해 주세요


1. 내부 클래스
§:

class OuterClass  {
/*  some code here...*/
     class InnerClass  {  }
/*  some code here...*/
}


내부 클래스는 중첩된 클래스의 하위 집합입니다.

  • inner 클래스는 중첩된 클래스의 특정 유형입니다.
  • 내부 클래스는 중첩된 클래스의 하위 집합입니다.
  • 내부 클래스도 중첩된 클래스라고 할 수 있지만 중첩된 클래스도 내부 클래스라고 할 수는 없습니다.

이너 클래스의 스페셜리티:

  • 내부 클래스의 인스턴스는 외부 클래스의 모든 멤버에 접근할 수 있으며, 심지어 "프라이빗"으로 표시된 멤버도 마찬가지입니다.


클래스 2. 다음 중 하나:
§:

class EnclosingClass {
  static class Nested {
    void someMethod() { System.out.println("hello SO"); }
  }
}

케이스 1: 비폐쇄 클래스에서 스태틱네스트 클래스 인스턴스화

class NonEnclosingClass {

  public static void main(String[] args) {
    /*instantiate the Nested class that is a static
      member of the EnclosingClass class:
    */

    EnclosingClass.Nested n = new EnclosingClass.Nested(); 
    n.someMethod();  //prints out "hello"
  }
}

케이스 2: 둘러싸인 클래스에서 스태틱네스트된 클래스의 인스턴스화

class EnclosingClass {

  static class Nested {
    void anotherMethod() { System.out.println("hi again"); } 
  }

  public static void main(String[] args) {
    //access enclosed class:

    Nested n = new Nested(); 
    n.anotherMethod();  //prints out "hi again"
  }

}

스태틱 클래스의 스페셜리티:

  • 스태틱 내부 클래스는 외부 클래스의 스태틱멤버에만 액세스 할 수 있고 비 스태틱멤버에는 액세스 할 수 없습니다.

★★★★
질문:Java에서 inner 클래스와 static nested 클래스의 주요 차이점은 무엇입니까?
답변: 위에서 언급한 각 클래스의 세부 사항을 살펴보십시오.

Java의 inner 클래스와 nested static 클래스는 모두 다른 클래스 내에서 선언된 클래스이며 Java에서는 최상위 클래스라고 합니다.Java 용어에서는 nested class static을 선언하면 Java에서는 nested static 클래스라고 불리는 반면 nonstatic nested 클래스는 단순히 inner 클래스라고 불립니다.

Java에서 Inner Class란 무엇입니까?

최상위 수준이 아니거나 다른 클래스 내에서 선언된 클래스는 중첩된 클래스라고 하며, 이러한 중첩된 클래스 중 스태틱하지 않은 클래스는 Java에서 내부 클래스라고 합니다. Java에는 세 가지 종류의 내부 클래스가 있습니다.

클래스 -메서드 됩니다.1) 로컬 내부 클래스 - 로컬 내부 클래스 - 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 。
2) 익명 내부 클래스 - 참조할 이름이 없고 생성된 장소에서 초기화된 클래스입니다.
- - - 부재외부 - 부재외부 - 부재외부 - 부재외부 - 부재외부 - 부재외부 - 부재외부 - 부재외부 - 부재외부 - 부재외부) 부재외부 - 부재외부 - - 부재외부외부

public class InnerClassTest {
    public static void main(String args[]) {      
        //creating local inner class inside method i.e. main() 
        class Local {
            public void name() {
                System.out.println("Example of Local class in Java");

            }
        }      
        //creating instance of local inner class
        Local local = new Local();
        local.name(); //calling method from local inner class

        //Creating anonymous inner class in Java for implementing thread
        Thread anonymous = new Thread(){
            @Override
            public void run(){
                System.out.println("Anonymous class example in java");
            }
        };
        anonymous.start();

        //example of creating instance of inner class
        InnerClassTest test = new InnerClassTest();
        InnerClassTest.Inner inner = test.new Inner();
        inner.name(); //calling method of inner class
    }

     //Creating Inner class in Java
    private class Inner{
        public void name(){
            System.out.println("Inner class example in java");
        }
    }
}

Java에서 nested static class란 무엇입니까?

네스트된 스태틱클래스는 클래스 내에서 멤버로 선언되어 스태틱하게 되는 다른 클래스입니다.네스트된 스태틱클래스도 외부 클래스의 멤버로 선언되어 다른 멤버와 마찬가지로 프라이빗, 퍼블릭 또는 보호를 할 수 있습니다.내부 클래스보다 중첩된 스태틱클래스의 주요 이점 중 하나는 중첩된 스태틱클래스의 인스턴스가 외부 클래스의 둘러싸인 인스턴스에 부가되지 않는다는 것입니다.또한 Java에서 중첩된 정적 클래스의 인스턴스를 만드는Outer 클래스의 인스턴스가 필요하지 않습니다.

1) Private를 포함한 외부 클래스의 정적 데이터 멤버에 접근할 수 있다.
2) 정적 중첩 클래스는 정적(인스턴스)이 아닌 데이터 멤버 또는 메서드에 액세스할 수 없습니다.

public class NestedStaticExample {
    public static void main(String args[]){  
        StaticNested nested = new StaticNested();
        nested.name();
    }  
    //static nested class in java
    private static class StaticNested{
        public void name(){
            System.out.println("static nested class example in java");
        }
    }
}

참조: Java의 내부 클래스중첩된 정적 클래스(예)

위의 답변 중 어느 것도 응용 프로그램 설계 측면에서 중첩 클래스와 정적 중첩 클래스의 차이를 제대로 보여주는 것은 아니라고 생각합니다.또한 정적 중첩 클래스와 내부 클래스의 주요 차이점은 외부 클래스 인스턴스 필드에 액세스할 수 있다는 것입니다.

다음 두 가지 예를 살펴보겠습니다.

정적 네스트 클래스:스태틱 네스트클래스를 사용하는 좋은 예로는 빌더 패턴(https://dzone.com/articles/design-patterns-the-builder-pattern)이 있습니다.

BankAccount에는 주로 다음과 같은 이유로 스태틱네스트 클래스를 사용합니다.

  1. 외부 클래스보다 먼저 정적 네스트 클래스 인스턴스를 만들 수 있습니다.

  2. 빌더 패턴에서 빌더는 BankAccount 작성에 사용되는 도우미 클래스입니다.

  3. 은행 계좌Builder는 BankAccount에만 연결되어 있습니다.BankAccount와 관련된 다른 클래스는 없습니다.빌더그래서 이름 표기법을 사용하지 말고 같이 정리하는 것이 좋습니다.
public class BankAccount {

    private long accountNumber;
    private String owner;
    ...

    public static class Builder {

    private long accountNumber;
    private String owner;
    ...

    static public Builder(long accountNumber) {
        this.accountNumber = accountNumber;
    }

    public Builder withOwner(String owner){
        this.owner = owner;
        return this; 
    }

    ...
    public BankAccount build(){
            BankAccount account = new BankAccount(); 
            account.accountNumber = this.accountNumber;
            account.owner = this.owner;
            ...
            return account;
        }
    }
}

내부 클래스:내부 클래스의 일반적인 용도는 이벤트핸들러를 정의하는 것입니다.https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html

MyClass에서는 주로 다음과 같은 이유로 내부 클래스를 사용합니다.

  1. 내부 클래스 MyAdapter는 외부 클래스 멤버에 액세스해야 합니다.

  2. 이 예에서 MyAdapter는 MyClass에만 연결됩니다.MyAdapter와 관련된 다른 클래스는 없습니다.따라서 이름 표기법을 사용하지 않고 함께 정리하는 것이 좋다.

public class MyClass extends Applet {
    ...
        someObject.addMouseListener(new MyAdapter());
    ...
    class MyAdapter extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            ...// Event listener implementation goes here...
            ...// change some outer class instance property depend on the event
        }
    }
}

나는 여기 사람들이 포스터에 주목해야 한다고 생각한다: Static Nest Class는 단지 첫 번째 내부 클래스일 뿐이다.예를 들어 다음과 같습니다.

 public static class A {} //ERROR

 public class A {
     public class B {
         public static class C {} //ERROR
     }
 }

 public class A {
     public static class B {} //COMPILE !!!

 }

요약하면 정적 클래스는 포함된 클래스에 따라 달라지지 않습니다.그래서 그들은 보통 수업에서는 할 수 없다.(일반 클래스에는 인스턴스가 필요하기 때문입니다).

클래스 내에서 스태틱멤버 클래스를 선언하면 톱레벨 네스트클래스 또는 스태틱 네스트클래스라고 불립니다다음과 같이 설명할 수 있습니다.

class Test{
    private static int x = 1;
        static class A{
        private static int y = 2;
        public static int getZ(){
            return B.z+x;
        }
    }
    static class B{
        private static int z = 3;
        public static int getY(){
            return A.y;
        }
    }
}

class TestDemo{
     public static void main(String[] args){
        Test t = new Test();
        System.out.println(Test.A.getZ());
        System.out.println(Test.B.getY());
    }
}

클래스 내에서 비스타틱멤버 클래스를 선언하면 내부 클래스라고 불립니다.내부 클래스는 다음과 같이 시연할 수 있습니다.

    class Test{
        private int i = 10;
        class A{
            private int i =20;
            void display(){
            int i = 30;
            System.out.println(i);
            System.out.println(this.i);
            System.out.println(Test.this.i);
        }
    }
}

도표

여기에 이미지 설명 입력

「 」의 주된 static nested ★★★★★★★★★★★★★★★★★」non-static nested는 그 'class'입니다.static nested 에는, 스태틱하지 않은 외부 클래스 멤버에 액세스 할 수 없습니다.

다음으로 의 예를 제시하겠습니다.static nested class ★★★★★★★★★★★★★★★★★」inner class:

OuterClass.java

public class OuterClass {
     private String someVariable = "Non Static";

     private static String anotherStaticVariable = "Static";  

     OuterClass(){

     }

     //Nested classes are static
     static class StaticNestedClass{
        private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable"; 

        //can access private variables declared in the outer class
        public static void getPrivateVariableofOuterClass(){
            System.out.println(anotherStaticVariable);
        }
     }

     //non static
     class InnerClass{

         //can access private variables of outer class
         public String getPrivateNonStaticVariableOfOuterClass(){
             return someVariable;
         }
     }

     public static void accessStaticClass(){
         //can access any variable declared inside the Static Nested Class 
         //even if it private
         String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable; 
         System.out.println(var);
     }

}

Outer Class Test:

public class OuterClassTest {
    public static void main(String[] args) {

        //access the Static Nested Class
        OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();

        //test the private variable declared inside the static nested class
        OuterClass.accessStaticClass();
        /*
         * Inner Class Test
         * */

        //Declaration

        //first instantiate the outer class
        OuterClass outerClass = new OuterClass();

        //then instantiate the inner class
        OuterClass.InnerClass innerClassExample =  outerClass. new InnerClass();

        //test the non static private variable
        System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass()); 

    }

}

우선 Static 클래스라는 클래스는 없습니다.내부 클래스와 함께 사용하는 정적 수식자(Nested Class라고 함)에서는 외부 클래스의 정적 멤버라고 합니다.즉, 외부 클래스의 인스턴스가 없어도 다른 정적 멤버와 마찬가지로 액세스할 수 있습니다.(이것은 원래 스태틱의 이점입니다).

Nested 클래스와 일반 Inner 클래스의 차이는 다음과 같습니다.

OuterClass.InnerClass inner = new OuterClass().new InnerClass();

먼저 외부 클래스를 인스턴스화한 다음 내부로 접속할 수 있습니다.

그러나 클래스가 Nested일 경우 구문은 다음과 같습니다.

OuterClass.InnerClass inner = new OuterClass.InnerClass();

static 키워드 표준 구현으로 static 구문을 사용합니다.

Java 프로그래밍 언어를 사용하면 다른 클래스 내에서 클래스를 정의할 수 있습니다.이러한 클래스를 네스트 클래스라고 하며, 다음과 같이 나타냅니다.

class OuterClass {
...
class NestedClass {
    ...
    }
}

네스트 클래스는 스태틱과 비 스태틱의 두 가지 카테고리로 나뉩니다.스태틱으로 선언된 중첩 클래스를 스태틱 중첩 클래스라고 합니다.스태틱하지 않은 네스트 클래스는 내부 클래스라고 불립니다.주의할 점은 비 스태틱네스트 클래스(내부 클래스)는 프라이빗으로 선언된 경우에도 엔클로저 클래스의 다른 멤버에 액세스 할 수 있다는 것입니다.스태틱 네스트 클래스는 스태틱한 경우에만 엔클로징 클래스의 다른 멤버에 액세스할 수 있습니다.외부 클래스의 스태틱하지 않은 멤버에는 액세스할 수 없습니다.클래스 메서드 및 변수와 마찬가지로 스태틱네스트 클래스는 외부 클래스와 관련지어집니다.예를 들어, 스태틱네스트 클래스의 오브젝트를 작성하려면 다음 구문을 사용합니다.

OuterClass.StaticNestedClass nestedObject =
 new OuterClass.StaticNestedClass(); 

내부 클래스를 인스턴스화하려면 먼저 외부 클래스를 인스턴스화해야 합니다.그런 다음 다음 다음 구문을 사용하여 외부 개체 내에 내부 개체를 만듭니다.

OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();

중첩 클래스를 사용하는 이유

  1. 이는 한 곳에서만 사용되는 클래스를 논리적으로 그룹화하는 방법입니다.
  2. 캡슐화가 향상됩니다.
  3. 보다 읽기 쉽고 유지보수가 쉬운 코드로 이어질 수 있습니다.

출처: Java™ 튜토리얼 - 중첩된 클래스

이미 언급한 것과 더불어 중첩된 클래스에 외부 클래스에서만 액세스할 수 있는 메서드가 있는 경우도 있습니다.이는 외부 클래스가 중첩된 클래스의 개인 생성자, 필드 및 메서드에 액세스할 수 있기 때문에 가능합니다.

에서는 음음 in in in in 。Bank 할 수 Bank.CreditCard 있으며 컨스트럭터를 하여 현행 할 수 setLimit(...) " " " " of method of of of of"Bank.CreditCard ( 변수에 limit이 경우에도 유효합니다).다른 클래스에서는 의 퍼블릭 메서드만Bank.CreditCard을 사용하다

public class Bank {

    // maximum limit as per current bank policy
    // is subject to change
    private int maxLimit = 7000;

    // ------- PUBLIC METHODS ---------

    public CreditCard issueCard(
            final String firstName,
            final String lastName
    ) {
        final String number = this.generateNumber();
        final int expiryDate = this.generateExpiryDate();
        final int CVV = this.generateCVV();
        return new CreditCard(firstName, lastName, number, expiryDate, CVV);
    }


    public boolean setLimit(
            final CreditCard creditCard,
            final int limit
    ) {
        if (limit <= this.maxLimit) {    // check against current bank policy limit
            creditCard.setLimit(limit);  // access private method Bank.CreditCard.setLimit(int)
            return true;
        }
        return false;
    }

    // ------- PRIVATE METHODS ---------

    private String generateNumber() {
        return "1234-5678-9101-1123";   // the numbers should be unique for each card
    }


    private int generateExpiryDate() {
        return 202405;                  // date is YYYY=2024, MM=05
    }


    private int generateCVV() {
        return 123;                     // is in real-life less predictable
    }


    // ------- PUBLIC STATIC NESTED CLASS ---------

    public static final class CreditCard {
        private final String firstName;
        private final String lastName;
        private final String number;
        private final int expiryDate;
        private final int CVV;

        private int balance;
        private int limit = 100; // default limit

        // the constructor is final but is accessible from outer class
        private CreditCard(
                final String firstName,
                final String lastName,
                final String number,
                final int expiryDate,
                final int CVV
        ) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.number = number;
            this.expiryDate = expiryDate;
            this.CVV = CVV;
        }

        // ------- PUBLIC METHODS ---------

        public String getFirstName() {
            return this.firstName;
        }

        public String getLastName() {
            return this.lastName;
        }

        public String getNumber() {
            return this.number;
        }

        public int getExpiryDate() {
            return this.expiryDate;
        }

        // returns true if financial transaction is successful
        // otherwise false
        public boolean charge(final int amount) {
            final int newBalance = this.balance - amount;
            if (newBalance < -this.limit) {
                return false;
            }
            this.balance = newBalance;
            return true;
        }

        // ------- PRIVATE METHODS ---------

        private int getCVV() {
            return this.CVV;
        }

        private int getBalance() {
            return this.balance;
        }

        private void setBalance(final int balance) {
            this.balance = balance;
        }

        private int getLimit() {
            return limit;
        }

        private void setLimit(final int limit) {
            this.limit = limit;
        }
    }
}

스태틱 중첩 클래스는 정의된 클래스의 PRIVATE 클래스 수준 스태틱 변수에 액세스합니다.아키텍처의 관점에서 보면(즉, 서비스에 중첩된 정적 도우미 클래스를 사용하는 서비스 로케이터 패턴), OP가 내부 클래스와 함께 존재하는 이유를 파악하는 데 도움이 될 수 있습니다.

차이점은 스태틱한 네스트된 클래스 선언을 둘러싸는 클래스 외부에서 인스턴스화할 수 있다는 점입니다.

내부 클래스라고도 하는 정적 클래스 선언이 아닌 중첩된 클래스 선언이 있는 경우 Java는 폐쇄 클래스를 통해서만 인스턴스화할 수 있습니다.내부 클래스에서 생성된 객체는 외부 클래스에서 생성된 객체에 연결되므로 내부 클래스는 외부 필드를 참조할 수 있습니다.

단, 스태틱한 경우 링크가 존재하지 않고 외부 필드에 액세스할 수 없으므로(다른 개체와 마찬가지로 일반 참조를 통해서만) 중첩된 클래스를 인스턴스화할 수 있습니다.

자바 코드에서 발생할 수 있는 다양한 수정 및 오류 시나리오를 보여드렸습니다.

    class Outter1 {

        String OutStr;

        Outter1(String str) {
            OutStr = str;
        }

        public void NonStaticMethod(String st)  {

            String temp1 = "ashish";
            final String  tempFinal1 = "ashish"; 

            //  below static attribute not permitted
            // static String tempStatic1 = "static";    

            //  below static with final attribute not permitted         
            // static final String  tempStatic1 = "ashish";  

            // synchronized keyword is not permitted below          
            class localInnerNonStatic1 {            

                synchronized    public void innerMethod(String str11) {
                    str11 = temp1 +" sharma";
                    System.out.println("innerMethod ===> "+str11);
                }

                /* 
        //  static method with final not permitted
          public static void innerStaticMethod(String str11) { 

                    str11 = temp1 +" india";
                    System.out.println("innerMethod ===> "+str11);
                }*/
            }

            // static class not permitted below
            //  static class localInnerStatic1 {   }                            

        }

        public static  void StaticMethod(String st)     {

            String temp1 = "ashish";
            final String  tempFinal1 = "ashish"; 

            // static attribute not permitted below
            //static String tempStatic1 = "static";     

            //  static with final attribute not permitted below
            // static final String  tempStatic1 = "ashish";                         

            class localInnerNonStatic1 {
                public void innerMethod(String str11) {
                    str11 = temp1 +" sharma";
                    System.out.println("innerMethod ===> "+str11);
                }

                /*
    // static method with final not permitted
    public static void innerStaticMethod(String str11) {  
                    str11 = temp1 +" india";
                    System.out.println("innerMethod ===> "+str11);
                }*/
            }

            // static class not permitted below
            //  static class localInnerStatic1 {   }    

        }

        // synchronized keyword is not permitted
        static  class inner1 {          

            static String  temp1 = "ashish";
            String  tempNonStatic = "ashish";
            // class localInner1 {

            public void innerMethod(String str11) {
                str11 = temp1 +" sharma";
                str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }

            public static void innerStaticMethod(String str11) {
                //  error in below step
                str11 = temp1 +" india";    
                //str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }
            //}
        }

        //synchronized keyword is not permitted below
        class innerNonStatic1 {             

//This is important we have to keep final with static modifier in non
// static innerclass below
            static final String  temp1 = "ashish";  
            String  tempNonStatic = "ashish";
            // class localInner1 {

            synchronized    public void innerMethod(String str11) {
                tempNonStatic = tempNonStatic +" ...";
                str11 = temp1 +" sharma";
                str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }

            /*
            //  error in below step
            public static void innerStaticMethod(String str11) {   
                            //  error in below step
                            // str11 = tempNonStatic +" india";                     
                            str11 = temp1 +" india";
                            System.out.println("innerMethod ===> "+str11);
                        }*/
                    //}
                }
    }

언급URL : https://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class

반응형