3 จุดในวิธีการต่อไปนี้หมายถึงอะไร
public void myMethod(String... strings){
// method body
}
3 จุดในวิธีการต่อไปนี้หมายถึงอะไร
public void myMethod(String... strings){
// method body
}
คำตอบ:
หมายความว่าวัตถุสตริงเป็นศูนย์หรือมากกว่านั้น (หรืออาเรย์ของพวกเขา) อาจถูกส่งผ่านเป็นอาร์กิวเมนต์สำหรับวิธีการนั้น
ดูหัวข้อ "จำนวนข้อโต้แย้งโดยพลการ" ที่นี่: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs
ในตัวอย่างของคุณคุณสามารถเรียกมันดังต่อไปนี้:
myMethod(); // Likely useless, but possible
myMethod("one", "two", "three");
myMethod("solo");
myMethod(new String[]{"a", "b", "c"});
หมายเหตุสำคัญ:อาร์กิวเมนต์ที่ส่งผ่านด้วยวิธีนี้จะเป็นอาร์เรย์เสมอแม้ว่าจะมีเพียงรายการเดียวก็ตาม ตรวจสอบให้แน่ใจว่าคุณปฏิบัติเช่นนั้นในร่างกายวิธี
หมายเหตุสำคัญ 2:อาร์กิวเมนต์ที่ได้รับ...
จะต้องเป็นครั้งสุดท้ายในลายเซ็นวิธีการ ดังนั้นmyMethod(int i, String... strings)
ก็โอเค แต่myMethod(String... strings, int i)
ไม่เป็นไร
ขอบคุณ Vash สำหรับคำอธิบายในความคิดเห็นของเขา
someMethod(new SomeType[] { })
ที่จะผ่านองค์ประกอบอย่างน้อยหนึ่งอาจจะข้ามโดยเพียงแค่โทร นั่นจะเป็นการแฮ็กใช่ไหม?
คุณลักษณะนั้นเรียกว่าvarargsและเป็นคุณลักษณะที่นำมาใช้ใน Java 5 ซึ่งหมายความว่าฟังก์ชันสามารถรับString
อาร์กิวเมนต์ได้หลายอย่าง:
myMethod("foo", "bar");
myMethod("foo", "bar", "baz");
myMethod(new String[]{"foo", "var", "baz"}); // you can even pass an array
จากนั้นคุณสามารถใช้String
var เป็นอาร์เรย์:
public void myMethod(String... strings){
for(String whatever : strings){
// do what ever you want
}
// the code above is is equivalent to
for( int i = 0; i < strings.length; i++){
// classical for. In this case you use strings[i]
}
}
คำตอบนี้ยืมมาอย่างหนักจาก kiswa's และ Lorenzo's ... และจากความคิดเห็นของ Graphain
มันเป็น Varargs :)
varargs สั้นสำหรับอาร์กิวเมนต์ที่มีความยาวผันแปรคือคุณลักษณะที่อนุญาตให้วิธีการยอมรับจำนวนตัวแปรของอาร์กิวเมนต์ (ศูนย์หรือมากกว่า) ด้วย varargs มันกลายเป็นเรื่องง่ายที่จะสร้างวิธีการที่ต้องใช้จำนวนตัวแปรของการขัดแย้ง มีการเพิ่มคุณสมบัติของอากิวเมนต์ตัวแปรใน Java 5
ไวยากรณ์ของ varargs
vararg ถูกทำให้เป็นจริงโดยสามจุดไข่ปลา (สามจุด) หลังจากชนิดข้อมูลรูปแบบทั่วไปของมันคือ
return_type method_name(data_type ... variableName){
}
ต้องการ varargs
ก่อน Java 5 ในกรณีที่มีความต้องการตัวแปรจำนวนอาร์กิวเมนต์มีสองวิธีในการจัดการมัน
หากจำนวนอาร์กิวเมนต์สูงสุดวิธีสามารถทำได้น้อยและเป็นที่รู้จักดังนั้นวิธีการสร้างเวอร์ชันที่มากเกินไปอาจถูกสร้างขึ้นได้ หากจำนวนอาร์กิวเมนต์สูงสุดที่วิธีสามารถทำได้นั้นมีขนาดใหญ่หรือ / และไม่ทราบวิธีการนั้นก็คือการใส่อาร์กิวเมนต์เหล่านั้นลงในอาร์เรย์และส่งผ่านไปยังวิธีที่รับอาร์เรย์เป็นพารามิเตอร์ วิธีการทั้งสองนี้มีข้อผิดพลาดเกิดขึ้นบ่อยครั้งการสร้างอาเรย์ของพารามิเตอร์ทุกครั้งและยากต่อการบำรุงรักษาเนื่องจากการเพิ่มอาร์กิวเมนต์ใหม่อาจส่งผลให้เกิดการเขียนวิธีโอเวอร์โหลดใหม่
ข้อดีของ varargs
เสนอตัวเลือกที่ง่ายกว่ามาก โค้ดน้อยลงโดยไม่จำเป็นต้องเขียนวิธีการโอเวอร์โหลด
ตัวอย่างของ varargs
public class VarargsExample {
public void displayData(String ... values){
System.out.println("Number of arguments passed " + values.length);
for(String s : values){
System.out.println(s + " ");
}
}
public static void main(String[] args) {
VarargsExample vObj = new VarargsExample();
// four args
vObj.displayData("var", "args", "are", "passed");
//three args
vObj.displayData("Three", "args", "passed");
// no-arg
vObj.displayData();
}
}
Output
Number of arguments passed 4
var
args
are
passed
Number of arguments passed 3
Three
args
passed
Number of arguments passed 0
มันสามารถเห็นได้จากโปรแกรมที่ใช้ความยาวที่นี่เพื่อหาจำนวนของข้อโต้แย้งที่ส่งผ่านไปยังวิธีการ เป็นไปได้เพราะ varargs ถูกส่งผ่านทางอ้อมเป็นอาร์เรย์ อาร์กิวเมนต์ใดก็ตามที่ถูกส่งผ่านเป็น varargs จะถูกเก็บไว้ในอาร์เรย์ซึ่งอ้างอิงโดยชื่อที่กำหนดให้กับ varargs ในชื่ออาร์เรย์โปรแกรมนี้เป็นค่า นอกจากนี้โปรดทราบว่าวิธีการนั้นถูกเรียกด้วยจำนวนอาร์กิวเมนต์ที่แตกต่างกันการเรียกครั้งแรกด้วยสี่อาร์กิวเมนต์จากนั้นสามอาร์กิวเมนต์และจากนั้นจะมีศูนย์อาร์กิวเมนต์ การเรียกทั้งหมดเหล่านี้ได้รับการจัดการโดยวิธีการเดียวกับที่ใช้เวลาเป็น
ข้อ จำกัด กับ varargs
เป็นไปได้ที่จะมีพารามิเตอร์อื่นที่มีพารามิเตอร์ varargs ในวิธีการอย่างไรก็ตามในกรณีนั้นพารามิเตอร์ varargs จะต้องเป็นพารามิเตอร์สุดท้ายที่ประกาศโดยวิธีการ
void displayValues(int a, int b, int … values) // OK
void displayValues(int a, int b, int … values, int c) // compiler error
ข้อ จำกัด อื่นที่มี varargs คือต้องมีพารามิเตอร์ varargs เพียงพารามิเตอร์เดียวเท่านั้น
void displayValues(int a, int b, int … values, int … moreValues) // Compiler error
วิธีการมากเกินไป varargs
เป็นไปได้ที่จะโอเวอร์โหลดเมธอดที่รับพารามิเตอร์ varargs วิธีการ Varargs สามารถโอเวอร์โหลดโดย -
ประเภทของพารามิเตอร์ vararg สามารถแตกต่างกันได้ โดยการเพิ่มพารามิเตอร์อื่น ๆ ตัวอย่างของวิธีการบรรทุกเกินพิกัดวิธีการ
public class OverloadingVarargsExp {
// Method which has string vararg parameter
public void displayData(String ... values){
System.out.println("Number of arguments passed " + values.length);
for(String s : values){
System.out.println(s + " ");
}
}
// Method which has int vararg parameter
public void displayData(int ... values){
System.out.println("Number of arguments passed " + values.length);
for(int i : values){
System.out.println(i + " ");
}
}
// Method with int vararg and one more string parameter
public void displayData(String a, int ... values){
System.out.println(" a " + a);
System.out.println("Number of arguments passed " + values.length);
for(int i : values){
System.out.println(i + " ");
}
}
public static void main(String[] args) {
OverloadingVarargsExp vObj = new OverloadingVarargsExp();
// four string args
vObj.displayData("var", "args", "are", "passed");
// two int args
vObj.displayData(10, 20);
// One String param and two int args
vObj.displayData("Test", 20, 30);
}
}
Output
Number of arguments passed 4
var
args
are
passed
Number of arguments passed 2
10
20
a Test
Number of arguments passed 2
20
30
ความหลากหลายและความคลุมเครือเกินพิกัด
ในบางกรณีการโทรอาจไม่ชัดเจนในขณะที่เรามีวิธี varargs มากเกินไป ลองดูตัวอย่าง
public class OverloadingVarargsExp {
// Method which has string vararg parameter
public void displayData(String ... values){
System.out.println("Number of arguments passed " + values.length);
for(String s : values){
System.out.println(s + " ");
}
}
// Method which has int vararg parameter
public void displayData(int ... values){
System.out.println("Number of arguments passed " + values.length);
for(int i : values){
System.out.println(i + " ");
}
}
public static void main(String[] args) {
OverloadingVarargsExp vObj = new OverloadingVarargsExp();
// four string args
vObj.displayData("var", "args", "are", "passed");
// two int args
vObj.displayData(10, 20);
// This call is ambiguous
vObj.displayData();
}
}
ในโปรแกรมนี้เมื่อเราทำการเรียกเมธอด displayData () โดยไม่มีพารามิเตอร์ใด ๆ มันจะพ่นข้อผิดพลาดเนื่องจากคอมไพเลอร์ไม่แน่ใจว่าการเรียกเมธอดนี้ใช้สำหรับdisplayData(String ... values)
หรือdisplayData(int ... values)
วิธีเดียวกันถ้าเรามีวิธีการมากเกินไปที่หนึ่งมีvararg
วิธีหนึ่งประเภทและวิธีอื่นมีหนึ่งพารามิเตอร์และvararg
พารามิเตอร์ประเภทเดียวกันแล้วเราก็มีความกำกวม - As Exp -
displayData(int ... values)
และdisplayData(int a, int ... values)
วิธีการโอเวอร์โหลดทั้งสองวิธีนี้มักจะมีความกำกวมอยู่เสมอ
นี่เป็นวิธี Java เพื่อส่งผ่านvarargs (อาร์กิวเมนต์หมายเลขตัวแปร)
หากคุณคุ้นเคยกับ C นี่จะคล้ายกับ...
ไวยากรณ์ที่ใช้กับprintf
ฟังก์ชัน:
int printf(const char * format, ...);
แต่ในประเภทที่ปลอดภัยประเภท: ทุกอาร์กิวเมนต์จะต้องสอดคล้องกับประเภทที่ระบุ (ในตัวอย่างของคุณพวกเขาควรจะทั้งหมดString
)
นี่เป็นตัวอย่างง่ายๆของวิธีที่คุณสามารถใช้varargs :
class VarargSample {
public static void PrintMultipleStrings(String... strings) {
for( String s : strings ) {
System.out.println(s);
}
}
public static void main(String[] args) {
PrintMultipleStrings("Hello", "world");
}
}
...
อาร์กิวเมนต์เป็นจริงอาร์เรย์เพื่อให้คุณสามารถผ่านString[]
เป็นพารามิเตอร์
มันเป็นตัวอย่างของน้ำตาล syntactic เพราะมันถูกนำมาใช้เป็นอาร์เรย์ anyways (ซึ่งไม่ได้หมายความว่ามันไร้ประโยชน์) - ฉันชอบที่จะผ่านอาร์เรย์เพื่อให้ชัดเจนและยังประกาศวิธีการที่มีอาร์เรย์ของประเภทที่กำหนด แต่ความเห็นมากกว่าคำตอบ
นอกจากนี้เพื่อลดแสงบางอย่างสิ่งสำคัญคือต้องรู้ว่าพารามิเตอร์ var-arg ถูก จำกัด ไว้ที่หนึ่งและคุณไม่สามารถมีพารามิเตอร์ var-art หลายรายการ เช่นนี้เป็นภาพลวงตา:
public void myMethod(String... strings, int ... ints){
// method body
}
แค่คิดว่ามันเป็นคำหลักparams
ใน C # หากคุณมาจากพื้นหลังนั้น :)
วิธีที่ใช้กันทั่วไปเพื่อดูตัวอย่างที่ชัดเจนของการใช้จุดสามจุดที่มีอยู่ในหนึ่งในวิธีการที่โด่งดังที่สุดใน Android AsyncTask (วันนี้ไม่ได้ใช้มากเกินไปเนื่องจาก RXJAVA ไม่พูดถึงองค์ประกอบสถาปัตยกรรมของ Google) คุณสามารถค้นหาตัวอย่างมากมายที่ค้นหาคำศัพท์นี้และวิธีที่ดีที่สุดในการเข้าใจและไม่ลืมอีกต่อไปความหมายของสามจุดคือพวกเขาแสดง ... สงสัย ... เหมือนในภาษาทั่วไป กล่าวคือยังไม่ชัดเจนว่าจำนวนพารามิเตอร์ที่ต้องผ่านอาจเป็น 0 อาจเป็น 1 อาจจะมากกว่า (อาร์เรย์) ...
String...
เป็นเช่นเดียวกับ String[]
import java.lang.*;
public class MyClassTest {
//public static void main(String... args) {
public static void main(String[] args) {
for(String str: args) {
System.out.println(str);
}
}
}
String...
เป็นเช่นเดียวกับString[]
คุณไม่สามารถพูดได้ใช่ไหม
String[]
ต้องมีอาร์กิวเมนต์ (อย่างน้อยอาร์เรย์ว่าง) ในขณะที่String...
ไม่ได้ (ดูคำตอบข้างต้น)
การเพิ่มไปยังคำตอบที่เขียนอย่างดีอื่น ๆ ข้อได้เปรียบของvaragrs
ฉันพบว่ามีประโยชน์คือเมื่อฉันเรียกวิธีการที่มีอาร์เรย์เป็นชนิดพารามิเตอร์จะใช้ความเจ็บปวดจากการสร้างอาร์เรย์; เพิ่มองค์ประกอบแล้วส่ง แต่ฉันสามารถเรียกวิธีที่มีค่ามากที่สุดเท่าที่ฉันต้องการ จากศูนย์ถึงมาก
ตัวอย่างที่ 1:
public class quest1 {
public quest1(String... mynum) {
System.out.println("yee haa");
}
public static void main(String[] args) {
quest1 q=new quest1();
quest1 q1=new quest1("hello");
}
}
ตัวอย่างที่ 2:
public class quest1 {
public quest1(int... at) {
System.out.println("yee haa");
}
public quest1(String... at) {
System.out.println("yee haa");
}
public static void main(String[] args) {
quest1 q=new quest1("value");
quest1 q1=new quest1(1);
}
public void name(String ... s) {
}
}
เอาท์พุท:
ใช่แล้ว
ใช่แล้ว
ไวยากรณ์: (จุดสามจุด ... ) -> หมายถึงเราสามารถเพิ่มวัตถุเป็นศูนย์หรือมากกว่าผ่านในการขัดแย้งหรือผ่านอาร์เรย์ประเภทวัตถุ
public static void main(String[] args){}
public static void main(String... args){}
คำจำกัดความ: 1) อาร์กิวเมนต์ Object ... เป็นเพียงการอ้างอิงไปยังอาร์เรย์ของวัตถุ
2) ('String []' หรือ String ... ) สามารถจัดการวัตถุสตริงจำนวนเท่าใดก็ได้ ภายในจะใช้อาร์เรย์ของวัตถุประเภทอ้างอิง
i.e. Suppose we pass an Object array to the ... argument - will the resultant argument value be a two-dimensional array - because an Object[] is itself an Object:
3) ถ้าคุณต้องการเรียกใช้เมธอดที่มีอากิวเมนต์เดียวและมันเกิดขึ้นเป็นอาเรย์คุณจะต้องล้อมมันด้วย
another. method(new Object[]{array});
OR
method((Object)array), which will auto-wrap.
แอปพลิเคชัน: ส่วนใหญ่จะใช้เมื่อจำนวนอาร์กิวเมนต์เป็นแบบไดนามิก (จำนวนอาร์กิวเมนต์ที่ทราบที่รันไทม์) และในการแทนที่ กฎทั่วไป - ในวิธีการที่เราสามารถผ่านประเภทใด ๆ และจำนวนข้อโต้แย้งใด ๆ เราไม่สามารถเพิ่มอาร์กิวเมนต์ object (... ) ก่อนอาร์กิวเมนต์ใด ๆ กล่าวคือ
void m1(String ..., String s) this is a wrong approach give syntax error.
void m1(String s, String ...); This is a right approach. Must always give last order prefernces.