[敏捷JAVA讀書筆記-java基礎部分] 第四章

1、類變量和類方法


對象是由屬性和行爲構成,屬性對應java類中的 成員變量(實例變量和類變量),行爲對應類中的方法。

java類的狀態是由他的成員變量的狀態決定的。

在java中被聲明爲static的成員變量和成員方法是類變量和類方法,在類加載的時候即被初始化。存放在方法區。

沒有被聲明爲static的成員變量和成員方法是實例變量和實例方法。實例變量在new 一個對象的時候初始化。實例方法應該是啥時候調用,啥時候初始化。

實例變量存放在堆區,他的生命週期與對象的相同。調用實例方法的時候,虛擬機會在棧區開闢一塊單獨的內存空間,因此實例方法內的變量是現成安全的,執行完畢後,虛擬機會收回這塊內存。


2、更多初始化的內容


執行一個類的時候,jvm首先找到類名.class,而後裝載,加載進內存,這個時候在內存中會造成一個類對象,用來表明這個類(因此咱們用對象.class.getClassName()的時候老是獲得相同的值,這個就是類對象的名字),而後進行靜態初始化,初始化類中的全部成員變量以及成員函數還有static塊。
靜態初始化只進行一次:當靜態變量或者方法被調用,類加載的時候進行!靜態的東西是屬於類的。而不是屬於對象的,過分的使用靜態是很危險的!確信使用靜態的時候才使用靜態!

java初始化的時候一個基本的原則:
先靜態後動態
先定義初始化後構造函數。
package com;

class A{
A(String who){
System.out.println("create A by "+who);
}
}

class B{
A a = new A("B");

B(String who){
System.out.println("create B by "+who);
}
}

class C{
static {
A a = new A("C static");
}

C(String who){
System.out.println("create C by "+who);
}
}

class Init{

static B b = new B("Init");
static C c = new C("Init");
//C c = new C("Init");

public static void main(String [] args){

}
}
保存爲Init.java
編譯:javac com/Init.java
執行:java com/Init

當你在cmd命令行窗口上敲入
java com/Init 的時候,
一、啓動java虛擬機。
二、到com下面查找Init.class。
三、若是有就加載進jvm,沒有就跑出一個nofound的異常。
四、jvm將Init.class加載到內存,造成類對象,而後開始靜態初始化。執行
static B b = new B("Init");
五、而後加載B.class進內存
六、而後執行new B("Init");的操做。即調用B的構造函數。
七、根據先定義初始化後構造函數的順序,會先執行
A a = new A("B");
八、jvm加載A進內存,並造成A的類對象。而後調用A的構造函數建立A 。
九、而後調用B的構造函數建立B。
十、而後執行
static C c = new C("Init");,重複上面的順序。
因此最後的打印結果是:
create A by B
create B by Init
create A by C static
create C by Init

注意:若是把
static C c = new C("Init");改爲:C c = new C("Init");打印的結果應該是:
create A by B
create B by Init

由於咱們並無用調用C的構造函數去new一個C出來,而沒有static修飾的變量不是類變量,並不在類加載的時候初始化,他是在調用此類的構造函數以前被初始化。

再來看一個java中比較有趣的東西:

package com;

class Some{
int i;

boolean b;

char c;

double d;

int k = f();

int u = g(k);

{
Init init = new Init();
}


int f(){
return 10;
}

int g(int u){
if(u==10)
return 100;
return 0;
}

void print(){
System.out.println("i:"+i+" k:"+k +" u:"+u+" b:"+b+" c:"+c+" d:"+d);
if(c=='\0'){
System.out.println("c is '\0'");
}

}
public static void main(String [] args){
Some some = new Some();
some.print();
}
}


執行結果是:

create A by B
create B by Init
create A by C static
create C by Init
i:0 k:10 u:100 b:false c: d:0.0
c is ' '

java容許在定義初始化的時候調用函數。
也容許使用{}這樣的東西來作一些特別的事情。

3、new String("a string")到底幹了什麼?

String str = new String("a string");到底作了什麼?

一、an object of String is create //在堆區內建立一個String類型的對象
二、the object is initialized by "a string"//用a string 初始化它
三、a variable as handle to String is create //在棧區內建立一個句柄,也就是引用變量str
四、the value of the handle variable is assign to the object//這個str指向堆區內的String對象

4、傳值仍是傳引用

java中函數傳遞參數通通能夠理解爲是傳值!不過要搞清楚,這個值裏面是什麼東西,是對象的引用仍是基本的數據類型。

class Letter{
char c = 'a';
}
class passObject{
static void f(Letter y){
y.c = 'z';//
y.c = 'z' 就是改變這個對象的成員變量c的值,因此,x.c = ‘z’
}
public static void main(String [] args){
Letter x = new Letter();//建立一個Letter類型的變量x,x中存儲Letter對象的首地址好比0x001....
f(x);//至關於作了 y = x的操做,這個時候y與x指向同一個對象

System.out.println(x.c);
}
}

x是一個引用,他是Letter類型的變量,他存儲Letter的對象的首地址好比多是0x001(也就是他是指向Letter對象的句柄),這句話就是把對象的引用付給y 就至關於作了 y = x 操做,這個時候y與x指向同一個對象。
相關文章
相關標籤/搜索