在Java的静态嵌套类,为什么呢?在Java的静态嵌套类,为什么呢?(Static nested c

2019-05-09 08:49发布

我一直在寻找的Java代码LinkedList ,并注意到它利用一个静态嵌套类的Entry

public class LinkedList<E> ... {
...

 private static class Entry<E> { ... }

}

什么是使用静态嵌套类,而不是一个正常的内部类的原因吗?

我能想到的唯一原因,是项没有访问实例变量,所以从一个面向对象的角度它有更好的封装。

不过,我想可能有其他原因,也许性能。 什么可能是什么?

注意。 我希望我已经得到了我来说是正确的,我会叫一个静态内部类,但我认为这是错误的: http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

Answer 1:

您链接到Sun页面有两个之间的一些主要区别:

嵌套类是它包围类的成员。 非静态内部类(内部类)可以访问外部类中的其他成员,即使它们被声明为private。 静态嵌套类不具有访问封闭类的其他成员。
...

注:Static Nested Class和其外部类的实例成员(其他类)就像任何其他的顶级类交互。 实际上,静态嵌套类是行为上已经嵌套在另一个顶层类用于包装方便顶层类。

有没有必要LinkedList.Entry是顶层类,因为它LinkedList (也有一些其他接口也有一个名为静态嵌套类Entry ,如Map.Entry -同一概念)。 而且因为它并不需要访问链表的成员,它是有道理的,它是静态的 - 这是一个更清洁的方式。

作为乔恩斯基特指出 ,我认为这是一个好主意,如果你使用的是嵌套类是与它是静态的开始,然后再决定是否真的需要根据您的使用是非静态的。



Answer 2:

在我看来,这个问题应该是,每当你看到一个内部类倒过来-它真正需要的是一个内部类,具有额外的复杂性和隐式的(而不是明确和清晰,IMO)参考实例包含类的?

你要知道,我有偏见的C#风扇 - C#没有内部类的等价物,但它确实有嵌套类型。 我不能说我已经错过了内部类尚未:)



Answer 3:

有不明显的内存保留问题考虑到这里。 由于非静态内部类维护它的“外”类的隐式引用,如果内部类的一个实例强烈引用,则外实例强烈引用过。 这可能会导致一些头部划伤外类没有垃圾回收的时候,尽管它看起来像是没什么引用它。



Answer 4:

那么,对于一两件事,非静态内部类有指向外部类的实例一个额外的隐藏字段。 因此,如果Entry类是不是静态的,那么除了具有存取,它并不需要,它会携带四个指针,而不是三个。

作为一个规则,我会说,如果你定义一个类,基本上是有来充当数据成员的集合,就像在C“结构”,可考虑将其静态的。



Answer 5:

静态嵌套类,就像任何其他的外部类,因为它不能访问外部类的成员。

只是为了方便包装我们可以静俱乐部嵌套类到一个外部类的可读性目的。 除此之外还有静态嵌套类没有其他使用情况。

例如,对于这样的一种用法,你可以在Android的R.java(资源)文件中找到。 机器人的res文件夹中包含的布局(含有的屏幕设计),可绘制文件夹(包含用于项目的图像),值的文件夹(其中包含字符串常量)等。

正弦所有的文件夹都res文件夹的一部分,Android的工具生成内部含有大量的静态嵌套类的每一个自己内心的文件夹的R.java(资源)文件。

这里采用的是Android生成R.java文件的外观和感受:在这里,他们只使用包装的方便。

/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 *
 * This class was automatically generated by the
 * aapt tool from the resource data it found.  It
 * should not be modified by hand.
 */

package com.techpalle.b17_testthird;

public final class R {
    public static final class drawable {
        public static final int ic_launcher=0x7f020000;
    }
    public static final class layout {
        public static final int activity_main=0x7f030000;
    }
    public static final class menu {
        public static final int main=0x7f070000;
    }
    public static final class string {
        public static final int action_settings=0x7f050001;
        public static final int app_name=0x7f050000;
        public static final int hello_world=0x7f050002;
    }
}


Answer 6:

静态内部类在生成器模式中使用。 静态内部类可以实例是它只有私有的构造外类。 所以,你可以使用静态内部类实例化外部类只具有私有的构造函数。 因为你需要有之前访问内部类创建外部类的对象不能做同样的内部类。

class OuterClass {
    private OuterClass(int x) {
        System.out.println("x: " + x);
    }

    static class InnerClass {
        public static void test() {
            OuterClass outer = new OuterClass(1);
        }
    }
}

public class Test {
    public static void main(String[] args) {
        OuterClass.InnerClass.test();
        // OuterClass outer = new OuterClass(1); // It is not possible to create outer instance from outside.
    }
}

这将输出x 1



Answer 7:

从http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html :

如果您需要访问一个类实例的非公共字段和方法使用非静态嵌套类(或内部类)。 使用静态嵌套类,如果你不需要这样的访问。



Answer 8:

简单的例子:

package test;

public class UpperClass {
public static class StaticInnerClass {}

public class InnerClass {}

public static void main(String[] args) {
    // works
    StaticInnerClass stat = new StaticInnerClass();
    // doesn't compile
    InnerClass inner = new InnerClass();
}
}

如果非静态的类不能被exept在上部类的实例实例化(因此不是在主要是静态函数的例子)



Answer 9:

其中一个原因静态还是正常有类加载做。 它的父母,你不能在构造函数实例化一个内部类。

PS:我始终明白“套”和“内”是可以互换的。 有可能是在条款的细微差别,但大多数Java开发人员会明白无论是。



Answer 10:

非静态内部类可以导致内存泄漏而静态内部类将防止他们。 如果外部类拥有相当大的数据,它可以降低应用程序的性能。



Answer 11:

我不知道性能差异,但正如你所说,Static Nested Class和不封闭的类的实例的一部分。 似乎只是简单的创建一个静态嵌套类,除非你真的需要它是一个内部类。

这是一个有点像,为什么我总是最后在Java中我的变量 - 如果他们不是最终的,我知道有和他们一起去上一些有趣的事情。 如果你使用一个内部类,而不是一个静态的嵌套类的,应该有一个很好的理由。



Answer 12:

使用静态嵌套类,而不是非静态的可节省在某些情况下的空间。 例如:实现一个Comparator类里面,说学生。

public class Student {
  public static final Comparator<Student> BY_NAME = new ByName();
  private final String name;
  ...
  private static class ByName implements Comparator<Student> {
    public int compare() {...}
  }
}

然后static确保学生类只有一个比较,而不是实例化一个新的每次创建一个新的学生实例时。



Answer 13:

内部分类 - 的Adavantage

  1. 一次性使用
  2. 支持并提高封装
  3. 可读性
  4. 私有字段访问

如果没有外部类内部类的存在将不存在。

class car{
    class wheel{

    }
}

有四种类型的内部类。

  1. 正常内部类
  2. 方法局部内部类
  3. 匿名内部类
  4. 静态内部类

点---

  1. 从静态内部类,我们只能访问外部类的静态成员。
  2. 内部内部类,我们cananot声明静态成员。
  3. 序来调用正常内部类在外部类的静态区域。

    Outer 0=new Outer(); Outer.Inner i= O.new Inner();

  4. 序来调用在外部类的实例区域正常内部类。

    Inner i=new Inner();

  5. 序来调用正常内部类在外部类的外部。

    Outer 0=new Outer(); Outer.Inner i= O.new Inner();

  6. 内部类内该指针至内部类。

    this.member-current inner class outerclassname.this--outer class

  7. 对于内部类适用修改为 - 大众,默认情况下,

    final,abstract,strictfp,+private,protected,static

  8. 外$内是内部类的名称。

  9. 实例方法中的内部类那么我们就可以接取外部类的静态和实例字段。

静态方法里面10.inner类,那么我们就可以访问的唯一的静态字段

外部类。

class outer{

    int x=10;
    static int y-20;

    public void m1() {
        int i=30;
        final j=40;

        class inner{

            public void m2() {
                // have accees x,y and j
            }
        }
    }
}


文章来源: Static nested class in Java, why?