不定長度自變量 在調用方法時,若方法的自變量個數事先沒法決定該如何處理,例如 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+之類語言中的「參考」,在根本上就是不一樣的定義,只不過恰好都叫做「參考」罷了。