使用Java将内部类设为静态有什么优势?

问题描述:

我在我的Java类中有一个内部类。使用Java将内部类设为静态有什么优势?

enter image description here

当我运行find bugs,它建议(警告),使其为静态。

enter image description here

这是什么警示意义?将内部类设为静态的优点是什么?

+0

可能重复http://stackoverflow.com/questions/70324/java-inner-中找到类和静态嵌套类) – andyb 2013-04-22 12:46:01

+0

链接的问题是*不重复 - 它不表示使内部类静态的优点或缺点。 – Perception 2013-04-22 13:09:21

+0

可能重复[静态嵌套类在Java中,为什么?](http://stackoverflow.com/questions/253492/static-nested-class-in-java-why) – fglez 2013-04-23 14:10:57

如果嵌套类不访问封闭类的任何变量,则可以将其设为静态。这样做的好处是你不需要外层类的封装实例来使用嵌套类。

+0

+1我刚碰到这个问题创建一个我的药水类的法力药水,但忘了宣布它是静态的,因此无法宣布新的ManaPotion()。 – arynaq 2013-04-22 12:58:54

+1

@arynaq - 继承是一个强烈的指标,指出'ManaPotion'不应该成为'Potion'的内部类。一个好的例子是使用Map.Entry实例来保存它的条目的Map。 “药水”会使用“Potion.ManaPotion”吗?这适用于静态内部类。 – 2013-04-22 16:41:29

+0

的确,这是为了测试的缘故,这几乎是我使用嵌套类的唯一时间。 – arynaq 2013-04-23 10:44:27

非静态内部类具有对外部类的隐式引用。如果您将该类设为静态,则可以保存一些内存和代码。

默认情况下,内部类具有对外部类的对象的隐式引用。如果你从外部类的代码实例化了这个对象,这一切都是为你完成的。否则,你需要自己提供对象。

静态内部类没有这个。

这意味着它可以在外部类对象的范围之外实例化。这也意味着,如果您“导出”内部类的实例,它不会阻止收集当前对象。作为一个基本规则,如果内部类没有理由访问外部类,则默认情况下应使其为静态。

+0

我爱这个基本规则,就是你定义的。 – roottraveller 2017-09-27 06:46:34

静态内部类是一个语义上更简单的事情。它就像一个顶级的课程,除了你有更多的可见性选项(例如,你可以将它设为私密)。

避免非静态内部类的一个重要原因是它们更复杂。有对外部类的隐藏引用(可能甚至超过一个)。现在,内部类的方法中的简单名称可能是三件事之一:本地,外部类或外部类的字段。

这种复杂性的一个神器是对外部类的隐藏引用可能导致内存泄漏。假设内部类是一个监听器,并且可能是一个静态的内部类。只要监听器被注册,它就拥有对外部类实例的引用,这可能会依次保存大量的内存。使侦听器静态可以允许外部实例被垃圾收集。

我们已经有了很好的答案,这里是我5毛钱:

静态和非静态的,当我们需要分开但使用的方法和外部类的变量的逻辑功能的内部类中使用。两个内部类都可以访问外部类的私有变量。静态内部类的

优点: 1)静态类可以从外部类访问静态变量 2)静态类可以像一个独立的类被处理

非静态内部类: 1)不能使用

0123:外部类 2)的静态成员不能像独立的类

public class NestedClassDemo { 
    private int a = 100; 
    int b = 200; 
    private static int c = 500; 

    public NestedClassDemo() { 
     TestInnerStatic teststat = new TestInnerStatic(); 
     System.out.println("const of NestedClassDemo, a is:"+a+", b is:"+b+".."+teststat.teststat_a); 
    } 

    public String getTask1(){ 
     return new TestInnerClass().getTask1(); 
    } 

    public String getTask2(){ 
     return getTask1(); 
    } 


    class TestInnerClass{ 
     int test_a = 10; 

     TestInnerClass() { 
      System.out.println("const of testinner private member of outerlcass"+a+"..."+c); 
     } 
     String getTask1(){ 
      return "task1 from inner:"+test_a+","+a; 
     } 
    } 

    static class TestInnerStatic{ 
     int teststat_a = 20; 

     public TestInnerStatic() { 
      System.out.println("const of testinnerstat:"+teststat_a+" member of outer:"+c); 
     } 

     String getTask1stat(){ 
      return "task1 from inner stat:"+teststat_a+","+c; 
     } 
    } 

    public static void main(String[] args){ 
     TestInnerStatic teststat = new TestInnerStatic(); 
     System.out.println(teststat.teststat_a); 
     NestedClassDemo nestdemo = new NestedClassDemo(); 
     System.out.println(nestdemo.getTask1()+"...."+nestdemo.getTask2()); 
    } 
} 

访问来自外部的静态内部和非静态内部类进行处理

public class TestClass { 
    public static void main(String[] args){ 
     NestedClassDemo.TestInnerClass a = new NestedClassDemo().new TestInnerClass(); 
     NestedClassDemo.TestInnerStatic b = new NestedClassDemo.TestInnerStatic(); 
    } 
} 

静态内部类的官方Java文档可以在https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

[爪哇内部类和静态嵌套类(的