Java内部类和静态嵌套类。

时间:2023-02-11 22:48:21

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?

在Java中,内部类和静态嵌套类的主要区别是什么?设计/实现在选择其中一个方面是否起作用?

23 个解决方案

#1


1439  

From the Java Tutorial:

从Java教程:

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.

内部类的实例只能存在于OuterClass的一个实例中,并且可以直接访问其封闭实例的方法和字段。

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 = outerObject.new InnerClass();

see: Java Tutorial - Nested Classes

参见:Java教程-嵌套类。

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.

这里,新的A(){…}是一个在静态上下文中定义的内部类,它没有一个封闭实例。

#2


502  

The Java tutorial says:

Java教程说:

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.

类可以是嵌套的无限的,例如类A可以包含类B,类中包含类D,等等。但是,类嵌套的一个级别是很少见的,因为它通常是不好的设计。

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:

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

  • 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.

静态类是声明为另一个类的静态成员的类。就像其他静态成员一样,这样的类实际上只是使用包含类作为其名称空间的一个挂钩,例如,在包批萨中声明为类Rhino中的静态成员的类山羊,它的名称是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:

与静态类一样,内部类以其包含的类名称“pizza.Rhino”而闻名。山羊,但是在包含的类里面,它可以用简单的名字来知道。但是,内部类的每个实例都与它的类的特定实例绑定在一起:上面,在jerry中创建的山羊,与Rhino实例在jerry中是隐式关联的。否则,当我们实例化山羊时,我们使相关的Rhino实例显式:

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.)

(请注意,在奇怪的新语法中,您将内部类型引用为“just Goat”:Java infers中包含来自rhino部分的类型。而且,是的,新犀牛也会对我更有意义。

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.

在内部类中,可以将这个包含类的类称为Rhino。这个,你可以用这个来指代它的成员,例如: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).

本地内部类是在方法体中声明的类。这样的类只在其包含的方法中被知道,所以它只能被实例化并让其成员在其包含的方法中访问。增益是一个本地内部类实例被绑定到并且可以访问其包含方法的最终局部变量。当实例使用其包含方法的最终局部时,变量保留在实例创建时所持有的值,即使该变量已经超出了范围(这实际上是Java的粗糙的、有限的闭包版本)。

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.

如果一个本地内部类在实例方法中声明,那么内部类的实例化与实例创建时包含的方法的实例相关联,因此包含类的实例成员可以在实例内部类中访问。本地内部类仅通过它的名称来实例化,例如,本地的内部类Cat被实例化为new Cat(),而不是新的this.Cat(),如您所期望的那样。


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.)

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

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).

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

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.

很明显,匿名内部类只是创建本地内部类的一种不太灵活的方法。如果您想要一个实现多个接口的本地内部类,或者在扩展某个类而不是对象或指定它自己的构造函数时实现接口,那么您就会被卡在创建一个名为本地内部类的规则中。

#3


122  

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:

如果查看编译器为一个(非静态的)嵌套类生成的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
}

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.

您可以看到,编译器创建了一个隐藏的字段容器,这个$0。这是在构造函数中设置的,该构造函数有一个额外的类型容器参数来指定封闭实例。您不能在源代码中看到这个参数,但是编译器会隐式地为一个嵌套类生成它。

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.

匿名类是一个非静态嵌套类的完美示例,它没有与之关联的名称,以后也不能引用。

#4


78  

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.

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

#5


29  

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

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

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.

Inner1是我们的静态内部类,Inner2是我们的内部类,它不是静态的。它们之间的关键区别是,您不能创建一个没有外部的Inner2实例,因为您可以独立地创建Inner1对象。

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.

考虑a类和B类相关的情况,B类需要访问类a成员,而B类只与类a相关。

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.

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

#6


23  

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 {}
    • 新的YourClass(){ };表示类[匿名]扩展您的类{}
    • new YourInterface(){}; means class [Anonymous] implements YourInterface {}
    • 新的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.

我觉得更大的问题是什么时候该用哪一个?这主要取决于你要处理的场景,但是阅读@jrudolph给出的回复可能会帮助你做出一些决定。

#7


20  

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

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

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):

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

  • 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.

    它增加了封装:考虑两个*类,A和B,其中B需要访问被声明为私有的A的成员。通过在类A中隐藏B类,A的成员可以被声明为私有,B可以访问它们。此外,B本身也可以隐藏在外面的世界。

  • 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.

    它可以导致更易于阅读和可维护的代码:在*类中嵌套小类使代码更接近于使用它的地方。

#8


12  

Nested class: class inside class

嵌套类:类内部类。

Types:

类型:

  1. Static nested class
  2. 静态嵌套类
  3. Non-static nested class [Inner class]
  4. 非静态嵌套类[内部类]

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

如果您想访问x,则编写以下内部方法。

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

#9


9  

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.

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

#10


8  

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'.

然而静态属性在类通过其构造函数实例化之前被实例化,嵌套静态类中的静态属性在类的构造函数被调用之前似乎不会被实例化,或者至少在第一次引用属性之后才会被实例化,即使它们被标记为“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'.

即使“嵌套”和“innerItem”都被声明为“静态final”。嵌套的设置。innerItem直到类被实例化(或者至少在嵌套的静态项被第一次引用之后)才会发生,您可以通过注释和取消我引用的这些行来查看。同样的情况也不适用于“outerItem”。

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

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

#11


8  

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

#12


7  

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.

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

#13


7  

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:

我不认为这里有太多需要补充的地方,大多数的答案完美地解释了静态嵌套类和内部类之间的区别。但是,在使用嵌套类和内部类时考虑以下问题。提到的几个答案内部类不能被实例化,没有和他们的封闭类的实例,意味着他们持有的实例的指针封闭类从而导致内存溢出或堆栈溢出异常是因为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();

}

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

如果您删除// inner = null的注释;这个程序会输出“我被摧毁了!”,但是保持这个注释不会。原因是,白色的内部实例仍然被引用,GC不能收集它,因为它引用(有一个指向)外部实例的指针,它也没有被收集。在项目中拥有足够的这些对象,并且内存不足。与静态内部类相比,它没有指向内部类实例,因为它不是实例相关的,而是类相关的。上面的程序可以打印“我被破坏了!”如果你使内部类静态和实例化的外部。内i = new Outer.Inner();

#14


6  

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.

嵌套类是一个非常通用的术语:不是顶层的每个类都是嵌套类。内部类是一个非静态嵌套类。Joseph Darcy写了一个关于嵌套、内部、成员和*类的很好的解释。

#15


6  

Ummm... an inner class IS a nested class... do you mean anonymous class and inner class?

嗯……内部类是一个嵌套类…你是指匿名类和内部类吗?

Edit: If you actually meant inner vs 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 8 years, and it's the first 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.

*声称Java有区别,但是我已经和Java合作了8年,这是我第一次听到这样的区别。更不必说,这里没有任何证据支持这一说法……底线,内部类是在类中定义的类(静态的或非静态的),嵌套是指同一事物的另一个术语。

There is a subtle difference between static and non-static nested class... 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). Static nested classes, on the other hand, don't have implicit access to instance fields and methods, and CAN be constructed in a static context.

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

#16


5  

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

针对初学者,他们是Java和/或嵌套类的新手。

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

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


1.Inner classes
Example:

1。内部类的例子:

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:

2。静态嵌套类:例如:

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

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

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

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

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

}

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.

结论:在Java中,内部类和静态嵌套类的主要区别是什么?回答:只看上面提到的每一个课程的细节。

#17


4  

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

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

 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).

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

#18


4  

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

#19


4  

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.

Java中的内部类和嵌套静态类都是在另一个类中声明的类,也就是Java中的*类。在Java术语中,如果您声明一个嵌套的类静态,它将在Java中调用嵌套的静态类,而非静态嵌套类被简单地称为内部类。

What is Inner Class in Java?

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:

任何不是*级别或在另一个类中声明的类都被称为嵌套类,并且在这些嵌套类中,被声明为非静态的类被称为Java中的内部类。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.

1)本地内部类——在代码块或方法中声明。匿名内部类——是一个没有名称的类,在创建它的地方初始化。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");
        }
    }
}

What is nested static class in Java?

在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.

嵌套的静态类是另一个类,它在类中声明为成员并使其静态。嵌套的静态类也声明为外部类的成员,可以像其他成员一样进行私有、公开或保护。内嵌静态类的主要好处之一是,嵌套静态类的实例不依附于外部类的任何封闭实例。您也不需要外部类的任何实例来创建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.

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

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

Ref: Java中的内部类和嵌套静态类。

#20


2  

The following is an example of static nested class and inner class:

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

OuterClass.java

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:

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

    }

}

#21


1  

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.

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

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.

但是如果它是静态的,那么这个链接就不存在,外部的字段不能被访问(除非通过像其他对象一样的普通引用),因此您可以自己实例化嵌套的类。

#22


1  

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.

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

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.

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

#23


0  

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

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

#1


1439  

From the Java Tutorial:

从Java教程:

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.

内部类的实例只能存在于OuterClass的一个实例中,并且可以直接访问其封闭实例的方法和字段。

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 = outerObject.new InnerClass();

see: Java Tutorial - Nested Classes

参见:Java教程-嵌套类。

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.

这里,新的A(){…}是一个在静态上下文中定义的内部类,它没有一个封闭实例。

#2


502  

The Java tutorial says:

Java教程说:

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.

类可以是嵌套的无限的,例如类A可以包含类B,类中包含类D,等等。但是,类嵌套的一个级别是很少见的,因为它通常是不好的设计。

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:

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

  • 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.

静态类是声明为另一个类的静态成员的类。就像其他静态成员一样,这样的类实际上只是使用包含类作为其名称空间的一个挂钩,例如,在包批萨中声明为类Rhino中的静态成员的类山羊,它的名称是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:

与静态类一样,内部类以其包含的类名称“pizza.Rhino”而闻名。山羊,但是在包含的类里面,它可以用简单的名字来知道。但是,内部类的每个实例都与它的类的特定实例绑定在一起:上面,在jerry中创建的山羊,与Rhino实例在jerry中是隐式关联的。否则,当我们实例化山羊时,我们使相关的Rhino实例显式:

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.)

(请注意,在奇怪的新语法中,您将内部类型引用为“just Goat”:Java infers中包含来自rhino部分的类型。而且,是的,新犀牛也会对我更有意义。

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.

在内部类中,可以将这个包含类的类称为Rhino。这个,你可以用这个来指代它的成员,例如: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).

本地内部类是在方法体中声明的类。这样的类只在其包含的方法中被知道,所以它只能被实例化并让其成员在其包含的方法中访问。增益是一个本地内部类实例被绑定到并且可以访问其包含方法的最终局部变量。当实例使用其包含方法的最终局部时,变量保留在实例创建时所持有的值,即使该变量已经超出了范围(这实际上是Java的粗糙的、有限的闭包版本)。

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.

如果一个本地内部类在实例方法中声明,那么内部类的实例化与实例创建时包含的方法的实例相关联,因此包含类的实例成员可以在实例内部类中访问。本地内部类仅通过它的名称来实例化,例如,本地的内部类Cat被实例化为new Cat(),而不是新的this.Cat(),如您所期望的那样。


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.)

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

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).

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

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.

很明显,匿名内部类只是创建本地内部类的一种不太灵活的方法。如果您想要一个实现多个接口的本地内部类,或者在扩展某个类而不是对象或指定它自己的构造函数时实现接口,那么您就会被卡在创建一个名为本地内部类的规则中。

#3


122  

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:

如果查看编译器为一个(非静态的)嵌套类生成的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
}

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.

您可以看到,编译器创建了一个隐藏的字段容器,这个$0。这是在构造函数中设置的,该构造函数有一个额外的类型容器参数来指定封闭实例。您不能在源代码中看到这个参数,但是编译器会隐式地为一个嵌套类生成它。

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.

匿名类是一个非静态嵌套类的完美示例,它没有与之关联的名称,以后也不能引用。

#4


78  

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.

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

#5


29  

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

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

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.

Inner1是我们的静态内部类,Inner2是我们的内部类,它不是静态的。它们之间的关键区别是,您不能创建一个没有外部的Inner2实例,因为您可以独立地创建Inner1对象。

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.

考虑a类和B类相关的情况,B类需要访问类a成员,而B类只与类a相关。

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.

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

#6


23  

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 {}
    • 新的YourClass(){ };表示类[匿名]扩展您的类{}
    • new YourInterface(){}; means class [Anonymous] implements YourInterface {}
    • 新的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.

我觉得更大的问题是什么时候该用哪一个?这主要取决于你要处理的场景,但是阅读@jrudolph给出的回复可能会帮助你做出一些决定。

#7


20  

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

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

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):

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

  • 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.

    它增加了封装:考虑两个*类,A和B,其中B需要访问被声明为私有的A的成员。通过在类A中隐藏B类,A的成员可以被声明为私有,B可以访问它们。此外,B本身也可以隐藏在外面的世界。

  • 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.

    它可以导致更易于阅读和可维护的代码:在*类中嵌套小类使代码更接近于使用它的地方。

#8


12  

Nested class: class inside class

嵌套类:类内部类。

Types:

类型:

  1. Static nested class
  2. 静态嵌套类
  3. Non-static nested class [Inner class]
  4. 非静态嵌套类[内部类]

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

如果您想访问x,则编写以下内部方法。

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

#9


9  

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.

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

#10


8  

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'.

然而静态属性在类通过其构造函数实例化之前被实例化,嵌套静态类中的静态属性在类的构造函数被调用之前似乎不会被实例化,或者至少在第一次引用属性之后才会被实例化,即使它们被标记为“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'.

即使“嵌套”和“innerItem”都被声明为“静态final”。嵌套的设置。innerItem直到类被实例化(或者至少在嵌套的静态项被第一次引用之后)才会发生,您可以通过注释和取消我引用的这些行来查看。同样的情况也不适用于“outerItem”。

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

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

#11


8  

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

#12


7  

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.

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

#13


7  

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:

我不认为这里有太多需要补充的地方,大多数的答案完美地解释了静态嵌套类和内部类之间的区别。但是,在使用嵌套类和内部类时考虑以下问题。提到的几个答案内部类不能被实例化,没有和他们的封闭类的实例,意味着他们持有的实例的指针封闭类从而导致内存溢出或堆栈溢出异常是因为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();

}

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

如果您删除// inner = null的注释;这个程序会输出“我被摧毁了!”,但是保持这个注释不会。原因是,白色的内部实例仍然被引用,GC不能收集它,因为它引用(有一个指向)外部实例的指针,它也没有被收集。在项目中拥有足够的这些对象,并且内存不足。与静态内部类相比,它没有指向内部类实例,因为它不是实例相关的,而是类相关的。上面的程序可以打印“我被破坏了!”如果你使内部类静态和实例化的外部。内i = new Outer.Inner();

#14


6  

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.

嵌套类是一个非常通用的术语:不是顶层的每个类都是嵌套类。内部类是一个非静态嵌套类。Joseph Darcy写了一个关于嵌套、内部、成员和*类的很好的解释。

#15


6  

Ummm... an inner class IS a nested class... do you mean anonymous class and inner class?

嗯……内部类是一个嵌套类…你是指匿名类和内部类吗?

Edit: If you actually meant inner vs 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 8 years, and it's the first 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.

*声称Java有区别,但是我已经和Java合作了8年,这是我第一次听到这样的区别。更不必说,这里没有任何证据支持这一说法……底线,内部类是在类中定义的类(静态的或非静态的),嵌套是指同一事物的另一个术语。

There is a subtle difference between static and non-static nested class... 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). Static nested classes, on the other hand, don't have implicit access to instance fields and methods, and CAN be constructed in a static context.

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

#16


5  

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

针对初学者,他们是Java和/或嵌套类的新手。

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

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


1.Inner classes
Example:

1。内部类的例子:

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:

2。静态嵌套类:例如:

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

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

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

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

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

}

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.

结论:在Java中,内部类和静态嵌套类的主要区别是什么?回答:只看上面提到的每一个课程的细节。

#17


4  

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

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

 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).

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

#18


4  

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

#19


4  

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.

Java中的内部类和嵌套静态类都是在另一个类中声明的类,也就是Java中的*类。在Java术语中,如果您声明一个嵌套的类静态,它将在Java中调用嵌套的静态类,而非静态嵌套类被简单地称为内部类。

What is Inner Class in Java?

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:

任何不是*级别或在另一个类中声明的类都被称为嵌套类,并且在这些嵌套类中,被声明为非静态的类被称为Java中的内部类。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.

1)本地内部类——在代码块或方法中声明。匿名内部类——是一个没有名称的类,在创建它的地方初始化。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");
        }
    }
}

What is nested static class in Java?

在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.

嵌套的静态类是另一个类,它在类中声明为成员并使其静态。嵌套的静态类也声明为外部类的成员,可以像其他成员一样进行私有、公开或保护。内嵌静态类的主要好处之一是,嵌套静态类的实例不依附于外部类的任何封闭实例。您也不需要外部类的任何实例来创建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.

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

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

Ref: Java中的内部类和嵌套静态类。

#20


2  

The following is an example of static nested class and inner class:

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

OuterClass.java

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:

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

    }

}

#21


1  

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.

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

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.

但是如果它是静态的,那么这个链接就不存在,外部的字段不能被访问(除非通过像其他对象一样的普通引用),因此您可以自己实例化嵌套的类。

#22


1  

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.

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

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.

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

#23


0  

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

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