靜態(tài)方法和實例方法的區(qū)別主要體現(xiàn)在兩個方面:
在外部調(diào)用靜態(tài)方法時,可以使用"類名.方法名"的方式,也可以使用"對象名.方法名"的方式。而實例方法只有后面這種方式。也就是說,調(diào)用靜態(tài)方法可以無需創(chuàng)建對象。
靜態(tài)方法在訪問本類的成員時,只允許訪問靜態(tài)成員(即靜態(tài)成員變量和靜態(tài)方法),而不允許訪問實例成員變量和實例方法;實例方法則無此限制。
下面幾個例子展示了這一區(qū)別。
1、調(diào)用靜態(tài)方法示例。
//-----------文件名hasStaticMethod.java,程序編號1-----------------public class hasStaticMethod{//定義一個靜態(tài)方法public static void callMe(){System.out.println("This is a static method.");}}
下面這個程序使用兩種形式來調(diào)用靜態(tài)方法。
//-----------文件名invokeStaticMethod.java,2-----------------public class invokeStaticMethod{public static void main(String args[]){hasStaticMethod.callMe(); //不創(chuàng)建對象,直接調(diào)用靜態(tài)方法 hasStaticMethod oa = new hasStaticMethod(); //創(chuàng)建一個對象oa.callMe(); //利用對象來調(diào)用靜態(tài)方法}}
程序3.36兩次調(diào)用靜態(tài)方法,都是允許的,程序的輸出如下:
This is a static method.This is a static method.
允許不創(chuàng)建對象而調(diào)用靜態(tài)方法,是Java為了減少程序員調(diào)用某些常用方法時的麻煩,而允許程序員按照傳統(tǒng)的C語言中使用函數(shù)的方式來使用方法。典型的例子是前面某些程序中使用"Math.ramdon()"來獲取隨機數(shù)。
2、靜態(tài)方法訪問成員變量示例。
//-----------文件名accessMember.java,程序編號3.37-----------------class accessMember{private static int sa; //定義一個靜態(tài)成員變量private int ia; //定義一個實例成員變量//下面定義一個靜態(tài)方法static void statMethod(){int i = 0; //正確,可以有自己的局部變量sa = 10; //正確,靜態(tài)方法可以使用靜態(tài)變量otherStat(); //正確,可以調(diào)用靜態(tài)方法ia = 20; //錯誤,不能使用實例變量insMethod(); //錯誤,不能調(diào)用實例方法}static void otherStat(){} //下面定義一個實例方法 void insMethod(){int i = 0; //正確,可以有自己的局部變量sa = 15; //正確,可以使用靜態(tài)變量ia = 30; //正確,可以使用實例變量statMethod(); //正確,可以調(diào)用靜態(tài)方法}}
本例其實可以概括成一句話:靜態(tài)方法只能訪問靜態(tài)成員,實例方法可以訪問靜態(tài)和實例成員。之所以不允許靜態(tài)方法訪問實例成員變量,是因為實例成員變量是屬于某個對象的,而靜態(tài)方法在執(zhí)行時,并不一定存在對象。同樣,因為實例方法可以訪問實例成員變量,如果允許靜態(tài)方法調(diào)用實例方法,將間接地允許它使用實例成員變量,所以它也不能調(diào)用實例方法。基于同樣的道理,靜態(tài)方法中也不能使用關(guān)鍵字this。
main()方法是一個典型的靜態(tài)方法,它同樣遵循一般靜態(tài)方法的規(guī)則,所以它可以由系統(tǒng)在創(chuàng)建對象之前就調(diào)用。
靜態(tài)方法與靜態(tài)變量一樣,屬于類本身,而不屬于那個類的一個對象。
調(diào)用一個被定義為static的方法,可以通過在它前面加上這個類的名稱,也可以像調(diào)用非靜態(tài)方法一樣通過類對象調(diào)用。實例方法必須通過類的實例來使用。
實例方法可以使用類的非靜態(tài)成員,也可以使用類的靜態(tài)成員。類的靜態(tài)方法,靜態(tài)變量是在類裝載的時候裝載的。
但是要特別注意,類的靜態(tài)變量是該類的對象所共有的,即是所有對象共享變量。所以建議盡量少用靜態(tài)變量。
盡量在靜態(tài)方法中使用內(nèi)部變量。 其中static關(guān)鍵字即表示靜態(tài)的。
聲明靜態(tài)方法的語法如下:static返回類型 方法名(參數(shù)列表){//方法體} 靜態(tài)方法與實例方法唯一不同的,就是靜態(tài)方法在返回類型前加static關(guān)鍵字。靜態(tài)方法的調(diào)用有兩種途徑:(1)通過類的實例對象去調(diào)用調(diào)用格式為: 對象名.方法名(2) 通過類名直接調(diào)用調(diào)用格式為: 類名::方法名 我們在使用時要注意:靜態(tài)方法只能訪問類的靜態(tài)成員,不能訪問類的非靜態(tài)成員;非靜態(tài)方法可以訪問類的靜態(tài)成員,也可以訪問類的非靜態(tài)成員;靜態(tài)方法既可以用實例來調(diào)用,也可以用類名來調(diào)用。
#include using namespace std;class CStaticTest{ public: CStaticTest(int a) { this->a = a; } ~CStaticTest(){}static int add(CStaticTest& c1, CStaticTest& c2) { return c1.a + c2.a; }private: int a; };int main() { CStaticTest tmp1(1); CStaticTest tmp2(2); int sum1 = tmp1.add(tmp1, tmp2); int sum2 = CStaticTest::add(tmp1, tmp2);cout << sum1 << endl; cout << sum2 << endl; return 0; } 1. 有靜態(tài)屬性的類,一般會定義靜態(tài)方法。2. 沒有屬性的類,一般會定義靜態(tài)方法,這樣在使用時,通過類名::方法名即可調(diào)用,而不用先定義對象,再調(diào)用,這樣可以省去一行代碼。
編程時我們心里一定要清楚靜態(tài)方法和類的非靜態(tài)方法方法的區(qū)別:
最根本區(qū)別從編譯角度來說吧:
1)靜態(tài)(static)方法是編譯時直接加載加載到內(nèi)存中(離cpu最近的一塊內(nèi)存區(qū)域也稱為堆棧),比如程序的public static main(args []){}方法,你能實例話嗎?
靜態(tài)方法不能被實例化,也不允許被實例化!
現(xiàn)在很多Java集成工具邊寫邊編譯的
因此 你可以通過“類名”+“.”+“靜態(tài)方法的名()”來調(diào)用
2)非靜態(tài)方法(類的非靜態(tài)方法)通過關(guān)鍵字 “new” 字來實例化一個對象(object),這個對象放在 內(nèi)存的另一塊區(qū)域 堆(heap)中。
也就是說編譯時,非靜態(tài)方法必須先實例化類的一個對象,通過“對象名”+“非靜態(tài)方法名()”來調(diào)用;
public class Student
{
private String name;
/************************************************************
*下面兩個方法是類的非靜態(tài)方法封裝 屬性name,看一下在 main()
*如何調(diào)用
************************************************************/
public set(string init_name)
{
this.name = init_name;
}
publc String get()
{
return this.name;
}
//構(gòu)造函數(shù)
public Student(){}
public Student(String init_name)
{
this.name = init_name;
}
//下面是一個靜態(tài)方法,看一下它在main()中如何調(diào)用
public static void PrintClassName()
{
System.out.print("該類的名字:Student");
}
}
//MainClass類
pubic class MainClass
{
public static void main(args[])
{
//先調(diào)用靜態(tài)方法,不需要實例化對象
Student.PrintClassName();
//現(xiàn)在調(diào)用非靜態(tài)方法,一定要實例化對象
Student stu1 = new Student();
stu1.set("Join");
String stu1_name = stu1.get();
}
}
靜態(tài)方法是使用公共內(nèi)存空間的,就是說所有對象都可以直接引用,不需要創(chuàng)建對象再使用該方法。
例如,我創(chuàng)建一個類,里面有一個靜態(tài)方法:
class Test{
public static int z(int xx,int yy){
return xx+yy;
}
public int zz(int xx,int yy){
return xx+yy;
}
}
然后在含有main方法的類中使用這個類時,對與以上非靜態(tài)和靜態(tài)方法的引用方式是不同的,如下:
import Test;
public class mainClass{
int sum;
public static void main(String args[]){
sum=Test.z(1,2); //直接用 類.方法或者屬性就可以使用該方法或?qū)傩浴?
System.out.println(sum);
Test t=new Test();
sum=t.zz(1,2); //因為zz不是靜態(tài)方法,所以只能只能用Test類創(chuàng)建一個t對象,然后調(diào)用該對象的方法。
System.out.println(sum);
}
}
ls他們說的也是有道理的,靜態(tài)方法只能被靜態(tài)方法調(diào)用。
靜態(tài)方法是類的公共方法,即每個對象共有的方法,一般情況下我們習慣通過類名.方法名來調(diào)用,但是也可以用某個實例對象來訪問。
例如:public class Test{
public static void getStaticTest(){
//////
}
}
第一種:我們通過Test.getStaticTest()來調(diào)用
第二種:Test t = new Test();t.getStaticTest()來調(diào)用
第二種的調(diào)用方式一般不推薦!首先是靜態(tài)方法不需要實例化對象,實例化之后再調(diào)用會造成內(nèi)存空間的浪費。其次,會讓閱讀代碼的人產(chǎn)生誤解,以為此方法為非靜態(tài)的方法。
靜態(tài)方法何時使用
如果某些操作不依賴具體實例,那它就是靜態(tài)的,反之如果某些操作是依賴具體實例的(例如訪問一個特定會員的名稱),那它就應該是實例化的。
靜態(tài)方法不用new對象可以直接調(diào)用
1.與類相關(guān)與對象無關(guān)
2.不需要對象的“輕”方法
3.工廠方法
如果某個方法是用頻率較高,或者方法本身通用性較強,無需初始化類成員變量,則可以使用靜態(tài)方法,那樣方便,速度也快.
可以直接拿來就用的方法,就算是靜態(tài)的.
肯定不涉及具體對象,因為靜態(tài)方法內(nèi),是無法直接使用任何非靜態(tài)成員的。
(1)制作工具類
(2)可以當作"作局"對象或方法來使用
靜態(tài)方法和實例方法是一樣的,在類型第一次被使用時加載。調(diào)用的速度基本上沒有差別。
靜態(tài)方法不用創(chuàng)建實例就可調(diào)用,比較簡單從面向?qū)ο蟮慕嵌壬蟻碚f,在抉擇使用實例化方法或靜態(tài)方法時,應該根據(jù)是否該方法和實例化對象具有邏輯上的相關(guān)性,如果是就應該使用實例化對象 反之使用靜態(tài)方法
不需要生成對象的
經(jīng)常頻繁使用的
工具類里的(如SqlHelper)
適當?shù)厥褂胹tatic方法本身并沒有什么,當一個人從來不懂使用多態(tài)、接口設(shè)計時,很自然地會濫用static方法。
個人理解在多個類中需要調(diào)用并且是與對象無關(guān)的方法可設(shè)為靜態(tài)方法,方便調(diào)用。
所有對象共有的方法
再不關(guān)系到任何于特定對象相關(guān)的操作
比如學生的年齡就是學生的相關(guān)。
修改學生的年齡就不適合用靜態(tài)方法。
一般來說,如果你的方法里沒有用到this關(guān)鍵字,
那就適合用靜態(tài)方法
通常通用的類中一些常用的方法可以設(shè)計為靜態(tài)類
只要是沒有用到類的狀態(tài)信息,只從參數(shù)獲取信息的都可以為靜態(tài)的
可以實現(xiàn)某些特殊的設(shè)計模式:如Singleton
由于沒有this指針,可以把某些系統(tǒng)API的回調(diào)函數(shù)以靜態(tài)函數(shù)的形式封裝到類的內(nèi)部
可以封裝某些算法,比如數(shù)學函數(shù),如ln,sin,tan等等,這些函數(shù)本就沒必要屬于任何一個對象,所以從類上調(diào)用感覺更好
總之,從OOA/OOD的角度考慮,一切不需要實例化就可以有確定行為方式的函數(shù)都應該設(shè)計成靜態(tài)的
靜態(tài)方法與非靜態(tài)方法最明顯的區(qū)別就是如果某個方法是公共靜態(tài)的,那么可以直接通過類名.方法名的方法來調(diào)用,而公共實例方法則需要事先實例化對象,然后才能調(diào)用。
這些各種說法,基本上都是正確的。
靜態(tài)變量
可以將靜態(tài)變量理解為類變量(與對象無關(guān)),而實例變量則屬于一個特定的對象。
靜態(tài)變量有兩種情況:
靜態(tài)變量是基本數(shù)據(jù)類型,這種情況下在類的外部不必創(chuàng)建該類的實例就可以直接使用
靜態(tài)變量是一個引用。這種情況比較特殊,主要問題是由于靜態(tài)變量是一個對象的引用,那么必須初始化這個對象之后才能將引用指向它。因此如果要把一個引用定義成static的,就必須在定義的時候就對其對象進行初始化。
靜態(tài)方法
與類變量不同,方法(靜態(tài)方法與實例方法)在內(nèi)存中只有一份,無論該類有多少個實例,都共用一個方法。
靜態(tài)方法與實例方法的不同主要有:
靜態(tài)方法可以直接使用,而實例方法必須在類實例化之后通過對象來調(diào)用。
在外部調(diào)用靜態(tài)方法時,可以使用“類名.方法名”或者“對象名.方法名”的形式。實例方法只能使用后面這種方式。
靜態(tài)方法只允許訪問靜態(tài)成員。而實例方法中可以訪問靜態(tài)成員和實例成員。
靜態(tài)方法中不能使用this(因為this是與實例相關(guān)的)。
聲明:本網(wǎng)站尊重并保護知識產(chǎn)權(quán),根據(jù)《信息網(wǎng)絡(luò)傳播權(quán)保護條例》,如果我們轉(zhuǎn)載的作品侵犯了您的權(quán)利,請在一個月內(nèi)通知我們,我們會及時刪除。
蜀ICP備2020033479號-4 Copyright ? 2016 學習鳥. 頁面生成時間:2.647秒