一、 Object Storage Service在那個地方
(1) 寄存器(register) 位於cpu內部,資源有限由程式編譯的時候根據需求進行分配
(2) 堆棧(stack) 位於RAM(Random Access Menory),通過堆棧指標分配記憶體,指標上移釋放記憶體。下移分配記憶體。
JAVA編譯器必須知道儲存在堆棧中的資料確切的大小和生命週期,包括儲存基礎資料型別 (Elementary Data Type)和對象參考型別
(3) 堆(heap) 位於RAM,存放JAVA對象,編譯器不需要知道大小和生命週期。靈活性強,不過分配記憶體速度比stack慢
(4) 靜態儲存 位於RAM 存放著程式運行時一直存放的資料,但java對象不能儲存在靜態儲存空間裡
(5) 常量儲存 位於ROM(Read Only Menory) 永遠不會改變,
(6) 非RAM儲存 資料存在於程式之外,可以不接受任何程式的控制,在程式沒有運行時都可以存在,如持久對象和流
static講解:
(1)如果要為某些特定資料分配記憶體,而不管要建立多少對象,或者根本就不需要建立任何對象。
(2)如果某些方法不予包含它的類的任何對象關聯在一起,也就是說沒有建立對象也可以調用這個方法。
通過static 來定義資料和方法可以給所有的對象共用使用。通過類可以直接存取。稱之為類資料或類方法。
二、初始化
在類的內部,變數的初始化的先後順序決定了初始化的順序。即使變數定義分散於方法定義之間,它們仍然能在
任何方法(包括構造器)被調用之前得到初始化。
class A{
public A(int nCount){
System.out.println(""+nCount);
}
}
class B{
A a0 = new A(0);
public B(){
System.out.println("HelloWorld");
a2 = new A(3);
}
A a1 = new A(1);
public void f(){
System.out.println("f()");
}
A a2 = new A(2);
}
public class HelloWorld{
public static void main(String []args){
B b=new B();
b.f();
}
}
列印結果:
0
1
2
HelloWorld
2
f()
三、待用資料的初始化
靜態資料成員只有在它所對應的類的對象被建立時才被初始化,初始化以後就不會再初始化,並且是先於非靜態成員
初始化之前。
class Bow1{
public Bow1(int market) {
System.out.println("Bow1("+market+")");
}
public void f(int market){
System.out.println("f("+market+")");
}
}
class Table{
static Bow1 b1 = new Bow1(1);
public Table(){
System.out.println("Table()");
b2.f(1);
}
public void f2(int market){
System.out.println("f2("+market+")");
}
static Bow1 b2 = new Bow1(2);
}
class CupBord{
Bow1 b3 = new Bow1(3);
static Bow1 b4 = new Bow1(4);
public CupBord(){
System.out.println("cupBord");
b4.f(2);
}
void f3(int market){
System.out.println("f3("+market+")");
}
static Bow1 b5 = new Bow1(5);
}
public class Init {
public static void main(String []args){
System.out.println("Creating new CupBord in main");
new CupBord();
System.out.println("Creating new CupBord in main");
new CupBord();
t2.f2(1);
t3.f3(1);
}
static Table t2 = new Table();
static CupBord t3 = new CupBord();
}
列印結果:
Bow1(1)
Bow1(2)
Table()
f(1)
Bow1(4)
Bow1(5)
Bow1(3)
cupBord
f(2)
Creating new CupBord in main
Bow1(3)
cupBord
f(2)
Creating new CupBord in main
Bow1(3)
cupBord
f(2)
f2(1)
f3(1)
總結:假如有一個Dog類
(1)首先建立Dog對象或者首次訪問類的靜態方法時,java解譯器找到類路徑,定位到Dog.class檔案
(2)載入Dog.class檔案,Dog類的靜態方法和靜態域被訪問,並且只是在載入時初始化一次
(3)在堆上面為Dog分配足夠的儲存空間
(4)儲存空間被清0,基礎資料型別 (Elementary Data Type)初始化為預設值,而參考型別設定為null
(5)執行所有出現域的初始化動作
(6)執行構造器
四、方法的綁定概念RTTI RunTime type indentify 運行時類型識別
方法調用和方法關聯起來叫綁定。當一個方法前有final或者static時(被final修飾的方法是不能重載和重寫的),方法是前期綁定的。因為在編譯的時候就可以確定。
而一般的方法是後期綁定,即在運行時才確定是調用哪個方法如:
class Shap{
public draw(){};
}
class Circle extends Shap{
public draw (){};
}
//調用
Shap circle = new Circle();
circle.draw();//在這裡只有在運行時才能確定是調用了Circle類裡的方法draw();
那麼在運行時是如何調用(或者綁定)Circle類的方法呢?這就需要知道類對象Class了
Class對象在需要時被載入,載入方法有製造這個類的對象或者通過類載入器載入。
它包含了類的有關資訊。