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


当前回答

从Java教程:

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

使用封闭类名访问静态嵌套类:

OuterClass.StaticNestedClass

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

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

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

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

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

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

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

请参见:Java教程-嵌套类

为了完整性,请注意还有这样一种东西,即没有封闭实例的内部类:

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

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

其他回答

嗯……内部类是嵌套类……您是指匿名类和内部类吗?

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

public class A {
    public class B {
    }
}

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

public class A {
}

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

进一步编辑:

维基百科声称Java存在差异,但我已经用Java工作了八年,这是我第一次听到这样的区别——更不用说那里没有引用来支持这一说法……总之,内部类是在类中定义的类(静态或非静态),嵌套只是另一个意思相同的术语。

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

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

例如:

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 Outer {
    public class Inner {}

    public static class Nested {}
}

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

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

概述

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

差别

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

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

结论

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

从Java教程:

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

使用封闭类名访问静态嵌套类:

OuterClass.StaticNestedClass

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

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

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

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

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

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

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

请参见:Java教程-嵌套类

为了完整性,请注意还有这样一种东西,即没有封闭实例的内部类:

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

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