方法的可變引數:
方法中有無參方法,有帶參方法,都多個引數的方法;代碼如下:
public class Dome { /* 方法無參和帶參 */ public static void method() { System.out.println("我是一個無參的方法"); } public static void method(int a) { System.out.println("我是一個帶參的方法"); } public static void method(int a,int b) { System.out.println("我是一個多參的方法"); } }
現在有一道題:定義一個方法,求2個數的和 和求多個數的和:我們的代碼可以如下:
public class Dome01 { public static void main(String[] args) { System.out.println(sum(1, 2)); System.out.println(sum(1, 2, 9)); } /* 定義一個求和方法sum */ public static int sum(int a, int b) { int sum = 0; sum = a + b; return sum; } /* 定義多個求和方法sum */ public static int sum(int a, int b, int c) { int sum = 0; sum = a + b + c; return sum; } }
現在又有一個問題,如果我不知道我要求幾個數的和,或者要求你寫方法來求2個數,3個數,4個數,5個數,就這樣一直下去,我們該怎么辦,難道要一直的反復的寫方法嘛,這樣肯定是不現實的,所以java引入了可變引數,
可變引數的語法如下:
public class Dome02 { /* 可變引數的定義: */ public static void main(String[] args) { int sum = sum(1, 2); // 第一次呼叫兩一引數的, System.out.println(sum); int sum1 = sum(1, 2, 3); // 第二次呼叫三個引數 的, System.out.println(sum1); } public static int sum(int... is) { // 可變引數的定義語法: 引數型別... 引數名 int sum = 0; for (int i = 0; i < is.length; i++) { sum = sum + is[i]; } return sum; } }
這樣就可以完美的解決上面的那個問題了,
Object...obj :
這里過一下超類Object;obj是所有基本型別的超類,它包含所有的基本資料型別,如果把object當可變引數寫會如何,演示如下:
public class Dome08 { public static void main(String[] args) { //可以看見我們傳了所有的基本資料型別,還加了String這個參考型別 沒有報錯 obj("121",21,null,true,'a',1.2); } public static void obj(Object... objects) { /* 我們試著列印一下 */ for (int i = 0; i < objects.length; i++) { System.out.println(objects[i]); } } }
結果是什么呢,沒錯就是和你想象的一樣:(將傳入的所有型別資料都列印了出來)

注意點:
- 可變引數定義用三個點多一個少一個都不可以,
- 傳參的數值必須和你所定義的型別相同,比如你定義了一個int...si 就不能傳 String或其他比int型別大的,
- 也可以如這樣定義:public static int sum(Stirng st, int... is){},可以和其他型別一起使用,
- 可變引數值的獲取和陣列一樣,已下標的形式獲取,比如你定義了 int...is并傳了 1, 2兩個數,則is[0] 就等于1,is[1]就等于2,
遞回方法:
遞回演算法是一種演算法,在java中遞回就是指 一個方法自身呼叫自己,就稱為遞回, 由于遞回是一種演算法思想所以就直接按實體來展示,
案例01:n的階乘
public class Dome03 { /* //簡單介紹一下階乘 * 一個正整數的階乘(factorial)是所有小于及等于該數的正整數的積,并且0的階乘為1, * 自然數n的階乘寫作n!,1808年,基斯頓·卡曼引進這個表示法, * 亦即n!=1×2×3×...×(n-1)×n,階乘亦可以遞回方式定義:0!=1,n!=(n-1)!×n, */ /* main入口 */ public static void main(String[] args) { int sum = sum(3); System.out.println(sum); } // 定義遞回求階乘方法 public static int sum(int n) { // n代表求幾的階乘 if (n == 1 || n == 0) { // 由于 0 的階乘 是1 1 的階乘也是1 所以設成出口 return 1; } else { return n * sum(n - 1); // 反復呼叫同一個方法直到碰上出口, } } }
遞回使用的注意點:
- 寫遞回演算法一定要設定出口,否則會造成堆疊溢位;
- 遞回方法的遞回次數也不能太多,否則會造成堆疊溢位;
為什么會造成堆疊溢位? 因為,方法中的變數隨著方法的呼叫而產生,隨著方法消失而消失(且是在堆疊中開辟空間);遞回是在方法中呼叫自己,所以當第一次執行的方法沒有結束時,整個方法就不會被摧毀,所以空間就一直存在,然后在方法中再次呼叫方法就會重新開辟一個空間,反復呼叫,就會反復創建,但第一次的方法還沒有執行完,導致方法無法摧毀,在創建的空間超過堆疊自身的記憶體而導致堆疊溢位,(死回圈也這個樣子),
注:使用遞回實作的功能,也可以用回圈實作,
構造方法:
首先,我們需要知道的是每一個類都默認存在一個無參的構造方法,
構造方法的特點:
- 首先構造方法也是方法 同樣也被權限修飾符所修飾
- 構造方法只有權限修飾符,與static 回傳值無關,方法名必須與類名同名 ,不能被static、final、synchronized、abstract和native修飾
- 構造方法有 無參構造方法和帶參構造方法
- 每一個類默認自帶一個無參構造方法
構造方法的作用:
- 構造出一個類的實體,當new物件的時候,程式首先執行的就是構造方法,
- 對實體化進行初始化
- 構造方法可以進行多載
public class Dome04 { String name; int age; /* 無參構造方法 */ public Dome04() { //方法名為類名 } /* 帶參構造方法 */ public Dome04(String name, int age) { //方法名為類名 且帶著引數 } }
this,static關鍵字:
this關鍵字說明: this是java提供的關鍵字,用來表示自身實體化物件,
三種使用方法:
- this.屬性名:用來訪問本類的成員方法,區分成員變數和區域變數
- this.方法名:來訪問本類中的方法,一般默認省略
- this()和this(引數1,引數2):來訪問本類的構造方法,訪問無參
this關鍵字演示代碼如下:
public class Dome05 { String name; int age; /* this關鍵字演示 */ public static void main(String[] args) { this.name; //this關鍵字不能在靜態方法中使用,main方法是一個靜態方法, } public Dome05() { this("zhangsan", 20); this.test1(); //this.方法名,訪問 本類中的成員方法 } public Dome05(String name, int age) { this.name ="李四"; //this.屬性名呼叫成員變數并賦值 this.age = age; //this.屬性名區分成員變數的age和成員變數的age System.out.println(this.name); //this.name 呼叫成員變數name } public void test1() { System.out.println("我是一個成員方法"); } }
static關鍵字使用:static關鍵字是Java提供的,方便在沒有創建物件的情況下進行呼叫(方法/變數),static可以用來修飾類的成員方法、類的成員變數,另外也可以撰寫static代碼塊來優化程式性能,
- static靜態修飾符可以修飾變數、方法、代碼塊、修飾的變數叫做靜態變數,方法叫做靜態方法,代碼塊叫做靜態代碼塊
- 被靜態修飾的,在類被加載的時候也一起加載,
靜態變數被全域共享,且只有一個副本,在類初次加載的時候初始化,非靜態變數是物件所擁有的,在創建物件的時候被初始化,存在多個副本,各個物件擁有的副本互不影響;使用方法:static int i =0;
靜態方法由于靜態方法不依賴于任何物件就可以直接訪問,因此對于靜態方法來說,是沒有this的;靜態方法中不能訪問非靜態的成員變數
語法: static 回傳值型別 方法名(引數串列){}
靜態代碼塊 :
- 靜態初始化塊,用于類的初始化操作
- static代碼塊隨著類的加載而加載,并且只初始化執行一次;
- 靜態代碼塊在類內方法外,可以存在多個
- 靜態初始化塊中不能直接訪問非static成員
代碼演示如下:
public class Dome06 { /* static關鍵字的使用 */ static int a = 0; //靜態的成員變數 int b = 1; static { System.out.println("我是一個靜態代碼塊"); } public static void name() { //靜態的成員方法 System.out.println(b); //靜態成員方法不可以訪問非靜態成員變數 System.out.println("我是一個靜態的成員方法"); } public void name2() { //普通的成員方法 System.out.println(a); //非靜態成員方法可以訪問靜態成員變數 System.out.println("我是一個普通的成員方法"); } }
除去靜態代碼塊之外,還有構造代碼塊,區域代碼塊 ,如下:
public class Dome07 { //構造代碼塊:類中方法外,用{}括起,每次呼叫構造方法前執行,用于給物件進行初始化 { System.out.println("我是一個構造代碼塊"); } //靜態代碼塊:類中方法外,加static修飾,用于給類進行初始化 static { System.out.println("我是一個靜態代碼塊"); } public static void main(String[] args) { //區域位置,用于限定變數的生命周期,提高記憶體利用率, { System.out.println("我是一個區域代碼塊"); } } }
單例模式:
單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一,這種型別的設計模式屬于創建型模式,它提供了一種創建物件的最佳方式,
這種模式涉及到一個單一的類,該類負責創建自己的物件,同時確保只有單個物件被創建,這個類提供了一種訪問其唯一的物件的方式,可以直接訪問,不需要實體化該類的物件,
注意:
-
1、單例類只能有一個實體,
-
2、單例類必須自己創建自己的唯一實體,
-
3、單例類必須給所有其他物件提供這一實體,
關鍵代碼:建構式是私有的,
代碼實作:
1、懶漢式,執行緒不安全
public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
2、餓漢式
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }
作業:
01.評委打分:
-
在編程競賽中,有6個評委為參賽的選手打分,分數為0-100的整數分,
-
選手的最后得分為:去掉一個最高分和一個最低分后 的4個評委平均值 (不考慮小數部分),
public class Dome03GameScore { /* * 在編程競賽中,有6個評委為參賽的選手打分,分數為0-100的整數分, 選手的最后得分為:去掉一個最高分和一個最低分后 的4個評委平均值 * (不考慮小數部分), */ public static void main(String[] args) { int[] arrysScore = arrysScore(); int avgScore = avgScore(arrysScore); System.out.println("這位選手的最終得分是:"+ avgScore); } // 鍵盤錄入六位評委的打分 public static int[] arrysScore() { { System.out.println("錄入程式開始"); } int[] arrys = new int[6]; Scanner sc = new Scanner(System.in); for (int i = 0; i < arrys.length; i++) { System.out.println("請輸入第" + (i + 1) + "為評委老師的分數"); arrys[i] = sc.nextInt(); } return arrys; } // 求六個評委的分數最大值 public static int maxScore(int[] arrsys) { int temp = arrsys[0]; for (int i = 0; i < arrsys.length-1; i++) { if (arrsys[i] < arrsys[i + 1]) { temp = arrsys[i + 1]; } } return temp; } // 求六個評委的分數最小值 public static int minScore(int[] arrsys) { int temp = arrsys[0]; for (int i = 0; i < arrsys.length-1; i++) { if (arrsys[i] > arrsys[i + 1]) { temp = arrsys[i + 1]; } } return temp; } // 求評委分數的平均值(去掉最大值最小值的平均值) public static int avgScore(int[] arrys) { int avg = 0; for (int i = 0; i < arrys.length; i++) { if (arrys[i] == maxScore(arrys) || arrys[i] == minScore(arrys)) { continue; } else { avg = avg + arrys[i]; } } return avg / (arrys.length - 2); } }
02.有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13....求出這個數列的前20項之和,
public class Dome03 { public static void main(String[] args) { /* 有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13....求出這個數列的前20項之和, */ // 方式一:for回圈 double a = 2.0, b = 1.0, sum = 0; for (int i = 1; i < 20; i++) { double tem = 0; sum = sum + a / b; tem = a; a = a + b; b = tem; } // 方式二 遞回 System.out.println(sum); double sumScore = sumScore(2, 1); System.out.println(sumScore); } // 方式二 遞回 static double i = 1; static double temp = 0; static double sum = 0; public static double sumScore(double a, double b) {// 傳遞a b初始值 a=2,b=1 2/1;求和的值sum if (i < 20 && i >= 1) { sum = sum + a / b; /* System.out.println(sum); */ temp = a; a = a + b; b = temp; i++; return sumScore(a, b); } else { return sum; } } }
個人學習,內容簡略
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/125364.html
標籤:Java
