不定程度自變量&(匿名)內部類&傳值調用

不定長度自變量 在調用方法時,若方法的自變量個數事先沒法決定該如何處理,例如 System. out. printf () 方法就沒法事先決定自變量個數:數組

Sys tem. out. printf("&d",10)i
 System. out. printf("%d%d", 10, 20);
 system. out. printf("%d %d %d", 10, 20, 30);
複製代碼

在JDK5以後支持不定長度自變量( Variable- Length Argument),能夠輕鬆地解決這個問題:bash

public static int sum(int...nums) {
		int sum=0;
		for(int num:nums) {
			sum+=num;
		}
		return sum;
	}
複製代碼

要使用不定長度自變量,聲明參數列時要在類型關鍵字後加上...,在sum()方法經過用加強式for循環來取得不定長度自變量中的每一個元素,能夠這樣使用:ide

System. out. printin (sum(1, 2))
 System. out. Println( sum(1, 2, 3))
 Sys tem. out. println (sum(1, 2, 3, 4))
複製代碼

實際上不定長度自變量是編譯程序蜜糖,反編譯後:int…聲明的變量實際上展開爲數組,而調用不定長度自變量客戶端,例如out. printin(sum(12,3)),展開後也是變爲數組看成自變量傳遞。這能夠從反編譯後的程序代碼得知:學習

out.println(
 thtool. sum(new int[] (1, 2, 3)
)
複製代碼

使用不定長度自變量時,方法上聲明的不定長度參數必須是參數列最後一個。例如如下是合法聲明:ui

public void some(int argl, int arg2, int... varargs){
 }
複製代碼

如下方式是不合法聲明:this

public void some(Int... varargs, int argl, int arg2){}
複製代碼

使用兩個及以上不定長度自變量也是不合法的: 若是使用對象的不定長度自變量,聲明的方法相同。例如spa

public void some(Other... others){}
複製代碼

匿名內部類 能夠在類中再定義類,這稱爲內部類。設計

class Some{
	class Other{
	}
}
複製代碼

雖然實際應用上不多看到接下來的寫法,不過要使用Some中的 other類必須先創建some實例code

Some s=new Some;
Some.Other o = new s.new otner();
複製代碼

內部類也能夠用public、 protected或 private聲明。 內部類自己能夠存取外部類的成員,一般非靜態內部類會聲明爲 private,這類內部類是輔助類中某些操做而設計,外部不用知道內部類的存在。 內部類也能夠聲明爲 static。例如:對象

class Some{
	static class Other{
	}
}
複製代碼

一個被聲明爲 static的內部類,一般是將部類看成名稱空間。能夠這樣創建類實例: Some Other o= new Some.Other(); 被聲明爲 static的內部類,雖然將外部類看成名稱空間,但算是個獨立類,它能夠存取外部類 static成員,但不可存取外部類非 static成員,

class Some{
	static int x;
	int y;
	static class Other{
		void doOther() {
			out.println(x);
			out.println(y);//這一行報錯
		}
	}
}
複製代碼

方法中也能夠聲明類,這一般是輔助方法中演算之用,方法外沒法使用。例如:

class Some{
	 public void dosome(){
	 class Other{}
	}
 }
複製代碼

在撰寫Java程序時,常常會有臨時繼承某個類或操做某個接口並創建實例的需求。因爲這類子類或接口操做類只使用一次,不須要爲這些類定義名稱,這時可使用匿名內部類( Anonymous Inner Class)來解決這個需求。匿名內部類的語法爲:

new 父類()|接口(){
//類本體操做
}
Object obj=new Object() {
			@Override
			public String toString() {
				
				return "返利";
			}
		};
複製代碼

繼承object從新定義toString方法。若是是操做接口如Some接口定義抽象方法doSome創建匿名內部類:

Some some = new Some(){
	public void doSome(){
		//執行語句
	};
};
複製代碼

JDK8之後接口只有一個方法能夠這樣:

Some some = () ->{
	//執行語句(Lambda)
}
複製代碼

傳值調用 在一些程序語言,像是C++之類,調用方法傳遞自變量給參數時,能夠有傳值調用(Call by Value)或傳參考調用( Call by Referenc)的方式。Java當中只有傳值調用。傳值調用也簡稱傳值 Pass by Value),傳參考調用也簡稱傳參考( Pass by Reference)若是沒有接觸過具備傳值調用與傳參考調用項的程序語言,瞭解傳值調用這個名詞,對學習Java並無太大意義。若是接觸過C++這類可傳值與傳參考的語言,注意,C++這類語言中「參考」的意義,跟Java中的「參考」並不相同。

public class PassDemo {
	public static void main(String[] args) {
		Customer c1=new Customer("wanger");
		some(c1);//c1對象
		System.out.println(c1.name);
		
		Customer c2=new Customer("wanger");
		other(c2);//c2對象
		System.out.println(c2.name);
	}
	
	static private void some(Customer c) {
		c.name="zhangsan";
	}
	static private void other(Customer c) {
		c=new Customer("lisi");
	}
	
}
class Customer{
	String name;
	public Customer(String name) {
		this.name=name;
	}
}
/*執行結果
zhangsan
wanger
*/
複製代碼

在調用some()方法時傳入了c1,這表示c1參考的對象也讓some()方法的參數c參考(因此c1與c參考至同一個對象)。在some()方法中c.name= "zhangsan",就是求將c參考對象的name成員指定爲"zhangsan"。**some方法執行結束後,c變量不存在了。**下一行取得c1.name並顯示。 接着看 other()方法調用時傳入了c2,這表示c2參考的對象也讓 other()方法的參數c參考。在 other()方法中 c= new customer(...),就是要求創建新對象,並指定給c參考,c參考至新建的對象。 some()方法執行結束後,c變量不存在了,本來c參考的對象會被JVM清除。下一行取得c2.name並顯示。 這樣的行爲就是傳值,以上示範的是傳遞對象給參數的狀況,若是由方法中返回對象並指定給變量,也是這種行爲。 這樣的行爲確實就是傳值,而不是傳參考再次強調,Java中的「參考」與C+之類語言中的「參考」,在根本上就是不一樣的定義,只不過恰好都叫做「參考」罷了。

相關文章
相關標籤/搜索