一個Java 方法是為了執行某個操作的一些語句的組合。舉個例子來說,當你調用System.out.println 方法時,系統實際上會執行很多語句才能在控制台上輸出信息。
現在你將學習怎麼創建你自己的方法,他們可以有返回值也可以沒有返回值,可以有參數,也可以沒有參數,重載方法要使用相同的方法名稱,並在程序設計中利用抽象的方法。
創建方法
我們用下面的例子來解釋方法的語法:
public static int funcName(int a, int b) { // body}在這裡
方法也包含過程或函數。
方法的定義包含方法頭和方法體。如下所示:
modifier returnType nameOfMethod (Parameter List) { // method body}以上的語法包括
示例
這是上面定義的方法max(),該方法接受兩個參數num1和num2返回兩者之間的最大值。
/** the snippet returns the minimum between two numbers */public static int minFunction(int n1, int n2) { int min; if (n1 > n2) min = n2; else min = n1; return min; }方法調用
要想使用一個方法,該方法必須要被調用。方法調用有兩種方式,一種是有返回值的,一種是沒有返回值的。
調用方法很簡單,當程序需要調用一個方法時,控製程序轉移到被調用的方法,方法將會返回兩個條件給調用者:
將返回void的方法作為一個調用語句,讓我看下面的例子:
System.out.println("wiki.jikexueyuan.com!");該方法的返回值可以通過下面的例子被理解:
int result = sum(6, 9);
示例
下面的例子表明了怎麼定義方法和怎麼調用它:
public class ExampleMinNumber{ public static void main(String[] args) { int a = 11; int b = 6; int c = minFunction(a, b); System.out.println("Minimum Value = " + c); } /** returns the minimum of two numbers */ public static int minFunction(int n1, int n2) { int min; if (n1 > n2) min = n2; else min = n1; return min; }}將會產生如下的結果
Minimum value = 6
關鍵字void
關鍵字void 允許我們創建一個沒有返回值的方法。這裡我們在下一個例子中創建一個void 方法methodRankPoints。這個方法是沒有返回值類型的。調用void 方法必須聲明methodRankPoints(255.7); Java 語句以分號結束,如下所示:
public class ExampleVoid { public static void main(String[] args) { methodRankPoints(255.7); } public static void methodRankPoints(double points) { if (points >= 202.5) { System.out.println("Rank:A1"); } else if (points >= 122.4) { System.out.println("Rank:A2"); } else { System.out.println("Rank:A3"); } }}這將產生如下的結果:
Rank:A1
通過值來傳遞參數
在調用函數時參數是必須被傳遞的。並且他們的次序必須和他們創建時的參數次序是一樣的。參數可以通過值或引用來傳遞。
通過值傳遞參數意味著調用方法的參數,通過參數值來傳遞給參數。
示例
下面的程序給出了一個例子來顯示通過值來傳遞參數。在調用方法後參數值是不會發生變化的。
public class swappingExample { public static void main(String[] args) { int a = 30; int b = 45; System.out.println("Before swapping, a = " + a + " and b = " + b); // Invoke the swap method swapFunction(a, b); System.out.println("/n**Now, Before and After swapping values will be same here**:"); System.out.println("After swapping, a = " + a + " and b is " + b); } public static void swapFunction(int a, int b) { System.out.println("Before swapping(Inside), a = " + a + " b = " + b); // Swap n1 with n2 int c = a; a = b; b = c; System.out.println("After swapping(Inside), a = " + a + " b = " + b); }}這將產生如下的結果:
Before swapping, a = 30 and b = 45Before swapping(Inside), a = 30 b = 45After swapping(Inside), a = 45 b = 30**Now, Before and After swapping values will be same here**:After swapping, a = 30 and b is 45
方法的重載
當一個方法有兩個或者更多的方法,他們的名字一樣但是參數不同時,就叫做方法的重載。它與覆蓋是不同的。覆蓋是指方法具有相同的名字,類型以及參數的個數。
讓我們來考慮之前的找最小整型數的例子。如果我們要求尋找浮點型中最小的數時,我們就需要利用方法的重載來去創建函數名相同,但參數不一樣的兩個或更多的方法。
下面的例子給予解釋:
public class ExampleOverloading{ public static void main(String[] args) { int a = 11; int b = 6; double c = 7.3; double d = 9.4; int result1 = minFunction(a, b); // same function name with different parameters double result2 = minFunction(c, d); System.out.println("Minimum Value = " + result1); System.out.println("Minimum Value = " + result2); } // for integer public static int minFunction(int n1, int n2) { int min; if (n1 > n2) min = n2; else min = n1; return min; } // for double public static double minFunction(double n1, double n2) { double min; if (n1 > n2) min = n2; else min = n1; return min; }}這將產生如下結果:
Minimum Value = 6Minimum Value = 7.3
重載方法使程序易讀。在這裡,兩種方法名稱相同但參數不同。產生整型和浮點類型的最小數作為程序運行結果。
使用命令行參數
有時你想要在程序運行之前傳遞參數。這可以通過給main 函數傳遞命令行參數來實現。
在命令行中,當要執行程序文件時,一個命令行參數是緊接著文件名字後面的出現的。要接受命令行參數在Java 程序中是十分容易的。它們傳遞到main 函數字符數組內。
示例
下面的例子展示了將所有命令行參數輸出的程序:
public class CommandLine { public static void main(String args[]){ for(int i=0; i<args.length; i++){ System.out.println("args[" + i + "]: " + args[i]); } }}通過以下方法來執行該程序:
java CommandLine this is a command line 200 -100
這將產生如下的結果:
args[0]: thisargs[1]: isargs[2]: aargs[3]: commandargs[4]: lineargs[5]: 200args[6]: -100
構造函數
這是一個簡單的使用構造函數的例子:
// A simple constructor.class MyClass { int x; // Following is the constructor MyClass() { x = 10; }}你可以通過以下方法來調用構造函數來實例化一個對象:
public class ConsDemo { public static void main(String args[]) { MyClass t1 = new MyClass(); MyClass t2 = new MyClass(); System.out.println(t1.x + " " + t2.x); }}通常,你將需要用構造函數來接受一個或多個參數。參數的傳遞和以上介紹的普通方法的參數傳遞是一樣的,就是在構造函數的名字後面列出參數列表。
示例
這是一個簡單的使用構造函數的例子:
// A simple constructor.class MyClass { int x; // Following is the constructor MyClass(int i ) { x = i; }}你可以通過以下方法來調用構造函數來實例化一個對象:
public class ConsDemo { public static void main(String args[]) { MyClass t1 = new MyClass( 10 ); MyClass t2 = new MyClass( 20 ); System.out.println(t1.x + " " + t2.x); }}這將產生如下的結果:
10 20
可變長參數
JDK1.5 能夠允許你傳遞可變長的同一類型的參數。用如下方法進行聲明:
typeName... parameterName
方法聲明時,你要在省略號前明確參數類型,並且只能有一個可變長參數,並且可變長參數必須是所有參數的最後一個。
示例
public class VarargsDemo { public static void main(String args[]) { // Call method with variable args printMax(34, 3, 3, 2, 56.5); printMax(new double[]{1, 2, 3}); } public static void printMax( double... numbers) { if (numbers.length == 0) { System.out.println("No argument passed"); return; } double result = numbers[0]; for (int i = 1; i < numbers.length; i++) if (numbers[i] > result) result = numbers[i]; System.out.println("The max value is " + result); }}這將產生如下的結果:
The max value is 56.5The max value is 3.0
finalize() 方法
你可以定義一個方法,僅在被垃圾收集器銷毀之前才會被調用。這個方法叫做finalize() 方法,它也可以用來確保一個對像被乾淨清除了。
舉個例子,你也許用finalize() 來確保被一個對像打開的文件已經關閉了。
為了給類添加一個終結器,你只需定義finalize() 方法。 Java要回收該類的一個對象時,會調用該方法。
在finalize() 方法中,你將指定一些必須在對象銷毀之前要做的行為。
finalize()方法一般是如下形似:
protected void finalize( ){ // finalization code here}這裡,關鍵字protected 是為了保證在類外的代碼不能訪問finalize() 方法。
這意味著你不能知道finalize() 什麼時候執行。舉個例子,如果你的程序在垃圾收集器發生之前就結束了,finalize() 方法將不會被執行。
泛型方法:
java泛型方法在方法返回值是容器類對象時廣泛使用。
public static List<T> find(Class<T> clazz,String userId){ ....}一般來說編寫java泛型方法時,返回值類型和至少一個參數類型應該是泛型,而且類型應該是一致的,如果只有返回值類型或參數類型之一使用了泛型,這個泛型方法的使用就大大的限制了,基本限製到跟不用泛型一樣的程度。
下面主要介紹兩種十分相似的java泛型方法的使用以及它們之間的區別。
第一種:
public static <T extends CommonService> T getService(Class<T> clazz) { T service = (T) serviceMap.get(clazz.getName()); if (service == null) { service = (T) ServiceLocator.getService(clazz.getName()); serviceMap.put(clazz.getName(), service); } return service; }第二種:
public static <T> T getService(Class<? extends CommonService> clazz) { T service = (T) serviceMap.get(clazz.getName()); if (service == null) { service = (T) ServiceLocator.getService(clazz.getName()); serviceMap.put(clazz.getName(), service); } return service; }下面是泛型方法所在的類:
public abstract class CommonService { private static HashMap<String, CommonService> serviceMap = new HashMap<String, CommonService>(); //這裡是泛型方法定義. . .}這兩個泛型方法只有方法的簽名不一樣,方法體完全相同,那它們有什麼不一樣呢?
我們來使用一下它們,就知道它們的區別了。
對第一種泛型方法使用:
public class Main { public static void main(String[] args) { NoticeService noticeService=CommonService.getService(NoticeService.class);//正確的使用第一種泛型方法,不會出現編譯錯誤。 NoticeService noticeService=CommonService.getService(UserService.class);//不正確的使用第一種泛型方法,會出現編譯錯誤。 }}對第二種泛型方法使用:
public class Main { public static void main(String[] args) { NoticeService noticeService=CommonService.getService(NoticeService.class);//正確的使用第二種泛型方法,不會出現編譯錯誤,邏輯也正確,運行時不會出現異常。 NoticeService noticeService=CommonService.getService(UserService.class);//不正確的使用第二種泛型方法,不會出現編譯錯誤,但邏輯不正確,運行時會出現異常,危險! }}現在知道了這兩種極其相似的泛型方法的區別了吧?