Java内部类和静态嵌套类

Java中的内部类和静态嵌套类之间的主要区别是什么? devise/实现在select其中一个方面起作用吗?

从Java教程 :

嵌套类分为两类:静态类和非静态类。 被声明为静态的嵌套类被简单地称为静态嵌套类。 非静态嵌套类称为内部类。

静态嵌套类可以使用包含的类名来访问:

 OuterClass.StaticNestedClass 

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

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

作为内部类实例的对象存在于外部类的实例中。 考虑以下类:

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

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

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

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

请参阅: Java教程 – 嵌套类

为了完整性,请注意,还有一个没有封闭实例的内部类 :

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

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

Java教程说 :

术语:嵌套类分为两类:静态和非静态。 被声明为静态的嵌套类被简单地称为静态嵌套类。 非静态嵌套类称为内部类。

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

类可以无限嵌套,例如,类A可以包含类B,其中包含类C,其包含类D等等。但是,多于一级的类嵌套是罕见的,因为它通常是不好的devise。

有三个原因可以创build一个嵌套类:

  • 组织:有时候把一个类sorting到另一个类的名字空间似乎是最明智的,特别是当它不会被用在任何其他的上下文中时
  • 访问:嵌套类对其包含的类的variables/字段有特殊的访问权(正是哪些variables/字段取决于嵌套类的types,无论是内部的还是静态的)。
  • 方便:不得不为每个新types创build一个新的文件是麻烦的,特别是当这个types只用于一个上下文

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

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

让我详细说明一下。

静态类

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

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

 package pizza; public class Rhino { ... public static class Goat { ... } } 

坦率地说,静态类是一个相当不值钱的function,因为类已经被包分解成名称空间。 创build一个静态类的唯一真正可以想象的理由是这样的类可以访问它的包含类的私有静态成员,但是我觉得这是静态类特性存在的一个非常蹩脚的理由。

内部类

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

 package pizza; public class Rhino { public class Goat { ... } private void jerry() { Goat g = new Goat(); } } 

与静态类一样,内部类被称为包含类名称pizza.Rhino.Goat的限定 ,但是在包含类中,可以通过它的简单名称来知道它。 然而,内部类的每个实例都与其包含的类的特定实例绑定在一起:在上面,在杰里中创build的山羊 ,隐含地与犀牛中的犀牛实例相关联。 否则,当我们实例化山羊时,我们使关联的Rhino实例显式化:

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

(请注意,在奇怪的语法中,将内部types称为“ 山羊 ”:Java推断出犀牛部分的包含types,而且新的rhino.Goat()也会对我更有意义。

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

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

在内部类中,你可以把这个包含类作为Rhino.this来引用,你可以用来引用它的成员, 比如Rhino.this.barry

本地内部类

本地内部类是在方法体内声明的类。 这样的类只在其包含的方法中是已知的,所以它只能被实例化并且在其包含的方法中访问它的成员。 增益是一个本地的内部类实例绑定到并且可以访问其包含方法的最终本地variables。 当实例使用其包含方法的最后一个局部variables时,即使variables超出了范围(这实际上是Java的原始的,限制版本的闭包),variables仍保留在创build实例时保留的值。

由于本地内部类既不是类或包的成员,也不会声明具有访问级别。 (不过要清楚,自己的成员像普通class级那样有访问权限。)

如果在实例方法中声明了一个本地内部类,那么在实例创build时,内部类的实例化与包含方法this所持有的实例相关联,因此包含类的实例成员在实例中是可访问的内心阶层。 一个本地的内部类是简单地通过它的名字来实例化的, 例如,本地内部类Cat被实例化为新的Cat() ,而不是像你所期望的那样新buildthis.Cat()。

匿名内部类

匿名内部类是编写本地内部类的语法上方便的方法。 大多数情况下,每次运行包含的方法时,最多只能实例化一个本地内部类。 那么,如果我们可以将本地的内部类定义和它的单一实例化结合成一个方便的语法forms,那将是很好的,如果我们不需要为这个类考虑一个名字就更好了(越less越不利用您的代码包含的名称越多越好)。 一个匿名的内部类允许这两个东西:

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

这是一个expression式,返回一个扩展ParentClassName的未命名类的新实例。 你不能提供你自己的构造函数; 而是隐式提供的,它只是简单地调用超级构造函数,所以提供的参数必须适合超级构造函数。 (如果父项包含多个构造函数,那么称为“最简单”的构造函数,这是由一组相当复杂的规则决定的,不值得深入研究的规则是最简单的,只要注意NetBeans或Eclipse告诉您的内容)。

或者,您可以指定一个接口来实现:

 new *InterfaceName*() {*members*} 

这样的声明创build了一个扩展Object并实现InterfaceName的未命名类的新实例。 同样,你不能提供你自己的构造函数。 在这种情况下,Java隐含地提供了一个无参数,无所作为的构造函数(所以在这种情况下永远不会有构造函数参数)。

即使你不能给一个匿名的内部类构造函数,你仍然可以使用初始化块(放置在任何方法之外的块)来执行任何设置。

要明确一个匿名的内部类是用一个实例创build一个本地内部类的一个不那么灵活的方法。 如果你想要一个实现多个接口的本地内部类,或者在扩展一些除Object以外的类的同时实现接口,或者指定了它自己的构造函数,那么你就不能创build一个常规的名为local的内部类。

我不认为真正的差异在上述答案中变得清楚。

首先得到正确的条款:

  • 嵌套类是在源代码级别包含在另一个类中的类。
  • 如果使用静态修饰符声明它是静态的
  • 一个非静态的嵌套类被称为内部类。 (我留在非静态嵌套类。)

马丁的回答是正确的。 但是,实际的问题是:声明一个嵌套类的目的是什么?

如果您只想将类保留在一起,或者如果嵌套类仅在封闭类中使用,则可以使用静态嵌套类。 静态嵌套类与其他类没有语义上的区别。

非静态嵌套类是一个不同的野兽。 类似于匿名内部类,这样的嵌套类实际上是闭包。 这意味着他们抓住他们的周围范围和封闭的实例,并使其可访问。 也许一个例子将澄清。 查看容器的这个存根:

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

在这种情况下,您希望从子项目到父容器的引用。 使用非静态嵌套类,这工作没有一些工作。 您可以使用语法Container.this访问Container的封闭实例。

更多的核心解释如下:

如果您查看编译器为非静态嵌套类生成的Java字节码,它可能会变得更加清晰:

 // class version 49.0 (49) // access flags 33 public class Container$Item { // compiled from: Container.java // access flags 1 public INNERCLASS Container$Item Container Item // access flags 0 Object data // access flags 4112 final Container this$0 // access flags 1 public getContainer() : Container L0 LINENUMBER 7 L0 ALOAD 0: this GETFIELD Container$Item.this$0 : Container ARETURN L1 LOCALVARIABLE this Container$Item L0 L1 0 MAXSTACK = 1 MAXLOCALS = 1 // access flags 1 public <init>(Container,Object) : void L0 LINENUMBER 12 L0 ALOAD 0: this ALOAD 1 PUTFIELD Container$Item.this$0 : Container L1 LINENUMBER 10 L1 ALOAD 0: this INVOKESPECIAL Object.<init>() : void L2 LINENUMBER 11 L2 ALOAD 0: this ALOAD 2: data PUTFIELD Container$Item.data : Object RETURN L3 LOCALVARIABLE this Container$Item L0 L3 0 LOCALVARIABLE data Object L0 L3 2 MAXSTACK = 2 MAXLOCALS = 3 } 

正如你可以看到编译器创build一个隐藏的字段Container this$0 。 这是在具有Containertypes的附加参数的构造函数中设置的,以指定封闭的实例。 你不能在源代码中看到这个参数,但是编译器为嵌套类隐式生成它。

马丁的例子

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

会被编译成类似于(在字节码中)

 new InnerClass(outerObject) 

为了完整:

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

我认为上面的答案没有一个能够解释应用程序devise中嵌套类和静态嵌套类之间的真正区别:

概观

嵌套类可以是非静态的,也可以是静态的,在任何情况下都是在另一个类中定义的类嵌套类应该只存在于封闭类中 ,如果嵌套类被其他类(不仅是封闭的)所用,应该被声明为顶级类。

区别

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

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

结论

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

简而言之,我们需要嵌套类,主要是因为Java不提供闭包。

嵌套类是在另一个封闭类的内部定义的类。 它们有两种types – 静态和非静态。

它们被视为封闭类的成员,因此您可以指定四个访问说明符中的任何一个 – private, package, protected, public 。 我们没有这种奢侈的顶级课程,只能宣布public或封装私人。

内部类aka非堆栈类可以访问顶级类的其他成员,即使它们被声明为私有的,而静态嵌套类也不能访问顶级类的其他成员。

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

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

你什么时候使用Inner类?

考虑到Class AClass B相关的情况, Class B需要访问Class A成员,而Class B Class A仅与Class A相关。 内部课程进入图片。

为了创build一个内部类的实例,你需要创build一个外部类的实例。

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

要么

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

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

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

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

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

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

我认为,一般遵循的惯例是这样的:

  • 顶级类中的静态类嵌套类
  • 顶级中的非静态类内部类 ,它还有两种forms:
    • 本地类名 – 在方法或构造函数体的块内声明的类
    • 匿名类 – 其实例在expression式和语句中创build的未命名类

但是,还有其他几点要记住的是:

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

  • 内部类可以访问Outer [parent]类的封闭实例的实例variables。 但是,并不是所有的内部类都包含实例,例如静态上下文中的内部类,就像静态初始化块中使用的匿名类一样。

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

    • new YourClass(){}; 意思是class [Anonymous] extends YourClass {}
    • new YourInterface(){}; 意味着class [Anonymous] implements YourInterface {}

我觉得更大的问题仍然是开放的哪一个使用什么时候? 那么,这主要取决于你正在处理的情况,但阅读由@jrudolph给出的答复可能会帮助你做出一些决定。

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

希望它有帮助!

内部类

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

     Outerclass.InnerClass innerObject = outerObject.new Innerclass(); 
  • 无法定义任何静态成员本身

  • 不能接口声明

静态嵌套类

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

  • 不与任何封闭类的实例关联所以实例化它:

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

相似

  • 两个内部类都可以访问外部类的 私有字段和方法
  • 外部类也可以访问内部类的 私有字段和方法
  • 这两个类都可以有私有的,受保护的或公共访问修饰符

为什么使用嵌套类?

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

  • 这是一种逻辑上将类只用于一个地方的方法:如果一个类只对另一个类有用,那么将其embedded到该类中并将它们保持在一起是合乎逻辑的。 嵌套这样的“帮助类”使得它们的包更加简化。

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

  • 它可以导致更易于读取和维护的代码:在顶层类中嵌套小类可以使代码更接近它的使用位置。

嵌套类:类内的类

types:

  1. 静态嵌套类
  2. 非静态嵌套类[Inner class]

区别:

非静态嵌套类[Inner class]

内部类的非静态嵌套类对象存在于外部类的对象中。 所以外部类的数据成员可以被内部类访问。 所以要创build内部类的对象,我们必须先创build外部类的对象。

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

静态嵌套类

内部类的静态嵌套类对象不需要外部类的对象,因为“静态”这个词表示不需要创build对象。

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

如果你想访问x,那么写下面的内部方法

  outerclass.nestedclass.x; ie System.out.prinltn( outerclass.nestedclass.x); 

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

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

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

在某些情况下,使用嵌套的静态类可能很有用。

尽pipe静态属性在类通过构造函数实例化之前被实例化,但嵌套静态类中的静态属性似乎并没有被实例化,直到类的构造函数被调用之后,或者至less在属性被第一次引用之后才被实例化,即使他们被标记为“最终”。

考虑这个例子:

 public class C0 { static C0 instance = null; // Uncomment the following line and a null pointer exception will be // generated before anything gets printed. //public static final String outerItem = instance.makeString(98.6); public C0() { instance = this; } public String makeString(int i) { return ((new Integer(i)).toString()); } public String makeString(double d) { return ((new Double(d)).toString()); } public static final class nested { public static final String innerItem = instance.makeString(42); } static public void main(String[] argv) { System.out.println("start"); // Comment out this line and a null pointer exception will be // generated after "start" prints and before the following // try/catch block even gets entered. new C0(); try { System.out.println("retrieve item: " + nested.innerItem); } catch (Exception e) { System.out.println("failed to retrieve item: " + e.toString()); } System.out.println("finish"); } } 

即使'nested'和'innerItem'都被声明为“static final”。 nested.innerItem的设置不会发生,直到类被实例化(或者至less直到嵌套的静态项被引用之后),你可以通过注释和取消注释来引用这些行,以上。 这同样不适用于'outerItem'。

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

在创build实例的情况下,非静态内部类的实例是通过引用它定义的外部类的对象来创build的。 这意味着它有sockets实例。 但是静态内部类的实例是通过Outer类的引用创build的,而不是外部对象的引用。 这意味着它没有插入实例。

例如:

 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(); AB obj1 =o.new B();//need of inclosing instance AC obj2 =new AC(); // not need of reference of object of outer class…. } } 

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

 public class Outer { public class Inner {} public static class Nested {} } 

这并不是一个广为接受的定义。

嵌套类是一个非常普遍的术语:每个不是顶层的类都是嵌套类。 内部类是一个非静态的嵌套类。 Joseph Darcy写了关于嵌套,内部,成员和顶级类的非常好的解释。

嗯…一个内部类是一个嵌套类…你的意思是匿名类和内部类?

编辑:如果你真的意味着内部与匿名…一个内部类只是一个类中定义的类,如:

 public class A { public class B { } } 

而匿名类是匿名定义的类的扩展,所以没有定义实际的“类”,如下所示:

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

进一步编辑:

维基百科声称在Java方面有所不同 ,但是我已经和Java一起工作了8年了,这是我第一次听到这样的区别…更不用说那里没有任何引用来支持这个声明…底部行,内部类是在类中定义的类(静态或不是),嵌套只是另一个术语来表示同样的事情。

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

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

 public class Outer { public class Inner { } public Inner inner(){ return new Inner(); } @Override protected void finalize() throws Throwable { // as you know finalize is called by the garbage collector due to destroying an object instance System.out.println("I am destroyed !"); } } public static void main(String arg[]) { Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); // out instance is no more used and should be garbage collected !!! // However this will not happen as inner instance is still alive ie 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();

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

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

1.Inner classes
例:

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

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

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

 class NonEnclosingClass { public static void main(String[] args) { /*instantiate the Nested class that is a static member of the EnclosingClass class: */ EnclosingClass.Nested n = new EnclosingClass.Nested(); n.someMethod(); //prints out "hello" } } 

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

 class EnclosingClass { static class Nested { void anotherMethod() { System.out.println("hi again"); } } public static void main(String[] args) { //access enclosed class: Nested n = new Nested(); n.anotherMethod(); //prints out "hi again" } } 

Specialty of Static classes:

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

结论:
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.

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

What is Inner Class in Java?

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

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

 public class InnerClassTest { public static void main(String args[]) { //creating local inner class inside method ie main() class Local { public void name() { System.out.println("Example of Local class in Java"); } } //creating instance of local inner class Local local = new Local(); local.name(); //calling method from local inner class //Creating anonymous inner class in Java for implementing thread Thread anonymous = new Thread(){ @Override public void run(){ System.out.println("Anonymous class example in java"); } }; anonymous.start(); //example of creating instance of inner class InnerClassTest test = new InnerClassTest(); InnerClassTest.Inner inner = test.new Inner(); inner.name(); //calling method of inner class } //Creating Inner class in Java private class Inner{ public void name(){ System.out.println("Inner class example in java"); } } } 

What is nested static class in Java?

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

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

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

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

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

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

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

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

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

OuterClass.java

 public class OuterClass { private String someVariable = "Non Static"; private static String anotherStaticVariable = "Static"; OuterClass(){ } //Nested classes are static static class StaticNestedClass{ private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable"; //can access private variables declared in the outer class public static void getPrivateVariableofOuterClass(){ System.out.println(anotherStaticVariable); } } //non static class InnerClass{ //can access private variables of outer class public String getPrivateNonStaticVariableOfOuterClass(){ return someVariable; } } public static void accessStaticClass(){ //can access any variable declared inside the Static Nested Class //even if it private String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable; System.out.println(var); } } 

OuterClassTest:

 public class OuterClassTest { public static void main(String[] args) { //access the Static Nested Class OuterClass.StaticNestedClass.getPrivateVariableofOuterClass(); //test the private variable declared inside the static nested class OuterClass.accessStaticClass(); /* * Inner Class Test * */ //Declaration //first instantiate the outer class OuterClass outerClass = new OuterClass(); //then instantiate the inner class OuterClass.InnerClass innerClassExample = outerClass. new InnerClass(); //test the non static private variable System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass()); } } 

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

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

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

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

Difference between using Nested class and regular Inner class is:

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

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

But if Class is Nested then syntax is:

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

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

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

  class Outter1 { String OutStr; Outter1(String str) { OutStr = str; } public void NonStaticMethod(String st) { String temp1 = "ashish"; final String tempFinal1 = "ashish"; // below static attribute not permitted // static String tempStatic1 = "static"; // below static with final attribute not permitted // static final String tempStatic1 = "ashish"; // synchronized keyword is not permitted below class localInnerNonStatic1 { synchronized public void innerMethod(String str11) { str11 = temp1 +" sharma"; System.out.println("innerMethod ===> "+str11); } /* // static method with final not permitted public static void innerStaticMethod(String str11) { str11 = temp1 +" india"; System.out.println("innerMethod ===> "+str11); }*/ } // static class not permitted below // static class localInnerStatic1 { } } public static void StaticMethod(String st) { String temp1 = "ashish"; final String tempFinal1 = "ashish"; // static attribute not permitted below //static String tempStatic1 = "static"; // static with final attribute not permitted below // static final String tempStatic1 = "ashish"; class localInnerNonStatic1 { public void innerMethod(String str11) { str11 = temp1 +" sharma"; System.out.println("innerMethod ===> "+str11); } /* // static method with final not permitted public static void innerStaticMethod(String str11) { str11 = temp1 +" india"; System.out.println("innerMethod ===> "+str11); }*/ } // static class not permitted below // static class localInnerStatic1 { } } // synchronized keyword is not permitted static class inner1 { static String temp1 = "ashish"; String tempNonStatic = "ashish"; // class localInner1 { public void innerMethod(String str11) { str11 = temp1 +" sharma"; str11 = str11+ tempNonStatic +" sharma"; System.out.println("innerMethod ===> "+str11); } public static void innerStaticMethod(String str11) { // error in below step str11 = temp1 +" india"; //str11 = str11+ tempNonStatic +" sharma"; System.out.println("innerMethod ===> "+str11); } //} } //synchronized keyword is not permitted below class innerNonStatic1 { //This is important we have to keep final with static modifier in non // static innerclass below static final String temp1 = "ashish"; String tempNonStatic = "ashish"; // class localInner1 { synchronized public void innerMethod(String str11) { tempNonStatic = tempNonStatic +" ..."; str11 = temp1 +" sharma"; str11 = str11+ tempNonStatic +" sharma"; System.out.println("innerMethod ===> "+str11); } /* // error in below step public static void innerStaticMethod(String str11) { // error in below step // str11 = tempNonStatic +" india"; str11 = temp1 +" india"; System.out.println("innerMethod ===> "+str11); }*/ //} } }