Java内部类和静态嵌套类

发布于 2024-07-05 10:06:21 字数 52 浏览 7 评论 0原文

Java 中内部类和静态嵌套类的主要区别是什么? 设计/实施在选择其中之一时发挥作用吗?

What is the main difference between an inner class and a static nested class in Java? Does design / implementation play a role in choosing one of these?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(28

甜妞爱困 2024-07-12 10:06:21

来自 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教程 - 嵌套类

为了完整起见,请注意,还有 内部类没有封闭实例

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

这里,new A() { ... } 是一个 >在静态上下文中定义的内部类并且没有封闭实例。

From the Java Tutorial:

Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.

Static nested classes are accessed using the enclosing class name:

OuterClass.StaticNestedClass

For example, to create an object for the static nested class, use this syntax:

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

Objects that are instances of an inner class exist within an instance of the outer class. Consider the following classes:

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

An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:

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

see: Java Tutorial - Nested Classes

For completeness note that there is also such a thing as an inner class without an enclosing instance:

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

Here, new A() { ... } is an inner class defined in a static context and does not have an enclosing instance.

原来分手还会想你 2024-07-12 10:06:21

Java 教程说

术语:嵌套类是
分为两类:静态
并且非静态。 嵌套类
被声明为静态的,只是简单地调用
静态嵌套类。 非静态
嵌套类称为内部类
类。

一般来说,大多数程序员可以互换使用术语“嵌套”和“内部”,但我将使用正确的术语“嵌套类”,它涵盖了内部和静态。

类可以无限嵌套,例如,类 A 可以包含类 B,类 B 包含类 C,类 C 又包含类 D,等等。但是,多于一层的类嵌套很少见,因为这通常是糟糕的设计。

创建嵌套类有以下三个原因:

  • 组织:有时将一个类排序到另一个类的命名空间中似乎是最明智的,特别是当它不会在任何其他上下文
  • 访问中使用时:嵌套类对其包含类的变量/字段(具体哪些变量/字段取决于嵌套类的类型,无论是内部类还是静态类)。
  • 方便:必须为每个新类型创建一个新文件,这又很麻烦,尤其是当该类型仅在一个上下文中使用时。Java

中有四种嵌套类。 简而言之,它们是:

  • 静态类:声明为另一个类的静态成员
  • 内部类:声明为另一个类的实例成员
  • 本地内部类 strong>:在另一个类的实例方法中声明
  • 匿名内部类:类似于本地内部类,但写成一个返回一次性对象的表达式

让我详细说明一下。

静态类

静态类是最容易理解的类型,因为它们与包含类的实例无关。

静态类是声明为另一个类的静态成员的类。 就像其他静态成员一样,这样的类实际上只是一个使用包含类作为其命名空间的挂钩,例如Goat声明为类<的静态成员pizza 包中的 em>Rhino 的名称为 pizza.Rhino.Goat

package pizza;

public class Rhino {

    ...

    public static class Goat {
        ...
    }
}

坦率地说,静态类是一个非常没有价值的功能,因为类已经被包划分为命名空间。 创建静态类的唯一真正可以想象的原因是这样的类可以访问其包含类的私有静态成员,但我发现这是静态类功能存在的一个相当蹩脚的理由。

内部类

内部类是声明为另一个类的非静态成员的类:

package pizza;

public class Rhino {

    public class Goat {
        ...
    }

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

与静态类一样,内部类通过其包含的类名进行限定,pizza.Rhino.Goat< /em>,但在包含类中,可以通过其简单的名称来了解它。 然而,内部类的每个实例都与其包含类的特定实例相关联:上面,在jerry中创建的Goat隐式地与Rhino相关联实例thisjerry中。 否则,当我们实例化 Goat 时,我们会显式关联 Rhino 实例:(

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

请注意,在奇怪的 Goat 中,您将内部类型称为 Goat em>new 语法:Java 从 rhino 部分推断出包含类型,并且,new rhino.Goat() 对我来说也更有意义。 .)

那么这对我们有什么好处呢? 那么,内部类实例可以访问包含类实例的实例成员。 这些封闭实例成员在内部类内部via仅引用它们的简单名称,而不是viathisthis内部类中指的是内部类实例,而不是关联的包含类实例):

public class Rhino {

    private String barry;

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

在内部类中,您可以将包含类的 this 引用为 Rhino.this >,并且您可以使用this来引用其成员,例如Rhino.this.barry

局部内部类

局部内部类是在方法体中声明的类。 这样的类仅在其包含方法中是已知的,因此只能在其包含方法中实例化并访问其成员。 好处是局部内部类实例绑定到并可以访问其包含方法的最终局部变量。 当实例使用其包含方法的最终局部变量时,即使变量已经超出范围,变量也会保留在实例创建时所保存的值(这实际上是 Java 的粗略、受限版本的闭包)。

因为局部内部类既不是类也不是包的成员,所以它没有声明访问级别。 (但是请注意,它自己的成员具有与普通类相同的访问级别。)

如果在实例方法中声明局部内部类,则内部类的实例化将与包含方法的 this 在实例创建时,因此可以像在实例内部类中一样访问包含类的实例成员。 本地内部类只需通过其名称进行实例化,eg本地内部类Cat实例化为new Cat() >,不是您所期望的 new this.Cat() 。

匿名内部类

匿名内部类是一种在语法上方便的编写本地内部类的方法。 最常见的是,每次运行本地内部类的包含方法时最多仅实例化一次。 那么,如果我们能够将本地内部类定义及其单个实例化组合成一种方便的语法形式,那就太好了,而且如果我们不必为类想出一个名称(无用的名称越少,那也就越方便)。代码包含的名称越好)。 匿名内部类允许这两件事:

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

这是一个返回扩展ParentClassName的未命名类的新实例的表达式。 您不能提供自己的构造函数; 相反,隐式提供的参数只是调用超级构造函数,因此提供的参数必须适合超级构造函数。 (如果父级包含多个构造函数,则称为“最简单”的构造函数,“最简单”是由一组相当复杂的规则决定的,不值得费心详细了解 — 只需注意 NetBeans 或 Eclipse 告诉您的内容即可。

) ,您可以指定要实现的接口:

new *InterfaceName*() {*members*}

这样的声明创建了一个未命名类的新实例,该类扩展了 Object 并实现了InterfaceName。 同样,您不能提供自己的构造函数; 在这种情况下,Java 隐式提供一个无参数、不执行任何操作的构造函数(因此在这种情况下永远不会有构造函数参数)。

即使您无法为匿名内部类提供构造函数,您仍然可以使用初始化块(放置在任何方法外部的 {} 块)进行任何您想要的设置。

请注意,匿名内部类只是一种使用一个实例创建本地内部类的不太灵活的方法。 如果您想要一个实现多个接口的本地内部类,或者在扩展除 Object 之外的某个类或指定其自己的构造函数的同时实现接口的本地内部类,那么您将不得不创建一个常规的命名本地内部类。

The Java tutorial says:

Terminology: Nested classes are
divided into two categories: static
and non-static. Nested classes that
are declared static are simply called
static nested classes. Non-static
nested classes are called inner
classes.

In common parlance, the terms "nested" and "inner" are used interchangeably by most programmers, but I'll use the correct term "nested class" which covers both inner and static.

Classes can be nested ad infinitum, e.g. class A can contain class B which contains class C which contains class D, etc. However, more than one level of class nesting is rare, as it is generally bad design.

There are three reasons you might create a nested class:

  • organization: sometimes it seems most sensible to sort a class into the namespace of another class, especially when it won't be used in any other context
  • access: nested classes have special access to the variables/fields of their containing classes (precisely which variables/fields depends on the kind of nested class, whether inner or static).
  • convenience: having to create a new file for every new type is bothersome, again, especially when the type will only be used in one context

There are four kinds of nested class in Java. In brief, they are:

  • static class: declared as a static member of another class
  • inner class: declared as an instance member of another class
  • local inner class: declared inside an instance method of another class
  • anonymous inner class: like a local inner class, but written as an expression which returns a one-off object

Let me elaborate in more details.

Static Classes

Static classes are the easiest kind to understand because they have nothing to do with instances of the containing class.

A static class is a class declared as a static member of another class. Just like other static members, such a class is really just a hanger on that uses the containing class as its namespace, e.g. the class Goat declared as a static member of class Rhino in the package pizza is known by the name pizza.Rhino.Goat.

package pizza;

public class Rhino {

    ...

    public static class Goat {
        ...
    }
}

Frankly, static classes are a pretty worthless feature because classes are already divided into namespaces by packages. The only real conceivable reason to create a static class is that such a class has access to its containing class's private static members, but I find this to be a pretty lame justification for the static class feature to exist.

Inner Classes

An inner class is a class declared as a non-static member of another class:

package pizza;

public class Rhino {

    public class Goat {
        ...
    }

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

Like with a static class, the inner class is known as qualified by its containing class name, pizza.Rhino.Goat, but inside the containing class, it can be known by its simple name. However, every instance of an inner class is tied to a particular instance of its containing class: above, the Goat created in jerry, is implicitly tied to the Rhino instance this in jerry. Otherwise, we make the associated Rhino instance explicit when we instantiate Goat:

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

(Notice you refer to the inner type as just Goat in the weird new syntax: Java infers the containing type from the rhino part. And, yes new rhino.Goat() would have made more sense to me too.)

So what does this gain us? Well, the inner class instance has access to the instance members of the containing class instance. These enclosing instance members are referred to inside the inner class via just their simple names, not via this (this in the inner class refers to the inner class instance, not the associated containing class instance):

public class Rhino {

    private String barry;

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

In the inner class, you can refer to this of the containing class as Rhino.this, and you can use this to refer to its members, e.g. Rhino.this.barry.

Local Inner Classes

A local inner class is a class declared in the body of a method. Such a class is only known within its containing method, so it can only be instantiated and have its members accessed within its containing method. The gain is that a local inner class instance is tied to and can access the final local variables of its containing method. When the instance uses a final local of its containing method, the variable retains the value it held at the time of the instance's creation, even if the variable has gone out of scope (this is effectively Java's crude, limited version of closures).

Because a local inner class is neither the member of a class or package, it is not declared with an access level. (Be clear, however, that its own members have access levels like in a normal class.)

If a local inner class is declared in an instance method, an instantiation of the inner class is tied to the instance held by the containing method's this at the time of the instance's creation, and so the containing class's instance members are accessible like in an instance inner class. A local inner class is instantiated simply via its name, e.g. local inner class Cat is instantiated as new Cat(), not new this.Cat() as you might expect.

Anonymous Inner Classes

An anonymous inner class is a syntactically convenient way of writing a local inner class. Most commonly, a local inner class is instantiated at most just once each time its containing method is run. It would be nice, then, if we could combine the local inner class definition and its single instantiation into one convenient syntax form, and it would also be nice if we didn't have to think up a name for the class (the fewer unhelpful names your code contains, the better). An anonymous inner class allows both these things:

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

This is an expression returning a new instance of an unnamed class which extends ParentClassName. You cannot supply your own constructor; rather, one is implicitly supplied which simply calls the super constructor, so the arguments supplied must fit the super constructor. (If the parent contains multiple constructors, the “simplest” one is called, “simplest” as determined by a rather complex set of rules not worth bothering to learn in detail--just pay attention to what NetBeans or Eclipse tell you.)

Alternatively, you can specify an interface to implement:

new *InterfaceName*() {*members*}

Such a declaration creates a new instance of an unnamed class which extends Object and implements InterfaceName. Again, you cannot supply your own constructor; in this case, Java implicitly supplies a no-arg, do-nothing constructor (so there will never be constructor arguments in this case).

Even though you can't give an anonymous inner class a constructor, you can still do any setup you want using an initializer block (a {} block placed outside any method).

Be clear that an anonymous inner class is simply a less flexible way of creating a local inner class with one instance. If you want a local inner class which implements multiple interfaces or which implements interfaces while extending some class other than Object or which specifies its own constructor, you're stuck creating a regular named local inner class.

爱已欠费 2024-07-12 10:06:21

我认为上述答案中真正的区别并没有变得清晰。

首先要正确理解术语:

  • 嵌套类是在源代码级别包含在另一个类中的类。
  • 如果使用 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 访问 Container 的封闭实例。

更多核心解释如下:

如果您查看编译器为(非静态)嵌套类生成的 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 。 这是在构造函数中设置的,该构造函数具有 Container 类型的附加参数来指定封闭实例。 您在源代码中看不到此参数,但编译器会为嵌套类隐式生成它。

马丁的示例

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

将被编译为类似的调用(以字节码形式)

new InnerClass(outerObject)

为了完整起见,

:匿名类非静态嵌套类的完美示例,它没有与它并且以后无法引用。

I don't think the real difference became clear in the above answers.

First to get the terms right:

  • A nested class is a class which is contained in another class at the source code level.
  • It is static if you declare it with the static modifier.
  • A non-static nested class is called inner class. (I stay with non-static nested class.)

Martin's answer is right so far. However, the actual question is: What is the purpose of declaring a nested class static or not?

You use static nested classes if you just want to keep your classes together if they belong topically together or if the nested class is exclusively used in the enclosing class. There is no semantic difference between a static nested class and every other class.

Non-static nested classes are a different beast. Similar to anonymous inner classes, such nested classes are actually closures. That means they capture their surrounding scope and their enclosing instance and make that accessible. Perhaps an example will clarify that. See this stub of a Container:

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);
    }
}

In this case you want to have a reference from a child item to the parent container. Using a non-static nested class, this works without some work. You can access the enclosing instance of Container with the syntax Container.this.

More hardcore explanations following:

If you look at the Java bytecodes the compiler generates for an (non-static) nested class it might become even clearer:

// 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
}

As you can see the compiler creates a hidden field Container this$0. This is set in the constructor which has an additional parameter of type Container to specify the enclosing instance. You can't see this parameter in the source but the compiler implicitly generates it for a nested class.

Martin's example

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

would so be compiled to a call of something like (in bytecodes)

new InnerClass(outerObject)

For the sake of completeness:

An anonymous class is a perfect example of a non-static nested class which just has no name associated with it and can't be referenced later.

蝶舞 2024-07-12 10:06:21

我认为上述答案都没有向您解释嵌套类和静态嵌套类在应用程序设计方面的真正区别:

OverView

嵌套类可以是非静态或静态的,并且在每种情况下< strong>是一个在另一个类中定义的类。 嵌套类应该只为外围类服务,如果嵌套类对其他类(不仅仅是外围类)有用,则应将其声明为顶级类。

区别

非静态嵌套类:与包含类的封闭实例隐式关联,这意味着可以调用封闭实例的方法和访问变量。 非静态嵌套类的一种常见用途是定义 Adapter 类。

静态嵌套类:无法访问封闭类实例并调用其方法,因此应在嵌套类不需要访问封闭类实例时使用。 静态嵌套类的常见用途是实现外部对象的组件。

结论

因此,从设计的角度来看,两者之间的主要区别是:非静态嵌套类可以访问容器类的实例,而静态则不能

I think that none of the above answers explain to you the real difference between a nested class and a static nested class in term of application design :

OverView

A nested class could be nonstatic or static and in each case is a class defined within another class. A nested class should exist only to serve is enclosing class, if a nested class is useful by other classes (not only the enclosing), should be declared as a top level class.

Difference

Nonstatic Nested class : is implicitly associated with the enclosing instance of the containing class, this means that it is possible to invoke methods and access variables of the enclosing instance. One common use of a nonstatic nested class is to define an Adapter class.

Static Nested Class : can't access enclosing class instance and invoke methods on it, so should be used when the nested class doesn't require access to an instance of the enclosing class . A common use of static nested class is to implement a components of the outer object.

Conclusion

So the main difference between the two from a design standpoint is : nonstatic nested class can access instance of the container class, while static can't.

叶落知秋 2024-07-12 10:06:21

以下是 Java 内部类和静态嵌套类之间的主要区别和相似之处。

希望能帮助到你!

内部类

  • 可以访问外部类实例和静态方法和字段
  • 与封闭类的实例关联,因此首先需要实例化它外部类的实例(注意 new 关键字位置):

    Outerclass.InnerClass innerObject = outerObject.new Innerclass(); 
      
  • < strong>不能定义任何静态成员本身

  • 不能接口声明

静态嵌套类

  • 无法访问外部类实例方法或字段

  • 不与封闭类的任何实例关联因此要实例化它:

    OuterClass.StaticNestedClassnestedObject = new OuterClass.StaticNestedClass(); 
      

相似之处

  • 内部类甚至可以访问私有字段和方法< 外部类的/strong>
  • 另外,外部类可以访问内部类私有字段和方法
  • 这两个类可以有私有、受保护或公共访问修饰符

为什么使用嵌套类?

根据 Oracle 文档,有几个原因(完整文档) :

  • 这是一种对仅在一个地方使用的类进行逻辑分组的方法:如果一个类仅对另一个类有用,那么将其嵌入到该类中是合乎逻辑的并将两者保持在一起。 嵌套这样的“帮助类”使得它们的包更加精简。

  • 它增加了封装性:考虑两个顶级类 A 和 B,其中 B 需要访问 A 的成员,否则这些成员将被声明为私有。 通过将类 B 隐藏在类 A 中,可以将 A 的成员声明为私有,并且 B 可以访问它们。 另外,B本身可以对外界隐藏。

  • 它可以生成更具可读性和可维护性的代码:在顶级类中嵌套小类可以使代码更接近其使用位置。

Here is key differences and similarities between Java inner class and static nested class.

Hope it helps!

Inner class

  • Can access to outer class both instance and static methods and fields
  • Associated with instance of enclosing class so to instantiate it first needs an instance of outer class (note new keyword place):

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
    
  • Cannot define any static members itself

  • Cannot have Class or Interface declaration

Static nested class

  • Cannot access outer class instance methods or fields

  • Not associated with any instance of enclosing class So to instantiate it:

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

Similarities

  • Both Inner classes can access even private fields and methods of outer class
  • Also the Outer class have access to private fields and methods of inner classes
  • Both classes can have private, protected or public access modifier

Why Use Nested Classes?

According to Oracle documentation there're several reasons (full documentation):

  • It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.

  • It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.

  • It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used.

回心转意 2024-07-12 10:06:21

简单来说,我们需要嵌套类主要是因为 Java 不提供闭包。

嵌套类是在另一个封闭类的主体内定义的类。 它们有两种类型 - 静态和非静态。

它们被视为封闭类的成员,因此您可以指定四个访问说明符中的任何一个 - private、package、protected、public。 我们没有顶级类的这种奢侈,只能将其声明为公共或包私有。

内部类(又名非堆栈类)可以访问顶级类的其他成员,即使它们被声明为私有,而静态嵌套类则无法访问顶级类的其他成员。

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

Inner1 是我们的静态内部类,Inner2 是我们的非静态内部类。 它们之间的主要区别是,您无法在没有 Outer 的情况下创建 Inner2 实例,而您可以独立创建 Inner1 对象。

什么时候会使用内部类?

考虑一下Class AClass B相关的情况,Class B需要访问Class A成员, B 类 仅与A 类 相关。 内部类就出现了。

为了创建内部类的实例,您需要创建外部类的实例。

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

或者

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

什么时候使用静态内部类?

当您知道静态内部类与封闭类/顶级类的实例没有任何关系时,您可以定义它。 如果你的内部类不使用外部类的方法或字段,那只是浪费空间,所以将其设为静态。

例如,要为静态嵌套类创建对象,请使用以下语法:

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

静态嵌套类的优点是它不需要包含类/顶级类的对象即可工作。 这可以帮助您减少应用程序在运行时创建的对象数量。

In simple terms we need nested classes primarily because Java does not provide closures.

Nested Classes are classes defined inside the body of another enclosing class. They are of two types - static and non-static.

They are treated as members of the enclosing class, hence you can specify any of the four access specifiers - private, package, protected, public. We don't have this luxury with top-level classes, which can only be declared public or package-private.

Inner classes aka Non-stack classes have access to other members of the top class, even if they are declared private while Static nested classes do not have access to other members of the top class.

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

Inner1 is our static inner class and Inner2 is our inner class which is not static. The key difference between them, you can't create an Inner2 instance without an Outer where as you can create an Inner1 object independently.

When would you use Inner class?

Think of a situation where Class A and Class B are related, Class B needs to access Class A members, and Class B is related only to Class A. Inner classes comes into the picture.

For creating an instance of inner class, you need to create an instance of your outer class.

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

or

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

When would you use static Inner class?

You would define a static inner class when you know that it does not have any relationship with the instance of the enclosing class/top class. If your inner class doesn't use methods or fields of the outer class, it's just a waste of space, so make it static.

For example, to create an object for the static nested class, use this syntax:

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

The advantage of a static nested class is that it doesn't need an object of the containing class/top class to work. This can help you to reduce the number of objects your application creates at runtime.

梦在深巷 2024-07-12 10:06:21

我认为,通常遵循的约定是:

  • 顶级类中的静态类
  • 顶级类中的嵌套类非静态类 level 类是一个内部类,它进一步
    还有两种形式:

    • 本地类 - 在块内部声明的命名类,如方法或构造函数体
    • 匿名类 - 其实例在表达式和语句中创建的未命名类

但是,很少有其他要记住的要点是:

  • 顶级类和静态嵌套类在语义上是相同的,除了在静态嵌套类的情况下,它可以静态引用其外部[父类的私有静态字段/方法] ] 类,反之亦然。

  • 内部类可以访问外部[父]类的封闭实例的实例变量。 但是,并非所有内部类都有封闭实例,例如静态上下文中的内部类(如静态初始化块中使用的匿名类)就没有。

  • 匿名类默认扩展父类或实现父接口,并且没有进一步的子句来扩展任何其他类或实现更多接口。 所以,

    • new YourClass(){}; 表示 class [Anonymous] 扩展 YourClass {}
    • new YourInterface(){}; 表示 class [Anonymous] 实现 YourInterface {}

我觉得更大的问题仍然悬而未决,该使用哪一个以及何时使用? 好吧,这主要取决于您正在处理什么情况,但阅读 @jrudolph 给出的回复可能会帮助您做出一些决定。

I think, the convention that is generally followed is this:

  • static class within a top level class is a nested class
  • non static class within a top level class is a inner class, which further
    has two more form:

    • local class - named classes declared inside of a block like a method or constructor body
    • anonymous class - unnamed classes whose instances are created in expressions and statements

However, few other points to remembers are:

  • Top level classes and static nested class are semantically same except that in case of static nested class it can make static reference to private static fields/methods of its Outer [parent] class and vice versa.

  • Inner classes have access to instance variables of the enclosing instance of the Outer [parent] class. However, not all inner classes have enclosing instances, for example inner classes in static contexts, like an anonymous class used in a static initializer block, do not.

  • Anonymous class by default extends the parent class or implements the parent interface and there is no further clause to extend any other class or implement any more interfaces. So,

    • new YourClass(){}; means class [Anonymous] extends YourClass {}
    • new YourInterface(){}; means class [Anonymous] implements YourInterface {}

I feel that the bigger question that remains open which one to use and when? Well that mostly depends on what scenario you are dealing with but reading the reply given by @jrudolph may help you making some decision.

打小就很酷 2024-07-12 10:06:21

创建外部类的实例时,也会创建内部类的实例。 因此内部类的成员和方法可以访问外部类的实例(对象)的成员和方法。 当外部类的实例超出范围时,内部类实例也不再存在。

静态嵌套类没有具体的实例。 它只是在第一次使用时加载(就像静态方法一样)。 它是一个完全独立的实体,其方法和变量无法访问外部类的实例。

静态嵌套类不与外部对象耦合,它们速度更快,并且不占用堆/堆栈内存,因为不需要创建此类的实例。 因此,经验法则是尝试定义静态嵌套类,范围尽可能有限(private >= class >= protected >= public),然后将其转换为内部类(通过删除“static”标识符)并放宽范围(如果确实有必要)。

The instance of the inner class is created when instance of the outer class is created. Therefore the members and methods of the inner class have access to the members and methods of the instance (object) of the outer class. When the instance of the outer class goes out of scope, also the inner class instances cease to exist.

The static nested class doesn't have a concrete instance. It's just loaded when it's used for the first time (just like the static methods). It's a completely independent entity, whose methods and variables doesn't have any access to the instances of the outer class.

The static nested classes are not coupled with the outer object, they are faster, and they don't take heap/stack memory, because its not necessary to create instance of such class. Therefore the rule of thumb is to try to define static nested class, with as limited scope as possible (private >= class >= protected >= public), and then convert it to inner class (by removing "static" identifier) and loosen the scope, if it's really necessary.

回忆躺在深渊里 2024-07-12 10:06:21

嵌套类:类内部的类

类型:

  1. 静态嵌套类
  2. 非静态嵌套类[内部类]

区别:

非静态嵌套类[内部类]

在非静态嵌套类对象中存在内部类外部类的对象。 这样外部类的数据成员就可以被内部类访问。 因此,要创建内部类的对象,我们必须先创建外部类的对象。

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

静态嵌套类

在静态嵌套类中,内部类的对象不需要外部类的对象,因为“静态”一词表示不需要创建对象。

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

如果要访问x,则在方法内部编写以下内容

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

Nested class: class inside class

Types:

  1. Static nested class
  2. Non-static nested class [Inner class]

Difference:

Non-static nested class [Inner class]

In non-static nested class object of inner class exist within object of outer class. So that data member of outer class is accessible to inner class. So to create object of inner class we must create object of outer class first.

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

Static nested class

In static nested class object of inner class don't need object of outer class, because the word "static" indicate no need to create object.

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

If you want to access x, then write the following inside method

  outerclass.nestedclass.x;  i.e. System.out.prinltn( outerclass.nestedclass.x);
忘你却要生生世世 2024-07-12 10:06:21

嵌套静态类的使用有一个微妙之处,在某些情况下可能很有用。

尽管静态属性是在类通过其构造函数实例化之前实例化的,
嵌套静态类内部的静态属性似乎直到之后才被实例化
类的构造函数被调用,或者至少在第一次引用属性之后被调用,
即使它们被标记为“最终”。

考虑这个例子:

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");
    }
}

尽管“nested”和“innerItem”都被声明为“static final”。 那个设定
直到类被实例化之后(或者至少
直到第一次引用嵌套静态项之后),正如您自己所看到的
通过注释和取消注释我上面提到的行。 同样不成立
对于“outerItem”为真。

至少这是我在 Java 6.0 中看到的。

There is a subtlety about the use of nested static classes that might be useful in certain situations.

Whereas static attributes get instantiated before the class gets instantiated via its constructor,
static attributes inside of nested static classes don't seem to get instantiated until after the
class's constructor gets invoked, or at least not until after the attributes are first referenced,
even if they are marked as 'final'.

Consider this example:

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");
    }
}

Even though 'nested' and 'innerItem' are both declared as 'static final'. the setting
of nested.innerItem doesn't take place until after the class is instantiated (or at least
not until after the nested static item is first referenced), as you can see for yourself
by commenting and uncommenting the lines that I refer to, above. The same does not hold
true for 'outerItem'.

At least this is what I'm seeing in Java 6.0.

梦途 2024-07-12 10:06:21

这些术语可以互换使用。 如果您想对此真正迂腐,那么您可以定义“嵌套类”来引用静态内部类,该内部类没有封闭的实例。 在代码中,您可能有这样的内容:

public class Outer {
    public class Inner {}

    public static class Nested {}
}

但这并不是一个真正被广泛接受的定义。

The terms are used interchangeably. If you want to be really pedantic about it, then you could define "nested class" to refer to a static inner class, one which has no enclosing instance. In code, you might have something like this:

public class Outer {
    public class Inner {}

    public static class Nested {}
}

That's not really a widely accepted definition though.

弱骨蛰伏 2024-07-12 10:06:21

在创建实例的情况下,非实例的实例
静态内部类是通过引用创建的
定义它的外部类的对象。 这
意味着它有内含实例。
但是静态内部类的实例
是使用外部类的引用创建的,而不是使用
外部类对象的引用。 这意味着
没有包含实例。

例如:

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….
  }
}

In the case of creating instance, the instance of non
static inner class is created with the reference of
object of outer class in which it is defined. This
means it have inclosing instance.
But the instance of static inner class
is created with the reference of Outer class, not with
the reference of object of outer class. This means it
have not inclosing instance.

For example:

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….
  }
}
走走停停 2024-07-12 10:06:21

我认为这里不需要添加太多内容,大多数答案都完美地解释了静态嵌套类和内部类之间的区别。 但是,在使用嵌套类与内部类时请考虑以下问题。
正如几个答案中提到的,内部类不能在没有其封闭类实例的情况下实例化,这意味着它们持有一个指向其封闭类实例的指针,该实例可以导致内存溢出或堆栈溢出异常,因为 GC 将无法对封闭类进行垃圾回收,即使它们不再使用。 为了清楚地说明这一点,请检查以下代码:

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();

}

如果删除 // inside = null; 上的注释,程序将输出 put
我被摧毁了!”,但保留此评论不会。
原因是白色内部实例仍然被引用,GC 无法收集它,并且因为它引用(具有指向)外部实例,所以它也没有被收集。 如果您的项目中有足够的这些对象,则可能会耗尽内存。
与静态内部类相比,静态内部类不持有指向内部类实例的点,因为它与实例无关,而是与类相关。
如果您将内部类设为静态并使用 Outer.Inner i = new Outer.Inner(); 实例化,上面的程序可以打印“I am destroy!

I don't think there is much to add here, most of the answers perfectly explain the differences between static nested class and Inner classes. However, consider the following issue when using nested classes vs inner classes.
As mention in a couple of answers inner classes can not be instantiated without and instance of their enclosing class which mean that they HOLD a pointer to the instance of their enclosing class which can lead to memory overflow or stack overflow exception due to the fact the GC will not be able to garbage collect the enclosing classes even if they are not used any more. To make this clear check the following code out:

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();

}

If you remove the comment on // inner = null; The program will out put
"I am destroyed !", but keeping this commented it will not.
The reason is that white inner instance is still referenced GC cannot collect it and because it references (has a pointer to) the outer instance it is not collected too. Having enough of these objects in your project and can run out of memory.
Compared to static inner classes which does not hold a point to inner class instance because it is not instance related but class related.
The above program can print "I am destroyed !" if you make Inner class static and instantiated with Outer.Inner i = new Outer.Inner();

恰似旧人归 2024-07-12 10:06:21

我认为上述答案都没有给您提供真实的例子,说明嵌套类和静态嵌套类在应用程序设计方面的区别。 静态嵌套类和内部类的主要区别在于访问外部类实例字段的能力。

让我们看一下下面两个例子。

静态嵌套类:使用静态嵌套类的一个很好的例子是构建器模式(https:// /dzone.com/articles/design-patterns-the-builder-pattern)。

对于BankAccount,我们使用静态嵌套类,主要是因为

  1. 静态嵌套类实例可以在外部类之前创建。

  2. 在构建器模式中,构建器是一个用于创建 BankAccount 的帮助器类。

  3. BankAccount.Builder 仅与 BankAccount 关联。 没有其他类与 BankAccount.Builder 相关。 因此最好将它们组织在一起而不使用命名约定。
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
        }
    }
}

I think that none of the above answers give the real example to you the difference between a nested class and a static nested class in term of application design. And the main difference between static nested class and inner class is the ability to access the outer class instance field.

Let us take a look at the two following examples.

Static nest class: An good example of using static nested classes is builder pattern (https://dzone.com/articles/design-patterns-the-builder-pattern).

For BankAccount we use a static nested class, mainly because

  1. Static nest class instance could be created before the outer class.

  2. In the builder pattern, the builder is a helper class which is used to create the BankAccount.

  3. BankAccount.Builder is only associated with BankAccount. No other classes are related to BankAccount.Builder. so it is better to organize them together without using name convention.
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;
        }
    }
}

Inner class: A common use of inner classes is to define an event handler.
https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html

For MyClass, we use the inner class, mainly because:

  1. Inner class MyAdapter need to access the outer class member.

  2. In the example, MyAdapter is only associated with MyClass. No other classes are related to MyAdapter. so it is better to organize them together without using a name convention

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
        }
    }
}
请帮我爱他 2024-07-12 10:06:21

嵌套类是一个非常笼统的术语:每个非顶级的类都是嵌套类。
内部类是非静态嵌套类。
Joseph Darcy 写了一篇关于嵌套类、内部类、成员类和顶级类的非常好的解释。

Nested class is a very general term: every class which is not top level is a nested class.
An inner class is a non-static nested class.
Joseph Darcy wrote a very nice explanation about Nested, Inner, Member, and Top-Level Classes.

梦里人 2024-07-12 10:06:21

针对 Java 和/或嵌套类新手的学习者

嵌套类可以是:

1. 静态嵌套类。
2. 非静态嵌套类。 (也称为内部类)=>请记住这一点

1.内部类
示例:

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

内部类是嵌套类的子集:

  • 内部类是嵌套类的特定类型
  • 内部类是嵌套类的子集
  • 您可以说内部类也是嵌套类类,但您不能说嵌套类也是内部类

内部类的特殊性:

  • 内部类的实例可以访问外部类的所有成员,甚至是那些标记为“私有”的

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 中内部类和静态嵌套类的主要区别是什么?
答案:只需查看上述每个类别的具体信息即可。

Targeting learner, who are novice to Java and/or Nested Classes

Nested classes can be either:

1. Static Nested classes.
2. Non Static Nested classes. (also known as Inner classes) =>Please remember this

1.Inner classes
Example:

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

Inner classes are subsets of nested classes:

  • inner class is a specific type of nested class
  • inner classes are subsets of nested classes
  • You can say that an inner class is also a nested class, but you can NOT say that a nested class is also an inner class.

Specialty of Inner class:

  • instance of an inner class has access to all of the members of the outer class, even those that are marked “private”

2.Static Nested Classes:
Example:

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

Case 1:Instantiating a static nested class from a non-enclosing class

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"
  }
}

Case 2:Instantiating a static nested class from an enclosing class

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"
  }

}

Specialty of Static classes:

  • Static inner class would only have access to the static members of the outer class, and have no access to non-static members.

Conclusion:
Question: What is the main difference between a inner class and a static nested class in Java?
Answer: just go through specifics of each class mentioned above.

北渚 2024-07-12 10:06:21

嗯...内部类嵌套类...您的意思是匿名类和内部类吗?

编辑:如果您实际上指的是内部与匿名:内部类只是在类中定义的类,例如:

public class A {
    public class B {
    }
}

...而匿名类是匿名定义的类的扩展,因此没有定义实际的“类”,如:

public class A {
}

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

进一步编辑:

维基百科声称Java中存在差异,但我一直在使用使用 Java 八年了,这是我第一次听到这样的区别——更不用说没有任何参考文献来支持这种说法……底线是,内部类是在类(静态或非静态)中定义的类,并且嵌套只是表示同一事物的另一个术语。

静态和非静态嵌套类之间存在微妙的区别......基本上,非静态内部类可以隐式访问封闭类的实例字段和方法(因此它们不能在静态上下文中构造,这将是编译器错误)。 另一方面,静态嵌套类没有对实例字段和方法的隐式访问,并且可以在静态上下文中构造。

Ummm… An inner class is a nested class… Do you mean anonymous class and inner class?

Edit: If you actually meant inner v.s. anonymous: an inner class is just a class defined within a class, such as:

public class A {
    public class B {
    }
}

…whereas an anonymous class is an extension of a class defined anonymously, so no actual "class" is defined, as in:

public class A {
}

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

Further edit:

Wikipedia claims there is a difference in Java, but I've been working with Java for eight years, and it's the first time I heard such a distinction – not to mention there are no references there to back up the claim… Bottom line, an inner class is a class defined within a class (static or not), and nested is just another term to mean the same thing.

There is a subtle difference between static and non-static nested classes… Basically, non-static inner classes have implicit access to instance fields and methods of the enclosing class (thus they cannot be constructed in a static context, it will be a compiler error). On the other hand, static nested classes don't have implicit access to instance fields and methods and can be constructed in a static context.

日裸衫吸 2024-07-12 10:06:21

Java中的内部类嵌套静态类都是在另一个类中声明的类,在Java中称为顶级类。 在Java术语中,如果将嵌套类声明为静态,则在Java中它将称为嵌套静态类,而非静态嵌套类简称为内部类。

什么是Java中的内部类?

任何不是顶级或在另一个类中声明的类都称为嵌套类,在这些嵌套类中,声明为非静态的类称为内部类在爪哇。 Java 中的内部类分为三种:

1) 局部内部类 - 在代码块或方法内部声明。
2) 匿名内部类 - 是一个没有名称可供引用的类,并且在创建它的同一位置进行初始化。
3) 成员内部类-被声明为外部类的非静态成员。

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中的嵌套静态类?

嵌套静态类是在类内部声明为成员并设为静态的另一个类。 嵌套静态类也被声明为外部类的成员,并且可以像任何其他成员一样设为私有、公共或受保护。 嵌套静态类相对于内部类的主要好处之一是嵌套静态类的实例不附加到外部类的任何封闭实例。 您也不需要任何外部类的实例来在 Java 中创建嵌套静态类的实例

1) 它可以访问外部类的静态数据成员,包括私有的。
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 中的嵌套静态类示例

Inner class and nested static class in Java both are classes declared inside another class, known as top level class in Java. In Java terminology, If you declare a nested class static, it will called nested static class in Java while non static nested class are simply referred as Inner Class.

What is Inner Class in Java?

Any class which is not a top level or declared inside another class is known as nested class and out of those nested classes, class which are declared non static are known as Inner class in Java. there are three kinds of Inner class in Java:

1) Local inner class - is declared inside a code block or method.
2) Anonymous inner class - is a class which doesn't have name to reference and initialized at same place where it gets created.
3) Member inner class - is declared as non static member of outer class.

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");
        }
    }
}

What is nested static class in Java?

Nested static class is another class which is declared inside a class as member and made static. Nested static class is also declared as member of outer class and can be make private, public or protected like any other member. One of the main benefit of nested static class over inner class is that instance of nested static class is not attached to any enclosing instance of Outer class. You also don't need any instance of Outer class to create instance of nested static class in Java.

1) It can access static data members of outer class including private.
2) Static nested class cannot access non-static (instance) data member or method.

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");
        }
    }
}

Ref: Inner class and nested Static Class in Java with Example

倾听心声的旋律 2024-07-12 10:06:21

静态嵌套类访问定义它们的类的私有类级静态变量。从体系结构的角度来看,这可能是巨大的(即在服务中使用嵌套静态帮助器类的服务定位器模式),并且可以帮助OP了解它们为什么存在内部类。

Static nested classes access PRIVATE class-level static variables of the class they are defined in. That can be huge from an architectural standpoint (i.e. Service Locator pattern employing nested static helper classes in Services), and may help OP see why they exist along with inner classes.

时光无声 2024-07-12 10:06:21

Java 编程语言允许您在一个类中定义另一个类。 这样的类称为嵌套类,如下所示:

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

嵌套类分为两类:静态类和非静态类。 声明为静态的嵌套类称为静态嵌套类。 非静态嵌套类称为内部类。
我们应该记住的一件事是非静态嵌套类(内部类)可以访问封闭类的其他成员,即使它们被声明为私有。 静态嵌套类只能访问封闭类的其他成员(如果这些成员是静态的)。 它不能访问外部类的非静态成员。
与类方法和变量一样,静态嵌套类与其外部类相关联。
例如,要为静态嵌套类创建对象,请使用以下语法:

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

要实例化内部类,必须首先实例化外部类。 然后,使用以下语法在外部对象中创建内部对象:

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

为什么我们使用嵌套类

  1. 这是一种对仅在一个地方使用的类进行逻辑分组的方法。
  2. 它增加了封装。
  3. 它可以带来更具可读性和可维护性的代码。

来源:Java™ 教程 - 嵌套类

The Java programming language allows you to define a class within another class. Such a class is called a nested class and is illustrated here:

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

Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.
One thing that we should keep in mind is Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes only have access to other members of the enclosing class if those are static. It can not access non static members of the outer class.
As with class methods and variables, a static nested class is associated with its outer class.
For example, to create an object for the static nested class, use this syntax:

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

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:

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

Why we use nested classes

  1. It is a way of logically grouping classes that are only used in one place.
  2. It increases encapsulation.
  3. It can lead to more readable and maintainable code.

Source: The Java™ Tutorials - Nested Classes

德意的啸 2024-07-12 10:06:21

以下是静态嵌套类内部类的示例:

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);
     }

}

OuterClassTest:

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()); 

    }

}

The following is an example of static nested class and 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);
     }

}

OuterClassTest:

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()); 

    }

}
霞映澄塘 2024-07-12 10:06:21

我认为这里的人们应该注意到海报:静态嵌套类只是第一个内部类。
例如:

 public static class A {} //ERROR

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

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

 }

所以,总结一下,静态类不依赖于它包含哪个类。 所以,他们不能正常上课。 (因为普通类需要一个实例)。

I think people here should notice to Poster that : Static Nest Class just only the first inner class.
For example:

 public static class A {} //ERROR

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

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

 }

So, summarize, static class doesn't depend which class its contains. So, they cannot in normal class. (because normal class need an instance).

单身狗的梦 2024-07-12 10:06:21

当我们在类中声明静态成员类时,它被称为顶级嵌套类或静态嵌套类。 可以如下证明:

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);
        }
    }
}

When we declare static member class inside a class, it is known as top level nested class or a static nested class. It can be demonstrated as below :

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());
    }
}

When we declare non-static member class inside a class it is known as inner class. Inner class can be demonstrated as below :

    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);
        }
    }
}
情场扛把子 2024-07-12 10:06:21

图表

enter图片描述在这里

静态嵌套非静态嵌套类之间的主要区别在于静态嵌套无法访问非静态外部类成员

A diagram

enter image description here

The main difference between static nested and non-static nested classes is that static nested does not have an access to non-static outer class members

不念旧人 2024-07-12 10:06:21

除了已经提到的那些之外,嵌套类的另一个用例是嵌套类具有只能从外部类访问的方法。 这是可能的,因为外部类可以访问嵌套类的私有构造函数、字段和方法。

在下面的示例中,Bank 可以发行一个 Bank.CreditCard,它具有私有构造函数,并且可以使用私有构造函数根据当前银行政策更改信用卡限额。 Bank.CreditCardsetLimit(...) 实例方法。 (在这种情况下,对实例变量 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;
        }
    }
}

Another use case for nested classes, in addition to those that already have been mentioned, is when the nested class has methods that should only be accessible from the outer class. This is possible because the outer class has access to the private constructors, fields and methods of the nested class.

In the example below, the Bank can issue a Bank.CreditCard, which has a private constructor, and can change a credit card's limit according to the current bank policy using the private setLimit(...) instance method of Bank.CreditCard. (A direct field access to the instance variable limit would also work in this case). From any other class only the public methods of Bank.CreditCard are accessible.

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;
        }
    }
}
终陌 2024-07-12 10:06:21

首先,不存在称为静态类的类。与内部类(称为嵌套类)一起使用的静态修饰符表示它是外部类的静态成员,这意味着我们可以像其他静态成员一样访问它,而无需任何其他静态成员。外部类的实例。 (这本来就是静态的好处。)

使用嵌套类和常规内部类之间的区别是:

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

首先我们可以实例化外部类,然后我们可以访问内部类。

但如果类是嵌套的,那么语法是:

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

它使用静态语法作为静态关键字的正常实现。

First of all There is no such class called Static class.The Static modifier use with inner class (called as Nested Class) says that it is a static member of Outer Class which means we can access it as with other static members and without having any instance of Outer class. (Which is benefit of static originally.)

Difference between using Nested class and regular Inner class is:

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

First We can to instantiate Outerclass then we Can access Inner.

But if Class is Nested then syntax is:

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

Which uses the static Syntax as normal implementation of static keyword.

凡间太子 2024-07-12 10:06:21

我已经说明了 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);
                        }*/
                    //}
                }
    }

I have illustrated various possible correct and error scenario which can occur in java code.

    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);
                        }*/
                    //}
                }
    }
狂之美人 2024-07-12 10:06:21

不同之处在于,同样是静态的嵌套类声明可以在封闭类之外实例化。

当您有一个非静态的嵌套类声明(也称为内部类)时,Java 不会让您实例化它,除非通过封闭类。 从内部类创建的对象链接到从外部类创建的对象,因此内部类可以引用外部类的字段。

但如果它是静态的,则链接不存在,无法访问外部字段(除非像任何其他对象一样通过普通引用),因此您可以自行实例化嵌套类。

The difference is that a nested class declaration that is also static can be instantiated outside of the enclosing class.

When you have a nested class declaration that is not static, also known as an inner class, Java won't let you instantiate it except via the enclosing class. The object created out of the inner class is linked to the object created from the outer class, so the inner class can reference the fields of the outer.

But if it's static, then the link does not exist, the outer fields cannot be accessed (except via an ordinary reference like any other object) and you can therefore instantiate the nested class by itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文