【问题标题】:Java: Static vs inner class [duplicate]Java:静态与内部类[重复]
【发布时间】:2010-11-24 02:38:04
【问题描述】:

静态和非静态嵌套类有什么区别?

【问题讨论】:

  • Java doc Terminology:嵌套类分为静态和非静态两类。声明为静态的嵌套类称为静态嵌套类。非静态嵌套类称为内部类。

标签: java static inner-classes


【解决方案1】:

内部类by definition 不能是静态的,所以我将把您的问题改写为“静态嵌套类和非静态嵌套类有什么区别?”

非静态嵌套类可以完全访问它所嵌套的类的成员。静态嵌套类没有对嵌套实例的引用,因此静态嵌套类不能调用非静态方法或访问它所嵌套的类实例的非静态字段。

【讨论】:

  • 好答案。从实例访问静态成员是如此不合逻辑。应该只能通过SomeClass.StaticMember 或在SomeClass 内部,通过StaticMember(没有this.)访问静态成员,那么我们根本不会得到这些问题。
  • @Brandon:当您说“静态嵌套类不能调用非静态方法或访问它所嵌套的类实例的非静态字段”时。 ...这意味着没有创建封闭类的对象对吗?因为在我看来,嵌套静态类在行为上是一个顶级类,为了方便打包,它已经嵌套在另一个顶级类中。因此,应该可以通过对象访问非静态成员。
【解决方案2】:

让我们看看这些问题的智慧来源:Joshua Bloch's Effective Java

从技术上讲,不存在静态内部类。根据Effective Java,正确的术语是静态嵌套类。非静态嵌套类确实是一个内部类,还有匿名类和本地类。

现在引用:

非静态嵌套类的每个实例都是隐式关联的 带有其包含类的封闭实例...这是可能的 调用封闭实例上的方法。

静态嵌套类无权访问封闭实例。它使用的空间也更少。

【讨论】:

  • 我只是在读它。第 22 条:支持静态成员类而不是非静态成员类
  • Bloch 还指出,在不必要的非静态内部类中对封闭实例的引用可能会阻止垃圾收集(如果保留)。
  • 什么时候比另一个更受欢迎?
  • 根据Java 语言规范,不存在静态内部类。 Bloch 的书可能不错,但 JLS 是这里唯一的规范参考。
  • 阅读此答案中的引文,我认为它与 JLS 不矛盾。相反,它似乎证实了这一点。
【解决方案3】:

静态内部类和非静态内部类有两个区别。

  1. 在声明成员字段和方法的情况下,非静态 内部类不能有静态字段和方法。 但是,在静态内部类的情况下,可以有静态和非静态字段 和方法。

  2. 使用引用创建非静态内部类的实例 定义了外部类的对象,这意味着它具有 封闭实例。但是静态内部类的实例是 在没有引用外部类的情况下创建,这意味着它确实 没有封闭实例。

看这个例子

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 a = new A();

        // Non-Static Inner Class
        // Requires enclosing instance
        A.B obj1 = a.new B(); 

        // Static Inner Class
        // No need for reference of object to the outer class
        A.C obj2 = new A.C(); 
    }
}

【讨论】:

  • 因为其中一个都不存在,所以差别是无限的。
  • 例子真的很有帮助=)
  • 在一个示例中解决了两个疑问(静态/非静态),非常整洁!
【解决方案4】:
  1. 静态内部类不能访问封闭类的非静态成员。它可以直接访问封闭类的静态成员(实例字段和方法),就像在不创建对象的情况下获取值的过程风格一样。

  2. 静态内部类可以声明静态和非静态成员。静态方法可以访问主类的静态成员。但是,它不能访问非静态内部类成员。要访问非静态内部类的成员,必须创建非静态内部类的对象。

  3. 非静态内部类不能声明静态字段和静态方法。它必须以静态或顶级类型声明。如果说“静态字段仅在静态或顶级类型中声明”,您将收到此错误。

  4. 非静态内部类可以通过获取值的过程方式访问封闭类的静态和非静态成员,但不能访问静态内部类的成员。

  5. 封闭类在创建内部类的对象之前不能访问内部类的成员。 IF主类在访问非静态类的成员时可以创建非静态内部类的对象。

  6. 如果主类在访问静态内部类的成员时有两种情况:

    • 案例一:对于静态成员,可以使用静态内部类的类名
    • 案例2:对于非静态成员,可以创建静态内部类的实例。

【讨论】:

  • 请您修正一下“如果主类访问非静态类成员”或“如果主类访问静态内部类成员”等地方的语法。我不知道你想说什么。
【解决方案5】:

讨论嵌套类...

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

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

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

【讨论】:

    【解决方案6】:

    静态内部类:可以声明静态和非静态成员,但只能访问其父类的静态成员。

    非静态内部类:只能声明非静态成员,但可以访问其父类的静态和非静态成员。

    【讨论】:

    • 没有“静态内部类”,(非静态)内部类可以声明某种静态成员。 JLS 8.1.3:An inner class is a nested class that is not explicitly or implicitly declared static. [...] Inner classes may not declare static members, unless they are compile-time constant fields (§15.28).
    【解决方案7】:

    内部类不能是静态的,所以我将把你的问题改写为“静态和非静态嵌套类有什么区别?”。

    正如你所说,内部类不能是静态的......我发现下面的代码被赋予了静态......原因?或者哪个是正确的......

    是的,静态嵌套类型的语义中没有任何东西可以阻止您这样做。这个 sn-p 运行良好。

        public class MultipleInner {
            static class Inner {
            }   
        public static void main(String[] args) {
            for (int i = 0; i < 100; i++) {
                new Inner();
            }
        }
    }
    

    这是张贴在本网站的代码...

    问题--->一个静态嵌套类可以实例化多次吗?

    答案是--->

    现在,嵌套类型当然可以进行自己的实例控制(例如私有构造函数、单例模式等),但这与它是嵌套类型这一事实无关。另外,如果嵌套类型是静态枚举,当然根本无法实例化。

    但一般来说,是的,一个静态嵌套类型可以被实例化多次。

    请注意,从技术上讲,静态嵌套类型不是“内部”类型。

    【讨论】:

      【解决方案8】:

      静态嵌套类与其外部类(和其他类)的实例成员交互,就像任何其他顶级类一样。实际上,静态嵌套类在行为上是一个顶级类,为了方便打包,它已经嵌套在另一个顶级类中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-27
        • 1970-01-01
        • 2015-02-16
        • 1970-01-01
        • 2011-05-10
        • 1970-01-01
        • 2015-04-28
        • 1970-01-01
        相关资源
        最近更新 更多