ไวยากรณ์การกำหนดค่าเริ่มต้นของอาร์เรย์เมื่อไม่อยู่ในการประกาศ


141

ฉันเขียนได้:

AClass[] array = {object1, object2}

ฉันยังสามารถเขียน:

AClass[] array = new AClass[2];
...
array[0] = object1;
array[1] = object2;

แต่ฉันไม่สามารถเขียน:

AClass[] array;
...
array = {object1, object2};

เหตุใดจึงถูกบล็อกโดย Java?

ฉันรู้วิธีการแก้ไข แต่บางครั้งมันก็จะง่ายขึ้น

ตัวอย่างเช่น:

public void selectedPointsToMove(cpVect coord) {

    if (tab == null) {
        if (arePointsClose(coord, point1, 10)) {
            cpVect[] tempTab = {point1};
            tab = tempTab;
        } else if (arePointsClose(point2, coord, 10)) {
            cpVect[] tempTab = {point2};
            tab = tempTab;
        } else {
            cpVect[] tempTab = {point1,point2};
            tab = tempTab;
        }
    }
}

คำถามง่าย ๆ นี้ที่บั๊กฉันตั้งแต่ฉันเรียนรู้วิธีเล่นกับอาร์เรย์ใน Java


ขออภัยเกี่ยวกับรูปแบบข้อความ แต่ด้วยเหตุผลบางอย่างในประเทศจีนปุ่มรูปแบบข้อความไม่ปรากฏ: S
Jason Rogers

สำหรับรหัสตรวจสอบให้แน่ใจว่ามีการเว้นวรรค 4 ครั้งขึ้นไป
Mat

ปัญหาอื่นคือคุณมีอักขระ TAB ในรหัสที่คุณวาง สิ่งนี้จะทำให้การจัดรูปแบบยุ่งเหยิง
สตีเฟ่นซี

ขอบคุณโอกิ eclipse ใช้แท็บในการเยื้องดังนั้นเมื่อฉันคัดลอกวางมันทำให้เกิดความยุ่งเหยิง ขอบคุณสำหรับการแก้ไข
Jason Rogers

Eclipse สามารถและควรตั้งค่าใหม่เพื่อไม่ให้ใช้อักขระ TAB เพื่อเยื้อง โปรดอย่าใช้มันเป็นข้อแก้ตัว
สตีเฟ่นซี

คำตอบ:


137

เหตุใดจึงถูกบล็อกโดย Java?

คุณต้องถามนักออกแบบ Java อาจมีเหตุผลทางไวยากรณ์ที่ลึกซึ้งสำหรับข้อ จำกัด โปรดทราบว่าบางส่วนของโครงสร้างการสร้าง / การเริ่มต้นไม่ได้อยู่ใน Java 1.0 และ (IIRC) ถูกเพิ่มใน Java 1.1

แต่ "ทำไม" ไม่สำคัญ ... มีข้อ จำกัด และคุณต้องอยู่กับมัน

ฉันรู้วิธีการแก้ไข แต่บางครั้งมันก็จะง่ายขึ้น

คุณสามารถเขียนสิ่งนี้:

AClass[] array;
...
array = new AClass[]{object1, object2};

9
ไม่มีการประกาศใหม่จะไม่มีความแตกต่างระหว่างชุดคำสั่งบล็อกและตัวเริ่มต้นอาร์เรย์ (เช่นใน javascript ซึ่งอาจทำให้เข้าใจผิด}
bestsss

10
มันจะทำให้สับสน ... และยากที่จะแยกวิเคราะห์ พิจารณาว่า{o1()}เป็นนิพจน์ที่ถูกต้องและ{o1();}เป็นบล็อกคำสั่งที่ถูกต้อง เครื่องมือแยกวิเคราะห์จะต้องไปที่ '}' หรือ ';' ก่อนที่มันจะสามารถแยกความแตกต่างของทั้งสองกรณี ปัญหาทางไวยากรณ์นั้นไม่ได้ลึกซึ้งเลย !!
สตีเฟ่นซี

19

ฉันจะพยายามตอบคำถามที่ว่าทำไม: อาร์เรย์ Java นั้นเรียบง่ายและเป็นพื้นฐานเมื่อเทียบกับคลาสอย่าง ArrayList ที่มีพลังมากขึ้น Java ต้องการทราบ ณ เวลาที่ประกาศว่าควรจัดสรรหน่วยความจำให้กับอาร์เรย์เท่าใด ArrayList นั้นมีความไดนามิกมากกว่าและขนาดของมันก็อาจเปลี่ยนแปลงไปตามกาลเวลา

หากคุณเริ่มต้นอาร์เรย์ของคุณด้วยความยาวของสองและหลังจากนั้นมันกลับกลายเป็นว่าคุณต้องการความยาวสามคุณจะต้องทิ้งสิ่งที่คุณมีและสร้างอาร์เรย์ใหม่ทั้งหมด ดังนั้นคำหลัก 'ใหม่'

ในสองตัวอย่างแรกของคุณคุณบอกเวลาการประกาศจำนวนหน่วยความจำที่จะจัดสรร ในตัวอย่างที่สามของคุณชื่ออาเรย์จะกลายเป็นตัวชี้ไปที่ไม่มีอะไรเลยดังนั้นเมื่อเริ่มต้นแล้วคุณจะต้องสร้างอาเรย์ใหม่อย่างชัดเจนเพื่อจัดสรรหน่วยความจำในปริมาณที่เหมาะสม

ฉันจะบอกว่า (และถ้ามีคนรู้ดีกว่าโปรดแก้ไขให้ฉัน) ตัวอย่างแรก

AClass[] array = {object1, object2}

จริง ๆ แล้วหมายถึง

AClass[] array = new AClass[]{object1, object2};

แต่สิ่งที่นักออกแบบ Java ทำคือทำวิธีที่รวดเร็วกว่าในการเขียนถ้าคุณสร้างอาร์เรย์ในเวลาที่ประกาศ

วิธีแก้ปัญหาที่แนะนำนั้นดี หากการใช้เวลาหรือหน่วยความจำมีความสำคัญในขณะใช้งานให้ใช้อาร์เรย์ ถ้ามันไม่สำคัญและคุณต้องการรหัสที่ง่ายต่อการเข้าใจและใช้งานได้ให้ใช้ ArrayList


2
นี้เป็นทางลัดที่คุณได้กล่าวอ้างของออราเคิล: "หรือคุณสามารถใช้ไวยากรณ์ทางลัดในการสร้างและการเตรียมอาร์เรย์" เหตุผลอาจเป็นเพราะอาร์เรย์ต้องมีพื้นที่ว่างในหน่วยความจำโดยใช้สิ่งใหม่ในบางจุด ใหม่มีความหมายในทางลัด แต่ทางลัดนั้นใช้ได้ในการประกาศเท่านั้น ที่อื่นไม่มีการอนุญาตให้ใช้ทางลัดและจำเป็นต้องมีสิ่งใหม่
นาที

3
ฉันขอโทษ แต่ความพยายามของคุณในการตอบคำถาม "ทำไม" ไม่ถือน้ำ คอมไพเลอร์จะสามารถคำนวณจำนวนอาร์เรย์ที่ต้องการโดยการนับนิพจน์ระหว่าง{และ}... เช่นเดียวกับที่ทำกับฟอร์มเริ่มต้นที่ได้รับอนุญาต
สตีเฟ่นซี

8

ฉันไม่สามารถตอบว่าทำไมส่วน

แต่ถ้าคุณต้องการบางสิ่งบางอย่างแบบไดนามิกแล้วทำไมคุณไม่ลองพิจารณา Collection ArrayList

ArrrayList สามารถเป็นประเภทวัตถุใด ๆ

และหากเป็นการบังคับคุณต้องการให้มันเป็นอาร์เรย์คุณสามารถใช้วิธี toArray () กับมัน

ตัวอย่างเช่น:

            ArrayList<String> al = new ArrayList<String>();
            al.add("one");
            al.add("two");
            String[] strArray = (String[]) al.toArray(new String[0]);

ฉันหวังว่านี่จะช่วยคุณได้


2
ไม่จำเป็นต้องร่ายชนิดส่งคืนของ Array to String [] โดยสัญญา Array ที่ส่งคืนจะเป็นชนิดเดียวกับอาร์เรย์ที่ระบุ docs.oracle.com/javase/6/docs/api/java/util/ …
Ankur Agarwal

4

สำหรับพวกคุณที่ไม่ชอบnew AClass[] { ... }ไวยากรณ์ที่ชั่วร้ายนี่คือน้ำตาลบ้าง:

public AClass[] c(AClass... arr) { return arr; }

ใช้ฟังก์ชั่นเล็ก ๆ น้อย ๆ นี้ตามที่คุณต้องการ:

AClass[] array;
...
array = c(object1, object2);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.