站群網(wǎng)絡促銷的方法有哪些
1 Java可變長參數(shù)
1.1 概述
Java 的可變長參數(shù)(Varargs)是在 Java 1.5 中引入的功能,允許方法接受任意數(shù)量的相同類型的參數(shù)??勺儏?shù)的語法是在參數(shù)類型后面加上三個點(...
),例如 int... numbers
。
1.2 使用規(guī)則
- 可變參數(shù)必須放在參數(shù)列表的最后一位:如果方法有多個參數(shù),可變參數(shù)必須放在最后。例如:
public void printNumbers(String prefix, int... numbers) {// 方法體 }
- 只能有一個可變參數(shù):一個方法中只能有一個可變參數(shù)。
1.3 原理
當使用可變參數(shù)時,Java 會在編譯時創(chuàng)建一個數(shù)組,數(shù)組的大小就是傳入的可變參數(shù)的數(shù)量。然后將這些參數(shù)放入數(shù)組中,并將數(shù)組傳遞給方法。
例如:
public void printNumbers(int... numbers) {for (int number : numbers) {System.out.println(number);}
}
調(diào)用 printNumbers(1, 2, 3)
時,Java 會創(chuàng)建一個 int[]
數(shù)組 {1, 2, 3}
,然后傳遞給方法。
1.4 使用場景
可變參數(shù)通常用于需要處理任意數(shù)量相同類型對象的場景。例如:
- 打印任意數(shù)量的整數(shù)
- 計算任意數(shù)量的數(shù)字的和
- 處理任意數(shù)量的字符串
1.5 注意事項
-
避免重載帶有可變參數(shù)的方法:重載帶有可變參數(shù)的方法可能會導致編譯器無法確定調(diào)用哪個方法,從而引發(fā)編譯錯誤。例如:
public void print(String... args) {// 方法體 }public void print(String arg1, String... args) {// 方法體 }
調(diào)用
print("a")
時,編譯器無法確定是調(diào)用第一個方法還是第二個方法。 -
明確指示:如果必須重載帶有可變參數(shù)的方法,確保在調(diào)用時明確指示參數(shù),避免編譯器混淆。
1.6 示例代碼
public class VarargsExample {public static void main(String[] args) {printNumbers(1, 2, 3);printNumbers(4, 5);printNumbers();}public static void printNumbers(int... numbers) {for (int number : numbers) {System.out.println(number);}}
}
2 Java native方法
2.1 概念
本地方法(Native Method)是用 native
關鍵字修飾的方法,通常不需要用 Java 語言實現(xiàn)。本地方法允許 Java 代碼調(diào)用其他語言(如 C/C++)編寫的代碼。
2.2 JNI:Java Native Interface
JNI(Java Native Interface)是 Java 平臺的一部分,從 Java 1.1 開始引入,允許 Java 代碼與其他語言編寫的代碼進行交互。JNI 主要用于以下場景:
- 標準 Java 類庫不支持的功能
- 調(diào)用已有的 C/C++ 庫
- 提高性能,特別是在需要接近硬件或運行次數(shù)特別多的方法中
2.2.1 JNI 的優(yōu)點
- 擴展 Java 功能:可以通過 JNI 調(diào)用其他語言編寫的庫。
- 性能優(yōu)化:在某些情況下,使用本地代碼可以提高性能。
2.2.2 JNI 的缺點
- 跨平臺性喪失:本地代碼通常不跨平臺,需要在不同系統(tǒng)環(huán)境下重新編譯。
- 安全性降低:本地代碼的不當使用可能導致程序崩潰。
2.3 用 C 語言編寫本地方法
2.3.1 步驟
- 編寫帶有 native 方法的 Java 類,生成
.java
文件。 - 編譯 Java 類,生成
.class
文件。 - 生成頭文件:使用
javah -jni
或javac -h
生成.h
文件。 - 實現(xiàn)本地方法:使用 C/C++ 實現(xiàn)
.h
文件中的方法,生成.c
或.cpp
文件。 - 生成動態(tài)鏈接庫:將 C/C++ 編寫的文件生成動態(tài)鏈接庫(如
.dll
或.so
)。
2.3.2 示例:HelloWorld 程序
-
編寫 Java 類:
public class HelloJNI {static {System.loadLibrary("hello"); // 加載動態(tài)鏈接庫}public native void sayHello(); // 聲明本地方法public static void main(String[] args) {new HelloJNI().sayHello(); // 調(diào)用本地方法} }
-
編譯 Java 類:
javac HelloJNI.java
-
生成頭文件:
javac -h . HelloJNI.java
這將生成
HelloJNI.h
文件。 -
實現(xiàn)本地方法:
#include <jni.h> #include "HelloJNI.h" #include <stdio.h>JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject obj) {printf("Hello, JNI!\n"); }
-
編寫編譯腳本:
# compile.sh gcc -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -dynamiclib -o libhello.dylib HelloJNI.c
-
執(zhí)行腳本:
sh compile.sh
-
運行 Java 程序:
java HelloJNI
2.4 JNI 調(diào)用 C 的流程圖
Java 代碼 -> JNI 接口 -> 本地代碼 (C/C++)
2.5 native 關鍵字
-
native 用于修飾方法,表示該方法的實現(xiàn)在外部定義,通常用 C/C++ 實現(xiàn)。
-
語法:
- 修飾方法的位置必須在返回類型之前。
- 不能用
abstract
修飾,沒有方法體。 - 返回值可以是任意類型。
-
native 方法示例
public native void sayHello();
2.6 小結
- JNI 允許 Java 代碼與其他語言編寫的代碼進行交互,擴展了 Java 的功能。
- 本地方法 用
native
關鍵字修飾,通常用于調(diào)用 C/C++ 庫或提高性能。 - 注意事項:使用 JNI 會喪失跨平臺性,且本地代碼的不當使用可能導致程序崩潰。
3 Java構造方法
3.1 概念
構造方法(Constructor)是 Java 中的一種特殊方法,用于在創(chuàng)建對象時初始化對象的狀態(tài)。每次使用 new
關鍵字創(chuàng)建對象時,構造方法至少會被調(diào)用一次。如果沒有顯式定義構造方法,編譯器會提供一個默認的無參構造方法。
3.2 創(chuàng)建構造方法的規(guī)則
- 名稱與類名相同:構造方法的名稱必須與類名完全一致。
- 無返回類型:構造方法沒有返回類型,包括
void
。 - 不能是抽象的、靜態(tài)的、最終的、同步的:
- 抽象:構造方法不能被子類繼承,因此用
abstract
修飾沒有意義。 - 靜態(tài):構造方法用于初始化對象,因此用
static
修飾沒有意義。 - 最終:構造方法不能被子類繼承,因此用
final
修飾沒有意義。 - 同步:多個線程不會同時創(chuàng)建內(nèi)存地址相同的同一個對象,因此用
synchronized
修飾沒有必要。
- 抽象:構造方法不能被子類繼承,因此用
3.3 語法格式
class class_name {public class_name(){} // 默認無參構造方法public ciass_name([paramList]){} // 定義有參數(shù)列表的構造方法…// 類主體
}
3.4 默認構造方法
- 無參構造方法:如果構造方法沒有任何參數(shù),它就是一個無參構造方法。
- 默認構造方法:如果類中沒有顯式定義構造方法,編譯器會自動提供一個無參構造方法。
- 目的:主要為對象的字段提供默認值。
- 代碼示例
public class DefaultConstructorExample {private int value;// 編譯器提供的默認構造方法public DefaultConstructorExample() {this.value = 0; // 默認值}public static void main(String[] args) {DefaultConstructorExample obj = new DefaultConstructorExample();System.out.println(obj.value); // 輸出: 0}
}
3.5 有參構造方法
- 有參數(shù)的構造方法:可以有一個或多個參數(shù),用于為不同的對象提供不同的初始值。
- 替代方案:如果沒有有參構造方法,可以通過
setter
方法為字段賦值。 - 代碼示例
public class ParameterizedConstructorExample {private String name;public ParameterizedConstructorExample(String name) {this.name = name;}public static void main(String[] args) {ParameterizedConstructorExample obj = new ParameterizedConstructorExample("Java");System.out.println(obj.name); // 輸出: Java}
}
3.6 重載構造方法
- 構造方法重載:通過提供不同的參數(shù)列表來重載構造方法。編譯器會根據(jù)參數(shù)的數(shù)量和類型來決定調(diào)用哪一個構造方法。
- 代碼示例
public class OverloadedConstructorExample {private int id;private String name;public OverloadedConstructorExample(int id) {this.id = id;}public OverloadedConstructorExample(int id, String name) {this.id = id;this.name = name;}public static void main(String[] args) {OverloadedConstructorExample obj1 = new OverloadedConstructorExample(1);OverloadedConstructorExample obj2 = new OverloadedConstructorExample(2, "Java");System.out.println(obj1.id); // 輸出: 1System.out.println(obj2.id + " " + obj2.name); // 輸出: 2 Java}
}
3.7 構造方法和方法的區(qū)別
特性 | 方法 | 構造方法 |
---|---|---|
目的 | 反映對象的行為 | 初始化對象的字段 |
返回類型 | 可以有返回類型 | 沒有返回類型 |
調(diào)用方式 | 明確的,開發(fā)者通過代碼決定調(diào)用 | 隱式的,通過編譯器完成 |
編譯器提供 | 不會由編譯器提供 | 如果沒有明確提供無參構造方法,編譯器會提供 |
名稱 | 可以和類名相同,也可以不同 | 必須和類名相同 |
3.8 復制對象
復制一個對象可以通過以下三種方式完成:
- 通過構造方法:使用另一個對象作為參數(shù)來創(chuàng)建新對象。
- 通過對象的值:手動復制對象的每個字段。
- 通過
Object
類的clone()
方法:實現(xiàn)Cloneable
接口并重寫clone()
方法。
- 通過構造方法
public class CopyConstrutorPerson {private String name;private int age;public CopyConstrutorPerson(String name, int age) {this.name = name;this.age = age;}public CopyConstrutorPerson(CopyConstrutorPerson person) {this.name = person.name;this.age = person.age;}public void out() {System.out.println("姓名 " + name + " 年齡 " + age);}public static void main(String[] args) {CopyConstrutorPerson p1 = new CopyConstrutorPerson("沉默王二",18);p1.out();CopyConstrutorPerson p2 = new CopyConstrutorPerson(p1);p2.out();}
}
在上面的例子中,有一個參數(shù)為 CopyConstrutorPerson 的構造方法,可以把該參數(shù)的字段直接復制到新的對象中,這樣的話,就可以在 new 關鍵字創(chuàng)建新對象的時候把之前的 p1 對象傳遞過去。
- 通過對象的值
public class CopyValuePerson {private String name;private int age;public CopyValuePerson(String name, int age) {this.name = name;this.age = age;}public CopyValuePerson() {}public void out() {System.out.println("姓名 " + name + " 年齡 " + age);}public static void main(String[] args) {CopyValuePerson p1 = new CopyValuePerson("沉默王二",18);p1.out();CopyValuePerson p2 = new CopyValuePerson();p2.name = p1.name;p2.age = p1.age;p2.out();}
}
直接拿 p1 的字段值復制給 p2 對象(p2.name = p1.name)
- 通過
Object
類的clone()
方法
public class ClonePerson implements Cloneable {private String name;private int age;public ClonePerson(String name, int age) {this.name = name;this.age = age;}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}public void out() {System.out.println("姓名 " + name + " 年齡 " + age);}public static void main(String[] args) throws CloneNotSupportedException {ClonePerson p1 = new ClonePerson("沉默王二",18);p1.out();ClonePerson p2 = (ClonePerson) p1.clone();p2.out();}
}
通過 clone()
方法復制對象的時候,ClonePerson
必須先實現(xiàn) Cloneable
接口的 clone()
方法,然后再調(diào)用clone()
方法(ClonePerson p2 = (ClonePerson) p1.clone())
。
3.9 小結
- 構造方法雖然沒有返回值,但返回的是類的對象。
- 初始化字段只是構造方法的一種工作,它還可以做更多,比如啟動線程、調(diào)用其他方法等。
4 思維導圖
參考鏈接
-
Java可變參數(shù)詳解,5分鐘教會我妹
-
手把手教你用 C語言實現(xiàn) Java native 本地方法
-
Java構造方法:打開Java對象創(chuàng)建之門的鑰匙