java中類的定義位置與分類

在java中,類最常見的定義位置是文件中,一個文件中可以定義多個類,但是只能有一個public的類,而且java文件名必須和這個public類相同。看看下面代碼

package com.senmu.pack_a
//TestA.java
public class TestA{}
class TestB{}
class TestC{}

這裏有一個TestA.java的源文件,裏面定義了三個class。可以看出一個源文件裏能定義多個class,但是有且只能有一個public類,非public類的名字只要符合java標識符規則就可以,public類的名字必須和源文件名一致。至於爲什麼有這個規定,很多網上的帖子都說是爲了方便JVM根據文件名找到main函數入口,個人覺得這種說法不太可信也不太合理。原因如下,JVM讀取的是編譯後的.class文件而不是.java源文件,而定義在一個源文件中的多個類編譯後都生成了由各自類名命名的.class文件。在我看來當初java的設計者這樣規定的主要目應該是爲了給源碼閱讀提供便利,試想一下如果一個源文件中可以有多個public的class而且名字與源文件名不一致,那麼當我們在閱讀代碼時想要了解某個引用類的定義情況應該去哪找這個類的源代碼呢?當有了這個規定之後我們就可以根據import的包名和類名準確找到源文件的位置。至於源文件中的其他非public類,他們只能被本包內的類使用,使用範圍有限,命名也就沒有嚴格要求了。

類除了可以定義在文件中還可以定義在其他類中。定義在其他類中的類成爲內部類,內部類又可以分成成員內部類和內嵌內部類,其區別在於是否被static修飾符修飾。成員內部類可以訪問外部類的所有成員屬性和方法,內嵌內部類和普通類沒有什麼區別只是加了外部類命名限定而已。如下面代碼。

package com.senmu.pack_a
//TestA.java
public class TestA{
    private int f1;
    private int f2;

    public TestA(int f1,int f2){
        this.f1 = f1;
        this.f2 = f2;
    }
    public int cal{
        return new TestAInner1().cal();//在外部類中可以像普通類一樣使用
    }
    public class TestAInner1{
        public int cal(){
            return f1+f2;//成員內部類可以直接訪問外部類的所有公有及私有屬性。
        }
    }
    public static class TestInner2{
        public int cal(){
            //return f1+f2 編譯錯誤,因爲內嵌內部類不能訪問外部類的成員屬性。
        return 0;
        }
    }
}
package com.senmu.pack_b
import com.senmu.pack_a.TestA;
//TestB.java
public class TestB{
    private TestA.TestAInner ti = new TestA.TestAInner();//TestA.TestInner是內嵌內部類,可以和普通類一樣使用
    public void test(){
        TestA ta = new TestA();
        ta.new TestInner1().cal();//在其他類中使用TestA的成員內部類。

    }
}

最後,java中的類還可以定義在方法中,定義在方法中的類只能在方法中使用,可以看到所有對方法可見的變量。

package com.senmu.pack_a
//TestA.java
public class TestA{
    private int f1;
    private int f2;

    public TestA(int f1,int f2){
        this.f1 = f1;
        this.f2 = f2;
    }
    public int cal(int a){
        class MethodInner{
            public int test(){
                return a + f1 +f2;//方法中內部類可以訪問對方法可見所以變量
            }
        }
        return new MethodInner().test();//方法中的內部類只能在本方法中使用。
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章