黑馬程序員--- 學習筆記(第六天)

 —————————— ASP.Net+Android+IOS開發.Net培訓、期待與您交流!——————————
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培訓、期待與您交流!——————————

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章