Java中的内部类和静态嵌套类之间的主要区别是什么? 设计/实施在选择其中一项方面是否起做用? 闭包
我认为上述答案都不能向您说明在应用程序设计方面嵌套类和静态嵌套类之间的真正区别: 函数
嵌套类能够是非静态的,也能够是静态的,而且在每种状况下都是在另外一个类中定义的类 。 嵌套类仅应存在于封闭类中 ,若是嵌套类对其余类(不单单是封闭类)有用,则应将其声明为顶级类。 this
非静态嵌套类 :与包含类的封闭实例隐式关联,这意味着能够调用封闭实例的方法和访问变量。 非静态嵌套类的一种常见用法是定义Adapter类。 spa
静态嵌套类 :没法访问封闭类实例并在其上调用方法,所以当嵌套类不须要访问封闭类实例时,应使用此方法。 静态嵌套类的常见用法是实现外部对象的组件。 设计
所以,从设计的角度来看,二者之间的主要区别是: 非静态嵌套类能够访问容器类的实例,而静态不能 。 code
首先没有这样的类称为静态类。内部类使用的static修饰符(称为嵌套类)表示它是外部类的静态成员,这意味着咱们能够像其余静态成员同样访问它,而无需任何其余外部类的实例。 (这本来是静态的。) 对象
使用嵌套类和常规内部类的区别是: get
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
首先,咱们能够实例化外部类,而后能够访问内部。 it
可是,若是Class为Nested,则语法为: io
OuterClass.InnerClass inner = new OuterClass.InnerClass();
它使用static语法做为static关键字的常规实现。
简单来讲,咱们须要嵌套类,主要是由于Java不提供闭包。
嵌套类是在另外一个封闭类的主体内部定义的类。 它们有两种类型-静态和非静态。
它们被视为封闭类的成员,所以您能够指定四个访问说明符中的任何一个private, package, protected, public
。 顶级类没有这种奢侈,只能将其声明为public
或package-private。
内部类(也称为非堆栈类)能够访问顶级类的其余成员,即便它们被声明为私有的,而静态嵌套类也不能访问顶级类的其余成员。
public class OuterClass { public static class Inner1 { } public class Inner2 { } }
Inner1
是咱们的静态内部类,而Inner2
是咱们的非静态内部类。 它们之间的主要区别在于,若是没有Outer,就没法建立Inner2
实例,由于能够单首创建Inner1
对象。
您何时使用内部课程?
考虑一下Class A
和Class B
相关的状况, Class B
须要访问Class A
成员,而Class B
Class A
仅与Class A
有关。 内部类进入画面。
要建立内部类的实例,您须要建立外部类的实例。
OuterClass outer = new OuterClass(); OuterClass.Inner2 inner = outer.new Inner2();
要么
OuterClass.Inner2 inner = new OuterClass().new Inner2();
何时使用静态内部类?
当您知道静态内部类与封闭类/顶级类的实例没有任何关系时,能够定义它。 若是您的内部类不使用外部类的方法或字段,则只会浪费空间,所以请将其设为静态。
例如,要为静态嵌套类建立一个对象,请使用如下语法:
OuterClass.Inner1 nestedObject = new OuterClass.Inner1();
静态嵌套类的优势是它不须要包含类/顶级类的对象便可工做。 这能够帮助您减小应用程序在运行时建立的对象数量。
在建立实例的状况下,非静态内部类的实例是使用定义了外部类的对象的引用建立的。 这意味着它具备封闭实例。 可是,静态内部类的实例是使用外部类的引用而不是外部类的对象的引用建立的。 这意味着它没有封闭实例。
例如:
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…. } }
关于嵌套静态类的使用有些微妙之处,在某些状况下可能有用。
静态属性是在经过类的构造函数实例化该类以前实例化的,而嵌套的静态类内部的静态属性彷佛直到该类的构造函数被调用以后才被实例化,或者至少在首次引用该属性以后才实例化,即便它们被标记为“最终”。
考虑如下示例:
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的设置才会发生,您能够经过注释和取消注释我所引用的行来亲自看到,以上。 'outerItem'并不是如此。
至少这是我在Java 6.0中看到的。