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