java關(guān)鍵字static學(xué)習(xí)心得
static是java中又一重要的關(guān)鍵字,在一定環(huán)境下使用,可以提高程序的運(yùn)行性能,優(yōu)化程序的結(jié)構(gòu)。其主要應(yīng)用有以下幾方面:
1.static修飾的成員變量,稱(chēng)為類(lèi)變量/靜態(tài)變量,以實(shí)現(xiàn)所有對(duì)象對(duì)該成員的共享。
2.static修飾的成員方法,稱(chēng)為類(lèi)方法/靜態(tài)方法,可直接通過(guò)類(lèi)名調(diào)用,無(wú)需創(chuàng)建對(duì)象。
3.形成靜態(tài)代碼塊,優(yōu)化程序性能。
4.靜態(tài)導(dǎo)包,一般將類(lèi)的方法直接導(dǎo)入到當(dāng)前類(lèi)中,從而直接使用方法名即可調(diào)用類(lèi)方法,更加方便。
5.修飾內(nèi)部類(lèi),無(wú)需實(shí)例化外部類(lèi)就可以調(diào)用內(nèi)部類(lèi)。
下面一附代碼說(shuō)明:
public class Student {
String name;
static int age;
public String toString() {
return "Name:" + name + ", Age:" + age;
}
public static void main(String[] args) {
Student s1 = new Student();
s1.name="張三";
s1.age=20;
Student s2 = new Student();
s2.name="李四";
s2.age=10;
System.out.println(s1);
System.out.println(s2);
}
}
/**輸出結(jié)果
Name:張三, Age:10
Name:李四, Age:10
*/
如上述代碼,s1和s2兩個(gè)對(duì)象分別存儲(chǔ)在內(nèi)存中堆區(qū)域的不同地址中,所以他們之間相互不會(huì)干擾。然而static關(guān)鍵字修飾了成員變量age,讓其變成類(lèi)的所屬,而不是對(duì)象的所屬,任何該類(lèi)實(shí)例的對(duì)象都可以共享使用它。所以,輸出的age均是最終賦給的10。如果去掉static,顯然對(duì)象之間互不影響,輸出如下:
Name:張三, Age:20 Name:李四, Age:10

如上述代碼,out1調(diào)用out2時(shí)出錯(cuò)。由此代碼可得,靜態(tài)方法不能調(diào)用非靜態(tài)的成員變量和成員方法。非靜態(tài)方法可以調(diào)用靜態(tài)的成員變量和成員方法。注意,static不影響成員的訪問(wèn)權(quán)限,Java中能夠影響到訪問(wèn)權(quán)限的關(guān)鍵詞是private、public、protected,default。
public class Test extends Base{
static{
System.out.println("static靜態(tài)塊1");
}
public Test(){
System.out.println("test構(gòu)造器");
}
public static void main(String[] args) {
new Test();
}
}
class Base{
static{
System.out.println("static靜態(tài)塊2");
}
public Base(){
System.out.println("base構(gòu)造器");
}
}
如上述代碼,記住兩句話,static代碼塊隨類(lèi)的加載一起加載。static修飾的變量方法比其他變量方法優(yōu)先加載,且只加載一次。加載子類(lèi)時(shí),會(huì)首先加載父類(lèi)。由此可以分析:在執(zhí)行開(kāi)始,先要尋找到main方法,因?yàn)閙ain方法是程序的入口,但是在執(zhí)行main方法之前,必須先加載Test類(lèi),而在加載Test類(lèi)的時(shí)候發(fā)現(xiàn)Test類(lèi)繼承自Base類(lèi),因此會(huì)轉(zhuǎn)去先加載Base類(lèi),在加載Base類(lèi)的時(shí)候,發(fā)現(xiàn)有static塊,便執(zhí)行了static塊。在Base類(lèi)加載完成之后,便繼續(xù)加載Test類(lèi),然后發(fā)現(xiàn)Test類(lèi)中也有static塊,便執(zhí)行static塊。在加載完所需的類(lèi)之后,便開(kāi)始執(zhí)行main方法。在main方法中執(zhí)行new Test()的時(shí)候會(huì)先調(diào)用父類(lèi)的構(gòu)造器,然后再調(diào)用自身的構(gòu)造器。因此,運(yùn)行結(jié)果如下:
static靜態(tài)塊2 static靜態(tài)塊1 base構(gòu)造器 test構(gòu)造器
/* A.java文件 */
package com.dogo.test;
public class A {
public static void outWord(Object o){
System.out.println(o);
}
}
/* B.java文件 */
import static com.dogo.test.A.*;
public class B
{
public static void main( String[] args )
{
outWord("Hello World!");
}
/**輸出
* Hello World!
*/
}
如上述代碼,A.java中包含一個(gè)簡(jiǎn)單的靜態(tài)方法,在B.java中我們用static關(guān)鍵字將A類(lèi)導(dǎo)入,由此,便無(wú)需使用“類(lèi)名.方法名”的方法去調(diào)用類(lèi)方法了,直接可以采用"方法名"去調(diào)用類(lèi)方法,就好像是該類(lèi)自己的方法一樣。
/*Outer.java*/
public class Outer {
static {
System.out.println("Outer靜態(tài)塊");
}
public Outer(){
System.out.println("Outer構(gòu)造器");
}
static class Inner{
static{
System.out.println("Inner靜態(tài)塊");
}
public Inner(){
System.out.println("Inner構(gòu)造器");
}
}
}
/*Test.java*/
public class Test{
public static void main(String[] args) {
new Outer.Inner();
}
}
如上述代碼,記住,用static修飾內(nèi)部類(lèi),外部類(lèi)可以直接調(diào)用內(nèi)部類(lèi),因?yàn)閟tatic修飾的的內(nèi)部類(lèi)是在加載外部類(lèi)的同時(shí)加載的,所以,并不要實(shí)例化外部類(lèi)就能直接調(diào)用靜態(tài)內(nèi)部類(lèi)。例子中,在進(jìn)入Test的main方法之前,加載Test類(lèi),然后執(zhí)行new Outer.Inner();這里需要注意:因?yàn)镮nner是靜態(tài)的,所以這里并不需要加載外部類(lèi)和實(shí)例化外部類(lèi),可以直接加載Inner并實(shí)例化。運(yùn)行結(jié)果如下:
Inner靜態(tài)塊 Inner構(gòu)造器
大喬注:static另一個(gè)很重要的應(yīng)用就是實(shí)現(xiàn)單例設(shè)計(jì)模式。單利模式的特點(diǎn)是該類(lèi)只能有一個(gè)實(shí)例,為了實(shí)現(xiàn)這一功能,必須隱藏類(lèi)的構(gòu)造函數(shù),即把構(gòu)造函數(shù)聲明為private,并提供一個(gè)創(chuàng)建對(duì)象的方法,由于構(gòu)造對(duì)象被聲明為private,外界無(wú)法直接創(chuàng)建這個(gè)類(lèi)型的對(duì)象,只能通過(guò)該類(lèi)提供的方法來(lái)獲取類(lèi)的對(duì)象,于是只能把創(chuàng)建對(duì)象的方法聲明為static,程序?qū)嵗缦拢?/p>
class SingleDemo{
private static SingleDemo ins=null;
private SingleDemo(){}
public static SingleDemo getIns(){
if(ins==null){
ins=new SingleDemo();
}
return ins;
}
}
相關(guān)文章
Java使用Lua實(shí)現(xiàn)動(dòng)態(tài)擴(kuò)展和腳本自動(dòng)升級(jí)
Lua是一種輕量級(jí)的腳本語(yǔ)言,常用于游戲開(kāi)發(fā)和嵌入式系統(tǒng)中,這篇文章主要介紹了Java如何調(diào)用Lua實(shí)現(xiàn)動(dòng)態(tài)擴(kuò)展和腳本自動(dòng)升級(jí),感興趣的可以學(xué)習(xí)下2023-08-08
java利用url實(shí)現(xiàn)網(wǎng)頁(yè)內(nèi)容的抓取
本文主要介紹了java利用url實(shí)現(xiàn)網(wǎng)頁(yè)內(nèi)容抓取的示例。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-03-03
Java執(zhí)行SQL腳本文件到數(shù)據(jù)庫(kù)詳解
這篇文章主要為大家詳細(xì)介紹了Java執(zhí)行SQL腳本文件到數(shù)據(jù)庫(kù)的相關(guān)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
Java實(shí)現(xiàn)航空航班管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)航空航班管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
SpringBoot項(xiàng)目加載配置文件的6種方式小結(jié)
這篇文章給大家總結(jié)了六種SpringBoot項(xiàng)目加載配置文件的方式,通過(guò)@value注入,通過(guò)@ConfigurationProperties注入,通過(guò)框架自帶對(duì)象Environment實(shí)現(xiàn)屬性動(dòng)態(tài)注入,通過(guò)@PropertySource注解,yml外部文件,Java原生態(tài)方式注入這六種,需要的朋友可以參考下2023-09-09

