Java程序員的基本修養01
1, 數組使用
Java是靜態語言,數組初始化後長度是不可以改變的
a) 數組初始化
i. 靜態初始化:
String[] s = newString[]{
“cloud”,”zhangsan”,”lisi”
};
簡化形式:
String[] s = {“cloud”,”zhangsan”,”lisi”};
ii. 動態初始化:
String[] s = new String[4];
基本類型數組和引用類型數組在初始化時內存分配機制有什麼區別?
基本類型在初始化時:程序先爲數組分配空間,再講數組元素的值存入對應內存中。
引用類型:數組初始化時,先爲數組在堆內存中分配一段空間,因爲數組中存放的是引用類型,所以先創建引用類型的變量,數組中存入的是引用變量的地址,並不是引用變量本身
JavaScript是動態語言,數組初始化後,長度依然可變
數組變量只是一個引用,數組對象纔是保存在堆內存中的連續內存空間,對數組初始化並不是對數組變量初始化,而是在堆內存中創建數組對象,及分配一塊連續的內存空間,這塊連續的內存空間長度就是數組長度
代碼解釋:
Java語言不允許直接訪問堆內存中的數據,要訪問堆內存中的數據只能通過數組引用變量來訪問數組。
多維數組其實就是一層層的引用
1, 對象及內存管理
a) 局部變量可分爲:
Ⅰ)形參:在方法簽名中定義的局部變量,由方法調用者負責爲其賦值,隨方法的結束而消亡
Ⅱ)方法內的局部變量
Ⅲ)代碼塊內的局部變量
b) static關鍵字不能修飾外部類,局部變量,局部內部類
因爲:static關鍵字修飾的成員是屬於類本身的,外部類不行;局部變量出局部範圍後就銷燬了,不能是屬於類;局部內部類首先也是局部的,所以也不行
c) Java類裏定義成員變量的順序問題
Java內存管理機制:
內存分配:jvm爲 新創建的對象在堆內存中分配內存空間
內存回收:java對象失去引用,jvm會自動清理該對象
實例變量的初始化時機:
初始化三種方式:
1, 定義實例變量時指定初始值
2, 非靜態初始化塊中對實例變量指定初始值
3, 構造器中對實例變量指定初始值
class Cat {
private String name;
private int age;
public Cat(String name, int age) {
System.out.println("執行構造函數");
this.name = name;
this.age = age;
}
// 非靜態初始化塊
{
System.out.println("執行非靜態初始化塊");
// 當下面定義weight的代碼先執行
weight = 2.0;
}
double weight = 2.3;
}
public class InitDemo {
public static void main(String[] args) {
Cat c = new Cat("kitty", 3);
System.out.println(c.weight);
}
}
類變量初始化:
1, 定義時初始化
2, 靜態代碼塊中初始化
執行順序按程序中代碼的順序
public class InitDemo1 {
private static String name = "Rhythm";
static {
System.out.println("執行靜態代碼塊");
age = 12;
}
private static int age = 22;
public static void main(String[] args) {
System.out.println(InitDemo1.name);
System.out.println(InitDemo1.age);
}
}
爲什麼java要求內部類訪問的局部變量必須使用final修飾?
因爲,對於普通局部變量來說,作用域就是該方法,方法結束後局部變量也會消失,但是內部類可能產生隱式的閉包(Closure)這樣就會使得局部變量脫離方法繼續存在,如果該變量不被final修飾,可以隨便更改,就會照成混亂。
public class ClosureTest {
/*
* 如下所示: 如果main方法結束後,執行run方法的線程還在執行,則可以繼續訪問到main方法的局部變量
*/
public static void main(String[] args) {
// 定義局部變量
final String name = "haha";
// 在內部類中訪問局部變量
new Thread(new Runnable() {
public void run() {
System.out.println(name);
}
}).start();
}
}