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