第四節課
static的用法和包
上次課提到了static關鍵字,下面介紹一下具體的用法
1.實例變量和類變量
我們已經知道一個類可以使用new關鍵字可以創建多個不同的對象,這些對象被分配不同的內存空間.具體說的話,不同的對象的實例變量將被分配不同的內存空間,如果類中的成員變量有類變量,那麼所有對象的這個類變量都分配分配給相同的一處內存,改變其中一個對象的這個類變量會影響其他對象的這個類變量,也就是說對象共享類變量.如
class Takecare
{
static int x;
int y;
}
class A
{
Takecare A1=now Takecare();
Takecare A2=now Takecare();
//在此代碼中如果給x賦值那麼,A1.x 和A2.x指的是同一個內存空間,無論那個對象修改都是對一個x進行操作
}
當java程序執行時,類的字節碼文件被加載到內存,如果該類沒有創建對象,類的實例成員變量不會被分配內存.但是類中的類變量被加載到內存時,會被分配相應的內存空間.簡單的說就是,沒創建對象當類加載到內存時候,只有類變量(static)會被分配內存空間,只有創建對象時候實例變量纔會被分配空間的.
像上面的例子裏,在沒有創建Takecare的對象時候,Takecare::x是有空間的即此時可以訪問的,當且僅當Takecare A1=now Takecare()時A1.y纔會有內存空間.
通過下面的例子體會一下,不同的對象會共享一個底
class 梯形
{ float 上底,高;
static float 下底;
梯形(float x,float y,float h)
{ 上底=x; 下底=y; 高=h;
}
float 獲取下底()
{ return 下底;
}
void 修改下底(float b)
{ 下底=b;
}
}
class Example4_7
{ public static void main(String args[])
{ 梯形 laderOne=new 梯形(3.0f,10.0f,20),laderTwo=new 梯形(2.0f,3.0f,10);
梯形.下底=200; //通過類名操作類變量
System.out.println("laderOne的下底:"+laderOne.獲取下底());
System.out.println("laderTwo的下底:"+laderTwo.獲取下底());
laderTwo.修改下底(60); //通過對象操作類變量
System.out.println("laderOne的下底:"+laderOne.獲取下底());
System.out.println("laderTwo的下底:"+laderTwo.獲取下底());
}
}
2.實例方法和類方法
和實例變量和類變量的描述時是一樣,當類的字節碼加載到內存是類方法的入口地址就會被加載到相應的內存空間,即此時可以訪問;而當且只有創建對象之後,實例方法的入口地址纔會被加載到內存中,這是纔可以調用.
既然知道了實例方法和類方法開始生效的時間,可以知道他們可以調用何種類的成員變量:
1)類方法因爲是在創建對象之前就已經生效了,這時候實例變量還沒有被分配內存空間,只有類變量被分配了內存空間,所以類方法只能調用被分配內存空間的變量即類變量;
2)實例方法是在創建對象之後纔開始生效的,這是無論是類變量還是實例變量都已經被分配了內存空間,所以實例方法生效後可以調用類變量和實例變量.
class Fibi
{ public static long fibinacii(int n)
{ long c=0;
if(n==1||n==2)
c=1;
else
c=fibinacii(n-1)+fibinacii(n-2);
return c;
}
}
public class Example4_8
{ public static void main(String args[])
{ System.out.println(Fibi.fibinacii(7));// 可見還沒喲創建Fibi的對象時就可以調用fibinacii()方法,因爲屬於static修飾的類變量
}
}
包
包是java中有效的管理類的一個機制,包有類似於目錄結構的層次結構.通過import關鍵字可以在程序中使用包
語法格式:
import<包名>.*; //包含包中的所有類
import<包名><類名>//包含包中的指定類
例如:
import java.awt.*; //包含java.awt包中的所有類
import java.awt.JButton;//包含java.awt包中的JButton類
既然知道了怎麼使用,那如何製作包呢,可以通過關鍵字package聲明包語句.package語句作爲java源文件的一個條語句,指明該源文件定義的類的所在包.
語法格式:
package 包名;
如果源文件中省略了package語句,那麼源文件中定義命名的類將被隱含的認爲是無名包的一部分,即源文件中定義命名的類在同一個包中,但該報沒有名字而已.
包還可以是一個合法的表示符,也可以是若干個標識符加"."分割而成,如
package sunrise;
package sunrise.com.cn
程序如果使用了包的語句,如
package desney.tom;
那麼目錄必須包含有如下結構,如
C:/cartoon/desney/tom
並且要將源文件保存在目錄C:/cartoon/desney/tom中,才能使用這個包,然後編譯源文件:
C:/cartoon/desney/tom/javac 源文件.java
或
jacac C:/cartoon/desney/tom/源文件.java
從一個例子體會此過程:
package desney.tom;
public class PrimNumber
{ public void getPrimnumber(int n)
{ int sum=0,i,j;
for(i=1;i<=n;i++)
{ for(j=2;j<=i/2;j++)
{ if(i%j==0)
break;
}
if(j>i/2)
System.out.print(" "+i);
}
}
public static void main(String args[])
{ PrimNumber p=new PrimNumber();
p.getPrimnumber(20);
}
}
保存上述源文件到C:/cartoon/desney/tom下,然後編譯
C:/cartoon/desney/tom/javac PrimNumber.java
運行程序時必須到desney/tom的上一層目錄cartoon中來運行,如
C:/cartoon/java desney.tom.PrimNumber
因爲起了報名,類PrimNumber的全名應該爲desney.tom.PrimNumber
導入這個包時也要注意名稱
import desney.tom.PrimNumber;
所以用package可以把認可類都打包然後在其他程序中使用,於c或c++中的頭文件有着相似的效果,差別就是java中的包裏只能是類
注意:使用import可以導入包中的類.在編寫源文件時,除了自己編寫的類外,經常需要使用java提供的去多類,這些類可能不在一個包中.在學習java時,使用已經存在的類,避免一切從頭做起,這是面向對象編程的一個重要方面.
總結:具體的把static修飾的變量和方法的使用方法做了介紹;對java中包有了初步認識