1.靜態static:用於修飾成員(成員變量和成員函數)
2.特點:
1.static是一個修飾符,用於修飾成員
2.static修飾的成員被所有的對象共享
3.static是優先於對象存在的,因爲static的成員隨着類的加載就已經存在了。
4.static修飾的成員多了一種調用方式,就可以直接被類名調用。類名.靜態成員。
5.static修飾的數據是共享的數據,對象中存儲的是特有的數據。
class Person
{
static String country = "CN"; //對象的共享數據,節省空間,在對象之前就存在。程序運行加載類時就存在。
//靜態修飾的成員,可以被對象調用,也可以被 " 類名. " 調用。
String name; //對象特有的數據
void show()
{
System.out.println(Person.country + " : " + this.name); //注意country前面省略的是Person.
//就是靜態前面省略的是類名,非靜態前面省略的是this.
}
}
class Test
{
public static void main(String[] args)
{
Person p = new Person();
p.name = "小強";
p.show();
System.out.println(Person.country); //country可以被 " 類名. " 調用
System.out.println(p.country); //country被對象調用
}
}
3.成員變量和靜態變量的區別:
String name; //成員變量(實例變量)
static String country = “CN”; //靜態變量
成員變量:也叫實例變量,就是對象中的變量。
靜態變量:也就類變量,可以用類調用。和類類型變量區別(Person p)。
區別:
1.兩個變量的生命週期不同:
成員變量隨着對象的創建而存在,隨着對象的被回收而釋放。
靜態變量隨着類的加載而存在,隨着類的消失而消失。
2.調用方式不同:
成員變量只能被對象調用。
靜態變量可以被對象調用(但不建議),還可以被類名調用。
3.別名不同:
成員變量,也稱爲實例變量。
靜態變量,也稱爲類變量。
4.數據的存儲位置不同。
成員變量數據存儲在堆內存的對象中,所以也叫對象的特有數據。
靜態變量數據存儲在方法區(共享區,數據區)的靜態區裏,所以也叫對象的共享數據。
4.注意:
1.靜態方法只能訪問靜態成員(即不能訪問對象的成員,因爲對像還不存在)(非靜態既可以訪問靜態,又可以訪問非靜態)
2.靜態方法中不可以使用this,super關鍵字(因爲對象還不存在)
3.主函數是靜態的
5.關於主函數是靜態的:
class StaticDemo
{
int num = 4; //成員變量,實例變量,是對象特有的
public static void main(String[] args)
{
StaticsDemo s = new StaticDemo(); //創建對象來調用
s.show(); //直接調用的話,成員必須都設置成靜態的,但是這樣就共享了,不合理。
//new StaticDemo().show();
}
void show() //成員方法,對象所特有的
{
System.out.println(this.num); //this可省
}
}
主函數的功能:就是在主函數中創建對象,去調用其他的函數功能。
(把功能都封裝在函數中,把函數都封裝在類中)
6.main函數解析:
public static void main(String[] args)
主函數特殊之處:
1.格式是固定的,只認這個,如果有同名main的函數,但是參數不同,也是可以的,就是main的重載而已。
2.被jvm所識別和調用
public:因爲權限必須最大
static:不需要對象,直接用主函數所屬類名調用即可(如:命令:java staticDemo(省略.main),也說明主函數所在的類名在權限爲public時必須和文件名一致,這樣可以通過文件名找到類名,才能調用主函數)
void: 主函數沒有具體的返回值,返回空類型即可。
main:函數名,不是關鍵字,只是一個jvm識別的固定的名字。
String[] args:這是主函數的參數列表,是一個數組類型的參數,而且元素都是字符串類型。args(arguments參數的意思)是唯一可變的。
調用有的形參的函數必須傳相對應的實參。所以
虛擬機調用主函數時也傳了值:new String[0]
命令傳值: java Test haha hehe xixi
class Test
{
public static void main(String[] args) //new String[0],只是提供一個入口,有需要的時候可以傳。字符串數據是通用的。
{
System.out.println(args); // [Ljava.lang.String;@5fd1358f
System.out.println(args.length); // 0
for(String x : args)
System.out.println(x); // 沒有值
System.out.println(args[0]); //數組越界異常,應爲args數組沒有元素
}
}
7.static內存圖解:
例子:
class Person
{
private String name;
private int age;
static String country = "CN";
Person(String name, int age)
{
this name = name;
this age = age;
}
void show()
{
System.out.println(Person.country + ":" + this.name + ":" + this.age);
}
static void method()
{
System.out.println(Person.country);
}
}
class StaticDemo
{
public static void main(String[] args)
{
Person.method();
Person p = new Person("java",20);
p.show();
}
}
8.static開發什麼時候用:
1.靜態變量:
當分析對象中所具備的成員變量的值都是相同的。這時這個成員就可以被靜態修飾。
只要數據在對象都是不同的,就是對象的特有數據,必須存儲在對象中,是非靜態的。
(如果是相同的數據,對象不需要修改,只需要使用即可,不需要存在對象中,則定義成靜態的。)
2.靜態函數:
函數是否用靜態修飾,就參考一點,就是該函數功能是否訪問到對象中的特有數據。
(簡單點說,從源代碼看,該功能是否需要訪問非靜態的成員變量,如果需要,該功能就是非靜態的。
如果不需要,就應該將該功能定義成靜態的。也可以定義非靜態,但是非靜態需要被對象調用,而僅創建對象調用非靜態的沒有訪問特有數據的方法,該對象的創建是沒有意義的。對象就是封裝特有數據存在的。)
9.靜態代碼塊:用的不多
static int num;
static //對類初始化
{
num = 10;
… //進行相應操作
}
作用:滿足靜態的一切特點,包括隨着類的加載而加載。
1.但是它是隨着類的加載而執行。而且只執行一次。
2.用於給類初始化。(有的類是全是靜態的成員,不需要對象,不能用構造函數初始化)
3.靜態代碼塊也優先於mian函數執行。
10.構造代碼塊:在類中定義的代碼塊
{
}
是給所有對象進行初始化,每new一個對象運行一次。具備對象初始化的通用性。
構造函數:
給對應的對象進行初始化。具備對象初始化的針對性。
局部代碼塊:在方法中定義的代碼塊,限定局部變量的生命週期。
執行順序:靜態代碼塊,父類構造函數,構造代碼塊,構造函數。