2013-04-22 88 views
19

我在我的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

回答

19

如果嵌套類不訪問封閉類的任何變量,則可以將其設爲靜態。這樣做的好處是你不需要外層類的封裝實例來使用嵌套類。

+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

2

非靜態內部類具有對外部類的隱式引用。如果您將該類設爲靜態,則可以保存一些內存和代碼。

7

默認情況下,內部類具有對外部類的對象的隱式引用。如果你從外部類的代碼實例化了這個對象,這一切都是爲你完成的。否則,你需要自己提供對象。

靜態內部類沒有這個。

這意味着它可以在外部類對象的範圍之外實例化。這也意味着,如果您「導出」內部類的實例,它不會阻止收集當前對象。作爲一個基本規則,如果內部類沒有理由訪問外部類,則默認情況下應使其爲靜態。

+0

我愛這個基本規則,就是你定義的。 – roottraveller 2017-09-27 06:46:34

2

靜態內部類是一個語義上更簡單的事情。它就像一個頂級的課程,除了你有更多的可見性選項(例如,你可以將它設爲私密)。

避免非靜態內部類的一個重要原因是它們更復雜。有對外部類的隱藏引用(可能甚至超過一個)。現在,內部類的方法中的簡單名稱可能是三件事之一:本地,外部類或外部類的字段。

這種複雜性的一個神器是對外部類的隱藏引用可能導致內存泄漏。假設內部類是一個監聽器,並且可能是一個靜態的內部類。只要監聽器被註冊,它就擁有對外部類實例的引用,這可能會依次保存大量的內存。使偵聽器靜態可以允許外部實例被垃圾收集。

0

我們已經有了很好的答案,這裏是我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

[爪哇內部類和靜態嵌套類(的
相關問題