1. 程式人生 > >Static Nested Class(巢狀類) 和 Inner Class(內部類)的不同

Static Nested Class(巢狀類) 和 Inner Class(內部類)的不同

前言:
本來是想總結一下inner class 的用法,但是卻發現這幾位頗為親近。索性一起拉出來溜溜。
寫作目的:
跟 static , final, inner class 搞好關係,以便將來遇見了,就像用if ,else一樣,一清二楚。
文中的術語定義以java language spec為準。

先想想,要關注的是那些地方?
1。語法。 (code, 我們吃飯的傢伙)
2。語義。 (其實寫程式碼也就是為了這個)
3。怎麼用簡單,可人的結構來表達語義。(這也是每個程式設計師追求的)
語義無限的,語法是Limited, 我們要理解不同的語法所表現的語義,這是本文的重點。

1。final 篇
final 做為一個獨立的存在,也表現的與眾不同。一般情況都可以理解為 can't be changed.
1)final data: 實現constant語義。說明這個值:在編譯時不會變;在執行時也不能被改變。
在java中,提供了blank final:允許大家將初始化的動作延遲到constructor中。這是極限,有編譯器保證。
2)final parameter: 同上語義。
3)final method:
a)防止子類overriden.(注:這個角度,private 隱含了final語義) b)efficiency: 允許編譯器轉換呼叫為inline call.
4)final class: 拒絕inherited.

2。static 篇
1。定義:static is modifier.本想找一個權威的定義給大家,才發現此物沒有特定範圍。也就意味著可能明天還有新的用法,也說明了語言的無限擴充套件性。不得以,我們只好在此註明:以下用法為java 1.5 之前的說明:

閒言碎語:這 static 可不得了,跟誰沾上整個就變質了。如果你想標榜獨立個性,請用。static 一上,就表明 “我是人民的公僕,你只要找得著我,就可以讓我為您服務“。它屬於定義層次,在jvm層次獨一無二。從另一個角度上,它只能用於成員定義。我們不能定義一個 top-level class 為static.
public static class Outest { // compile error
...;
}

裝載:
因為static成員(include field, method, nested class)是在儲存在類定義層次的,只要任何與其類相關的操作,均會產生它的初始化動作。(也就意味著,它已經準備就緒,你只要想用就用。classname.staticMember)

所有的static object/primitive and static block,按照先來後到的順序執行初始化操作。
與其他一樣。

可以用在:
1)static import (static import ...)
single-static-import declaration: import static TypeName.Identifier 使得訪問標識得以簡化。(簡單,無二義)
2) static initializer: (static {}):
完成一段初始化操作.常見用法:
3) static field: (static type field)
static field : 別名:class variable ;
non-static fileds: 別名:instance variable.
4) static method: (static type method())
同上。
5)static member type.( member class & member interface:
此處放在 nested class 部分講解)

jvm是實現這些java程式語義的根源:類變數是作為型別資訊的一部分儲存在方法區(jvm放置類定義的記憶體結構)。jvm在使用類之前,必須在方法區中為這些類變數分配空間。所以類變數是所有類例項共享的,即使沒有任何類例項,它也可以被訪問。這些變數只與類有關。

下面是重頭戲:nested class.
3。nested class 篇
說到類定義,我們先看看有那些值得關注的:
在java中,類宣告的表現形式可以分為兩種:
1)top level class:
2)nested class:
define: nestd class is any class whose declaration occurs within the body of another class or interface.
top level class is a class that is not a nested class.

而在nested class 我們需要特殊關注的是inner class, local class, anonymous class的用法。
在討論下面兩種特殊定義時,我們先看看一個重要概念:inner class.
1)An inner class is a nested class that is not explicitly or implicitly declared
static. Inner classes may not declare static initializers or member interfaces.
Inner classes may not declare static members, unless they are compile-time
constant fields。(對內部類的限制:不能宣告static 初始化操作)
在這裡我要澄清一點:Nested class != inner class, inner class 是一種特殊的 Nested class.Bruce 大叔在thinking java 3rd中混餚了這兩個概念。(汗,直到寫此文時我才究正過來,還好我寫得時候把 java language spec和 jvm spec 拿來參考)
看看inner class 的表現形式吧。
/* 普通的情況 */
class HasStatic{
static int j = 100;
|
class Outer{
class Inner extends HasStatic {
static final int x = 3; // ok - compile-time constant
static int y = 4; // compile-time error, an inner class
}
static class NestedButNotInner {
static int z = 5; // ok, not an inner class
}
interface NeverInner{} // interfaces are never inner
}


2)local class: is a nested class that is not a member of any class and that has a name. all local classes are inner classes. local class 不能用public, protected, private, or static宣告(編譯錯誤).
從定義中我們可以看出,它的生命期是 block scope.比較local variable的形式,就不難理解其語義。同樣你也不能用modifier(public/static etc.)去定義一個區域性變數。
e.p
class Test {
public static void main (String[] args) {
int i ;
// public class Local{} : compile error: illegal start of expression
class Local {
{
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}

public void p() {
System.out.println("call local class p():");
}
}
Local l = new Local();
l.p();
}
}
3)anonymous class:is automatically derived from a class instance creation expression by the compiler.
:1.never abstract; 2.inner class; 3.never static; 4.impicitly final.
interface Contents{};
public class Parcel6 {
public Contents cont() {
return new Contents() {
private int i = 11;
public int value() { return i; }
};
}
public static void main(String[] args) {
Parcel6 p = new Parcel6();
Contents c = p.cont();
}
} ///:~

這個看似神祕的結構,讓你將類的定義和構建過程融為一體。實際上它實現的語義是:
class MyContents implements Contents {
private int i = 11;
public int value() { return i; }
}
return new MyContents();
(impicitly final)這樣大家就一目瞭然了吧。

看了以上或簡單,或複雜的類定義。也許大家都有些頭痛。為什麼java提供如此豐富的類定義方式呢?不如讓我們問問自己,我們定義類的目的是什麼?是為了讓我們的程式擁有更好的邏輯結構。類定義是資訊組織的形式。java語言給我們提供了在各個的實現階段允許我們去做資訊的封裝,真正是everything is object.這些是我們應該高興的事才對。它絕不是負擔,只是給我們更多的選擇空間。

語義特點:(以下inner class is thinkingInjava3th 中的定義,可以看作本文所定義的nested class)
Each inner class can independently inherit from an implementation. Thus, the inner class is not limited by whether the outer class is already inheriting from an implementation.
(是不是看到了點什麼,多繼承!!visitor pattern!!)
1。 The inner class can have multiple instances, each with its own state information that is independent of the information in the outer class object. 一個獨立的實體,誕生於某個更大的實體中(外部實體),卻可以用外部實體的資源(請聯想寄生蟲:<)
2。 In a single outer class you can have several inner classes, each of which implement the same interface or inherit from the same class in a different way. (可以有不同種類的寄生蟲)
3。The point of creation of the inner class object is not tied to the creation of the outer class object.
(它的建立過程並不繫於外部物件的建立)
4。There is no potentially confusing “is-a” relationship with the inner class; it’s a separate entity.
(於外部類無inherit關係)


經過以上的說明,你是否頭腦中更清晰了些:
Inner class 常見用法:
Closures & Callbacks
1.在java中可以利用Inner class 實現Closure(閉包) 和 Callback(回撥) 語義:
Closure的定義:(我試圖從不同側面來闡述這個概念)
Martin Fowler :Essentially a closure is a block of code that can be passed as an argument to a function call.
Bruce:A closure is a callable object that retains information from the scope in which it was created.
那什麼時候使用它呢?它有什麼優點呢?
打個比方:讓你去照看小孩:你是想要嬰兒還是小學生呢?我想大多數人會選擇小學生。為什麼?因為小學生可以自己吃飯,自己上廁所,自己洗澡。這兩個物件的實現,你更偏向哪一個呢?Smile


call back:With a callback, some other object is given a piece of information that allows it to call back into the originating object at some later point. (順藤摸瓜,製造一個可控的介面)