static關鍵字
靜態:static
用法:是一個修飾符,用於修飾成員(成員變量,成員函數)
當成員被靜態所修飾後,就多了一種調用方法,除了可以用被對象調用外,還可以
直接被類名調用
類名.靜態成員
特有數據存放在對象,存儲在堆內存
static存放在方法區(共享區,數據區)
static特點:
1.隨着類的加載而加載(代表隨着類的消失而消失,生命週期最長)
2.優先於對象存在
3.被所有對象共享
4.可以被類名直接使用
靜態成員變量稱爲類變量,靜態函數稱爲類方法
實例變量和類變量的區別:
1.存放位置: 類變量隨着類的加載就存在於方法區中,
實例變量隨着對象的建立而存在堆內存中
2.生命週期: 類變量的生命週期最長,隨着類的消失而消失
實例變量生命週期隨着對象的消失而消失
靜態使用注意事項:
1.靜態方法只能訪問靜態成員,非靜態方法能訪問靜態成員
2.靜態方法不可以定義this,super關鍵字,因爲先有類再有對象
2.主函數就是靜態的
靜態有利有弊:
利:對對象的共享數據進行單獨空間的存儲,節省空間,沒有必要每一個對象中都存儲一份,還可以
直接被類名使用
弊: 生命週期長,訪問有侷限性.
/*
static 關鍵字
*/
class Demo1
{
public static void main(String[] args)
{
Student.show();//多了種類名直接調用的方式 static代碼塊執行
new Student().show_1(); //在new static代碼塊也不會執行了
}
}
class Student
{
{
System.out.println("我是構造代碼塊,優先於構造函數");
}
public Student(){
System.out.println("構造函數,隨着對象的加載而加載");
}
private String name;
private static String schoolName="xx學校";//共享數據
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
static
{
System.out.println("我是static代碼塊,隨着類的加載而加載,我只會被執行一次");
}
/*錯誤的 類方法不能調用非靜態變量
public static void show(){
System.out.println("我叫"+name+"來自"+schoolName);
}
*/
/*類方法只能訪問靜態變量*/
public static void show(){
System.out.println("靜態方法,我來自"+schoolName);
}
/*非靜態方式可以訪問靜態變量*/
public void show_1(){
System.out.println("非靜態方法,我來自"+schoolName);
}
}
解析main主函數:
主函數: 是一個特殊的函數,作爲程序的入口,可以被jvm調用
public static void main(String []args){
}
主函數的定義:
public:代表該函數訪問權限最高
static:代表函數是隨着類的加載就已經存在了
void:主函數沒有具體的返回值
main:不是關鍵字,可以被jvm識別的特殊單詞
String[]args:字符串類型數組
主函數是固定的格式才被jvm識別,只有字符串類型數組名可以改
jvm在調用函數時,傳入的new String[0];在調用的時候可以傳入參數,
用空格隔開,jvm會自動封裝成數組
/*
主函數測試 給主函數傳參 這這是一種方式
*/
class Demo2
{
public static void main(String[] args)
{
String []arr={"a","b","c","d"};
Test.main(arr); //給test主函數傳can
}
}
class Test
{
public static void main(String []args){
System.out.println(args.length);
for(int i=0;i<args.length;i++){
System.out.print(args[i]+"\t");
}
}
}
例子:java 類名 字符串1 字符串2 字符串3
什麼時候使用靜態:
什麼時候定義類變量:
當對象出現共享數據時,非共享數據屬性
例如:學生在同一學校 學校就是共享數據
什麼時候定義類方法:
當功能內部沒有訪問到內部非靜態數據(對象的特有數據),那麼該功能可以定義成靜態的
靜態的應用: 工具類
class Demo3
{
public static void main(String[] args)
{
int []arr={5,4,6,8,15,11,78,55,226,456};
System.out.println(ArrTools.getMax(arr)); //獲取最大值
System.out.println(ArrTools.getMin(arr)); //獲取最小值
ArrTools.printArr(arr);
// ArrTools.selectSort(arr); //選擇排序
ArrTools.bubbleSort(arr);//冒泡排序
ArrTools.printArr(arr);
System.out.println(ArrTools.halfSearch(arr,5)); //位置是1
}
}
/**
static 應用 數組工具類
@author 劉陽文
@version v1.0
*/
public class ArrTools
{
/**
@param arr int型數組
求數組最大值
*/
public static int getMax(int []arr){
int max=0;
for (int i=0;i<arr.length ;i++ )
{
if(arr[i]>arr[max])
max=i;
}
return arr[max];
}
/*求數組中最小值*/
public static int getMin(int []arr){
int min=0;
for(int i=0;i<arr.length;i++){
if(arr[i]<arr[min])
min=i;
}
return arr[min];
}
/*選擇排序*/
public static void selectSort(int []arr){
for (int i=0;i<arr.length-1 ;i++ )
for (int j=i+1;j<arr.length-1 ;j++ )
if(arr[i]>arr[j])
swap(arr,i,j);
}
/*冒泡排序*/
public static void bubbleSort(int []arr){
for (int i=0;i<arr.length-1 ;i++ )
for (int j=0;j<arr.length-i-1 ;j++ )
if(arr[j]>arr[j+1])
swap(arr,j,j+1);
}
/*位置交換*/
private static void swap(int arr[],int i,int j){
arr[i]=arr[i]^arr[j];
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
}
/*打印數組*/
public static void printArr(int []arr){
for(int u : arr)
System.out.print(u+"\t");
}
/*二分查找*/
public static int halfSearch(int []arr,int want){
int min=0,max=arr.length-1,mid;
do
{
mid=(min+max)>>>1;
if(arr[mid]==want)
return mid;
else{
if(arr[mid]<want)
min=mid+1;
else if(arr[mid]>want)
max=mid-1;
else
return mid;
}
}
while (min<=max);
return -1;
}
}
每一應用程序都有共性的功能,可將這些功能進行抽取,獨立發呆封裝,以便使用
雖然可以通過new實體操作這些方法,對數組進行操作時發現了問題:
1.對象時用於封裝數據的,可是實體並未封裝特有數據
2.操作數組的每一方法都沒有用到實體的特有數據
這時,爲了讓程序更嚴謹,是不需要對象的,這時可以定義用private私有對象構造函數
製作幫助文檔:
//製作時,claspath 路徑要在當前運行的目錄下
將工具類發送給別人用,對方只要設置classpath即可,但也要看說明書
這就用到了java的文檔註釋,生成程序說明書
@author 作者
@version 版本
@param 變量名 作用
@return 返回值類型 作用
public,protected權限可以生成java註釋文檔
在cmd生成的方法:
javadoc -d 目錄名 -author -version 類名
-d:就是存放目錄 後面接的目錄名 沒有則新建
作者和版本是可選的.. 類名就是要生成註釋的類
一個的默認構造函數根據與該類權限一致,如果被public修飾,那麼默認
構造函數就是public的,隨着類權限變化而變化
靜態代碼塊
static{
執行語句;
}
特點: 隨着類的加載而執行,只執行一次,優先於主函數
即使重新new實體也不會改變,類方法執行,static代碼塊也會加載
對象初始化過程:
Person p=new Person("track",20);
該語句都做了什麼事情呢?
1.因爲new用到了Person.class,所以會先找到Person.class並加載到內存中
2.執行該類static代碼塊,如果有的話,給Person.class進行初始化
3.在堆內存中開闢空間,分配內存地址
4.在堆內存中建立對象的特有屬性,並進行默認初始化
5.對屬性進行顯示初始化
6.對對象進行構造代碼塊初始化
7.對對象的構造函數進行初始化
8.將內存地址賦給棧內存中的變量(引用)
設計模式
解決某一類問題最有效的方式,java有23中設計模式
單例模式就是其中一種
想要保證對象的唯一:
1.爲了避免其他程序過多的建立該類對象,先控制進制其他程序建立該類對象
2.還爲了讓其他程序可以訪問到該類對象,只好在本類中定義一個對象
3.爲了方便其他程序對對象的訪問,可以對外提供訪問方式
用代碼實現以上三種步驟:
1.將構造函數私有化
2.在類中定義一個對象 private static
3.提供一個方法可以獲取該對象
對於事物怎麼描述還是怎麼描述,當需要將該事物的對象保證在內存中的唯一
時,就可以加上上訴三步即可.
單例模式有兩種方式:
1.餓漢式
2.懶漢式
兩種方法的區別:
1.餓漢式:類一進內存就已經初始化對象
2.懶漢式:類進內存,對象還沒有存在,只有調用獲取實例方法才建立對象.
簡而言之:就是先初始化,後出初始化的問題.
/*單例模式*/
class Demo4
{
public static void main(String[] args)
{
Single s=Single.getInstance();
s.show();
}
}
/*懶漢式
class Single
{
private static Single s=new Single();
private Single(){};
public static Single getInstance(){
return s;
}
public void show(){
System.out.println("我是餓漢式");
}
}
*/
/*餓漢式*/
class Single
{
private static Single s=null;
private Single(){};
public static Single getInstance(){
if(s==null){
synchronized(Single.class)
{
if(s==null)
s=new Single();
}
}
return s;
}
public void show(){
System.out.println("我是懶漢式");
}
}
—————————— ASP.Net+Android+IOS開發、.Net培訓、期待與您交流!——————————