อะไรคือความแตกต่างระหว่าง double a = a + int b และ int a += double b?

ทำไม:

public class Addition { 
  public static void main() { 
    int a = 0; 
    double b = 1.0; 
    a = a + b;
    System.out.println(a); 
  }
}

ไม่รวบรวม แต่:

public class Addition { 
  public static void main() { 
    int a = 0; 
    double b = 1.0; 
    a += b; 
    System.out.println(a); 
  }
}

คอมไพล์


person rawnd    schedule 03.03.2009    source แหล่งที่มา


คำตอบ (4)


ใน Java += โอเปอเรเตอร์มีการส่งแบบนัยไปยังประเภทมือซ้าย สิ่งนี้ใช้ได้กับตัวดำเนินการที่ประกอบทั้งหมด

person DefLog    schedule 03.03.2009
comment
ฉันคิดว่านี่เป็นคำตอบที่กระชับมากขึ้น - person matt b; 04.03.2009

int = int + double เป็นหลัก

int = สองเท่า + สองเท่า

และคุณไม่สามารถทำสิ่งนั้นได้โดยไม่แคสต์...

int += double บังคับให้ผลลัพธ์เป็น int ในขณะที่อีกอันหนึ่งต้องการการร่าย

ดังนั้น a = (int)(a + b);

ควรรวบรวม

แก้ไข: ตามที่ร้องขอในความคิดเห็น ... นี่คือลิงค์สำหรับการอ่านเพิ่มเติม (ไม่ใช่วิธีอ่านที่ง่ายที่สุด แต่เป็นข้อมูลที่ถูกต้องที่สุด): http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.2

person TofuBeer    schedule 03.03.2009
comment
คุณช่วยระบุลิงค์เกี่ยวกับเรื่องนั้นเพื่ออ่านเพิ่มเติมได้ไหม? ขอบคุณ - person hhafez; 04.03.2009
comment
ฉันคิดว่าเหตุผลที่ลึกซึ้งก็คือเพราะมันไม่ได้รับอนุญาตให้กำหนดในขณะที่แคบลง: byte = int ไม่ได้รับอนุญาตและ int = double เช่นกัน เราจะทำไบต์ง่ายๆ a; ก += 2; และล้มเหลวในการคอมไพล์ ผู้คนก็โยนรองเท้าไปที่จาวา แต่ฉันยังคงชอบกฎเพิ่มเติมที่ทำให้มันทำงานได้โดยไม่ต้องใช้นักแสดง :( - person Johannes Schaub - litb; 04.03.2009
comment
ฉันไม่แน่ใจว่ามีเหตุผลที่ลึกซึ้ง แต่ข้อกำหนดภาษา Java กำหนดนักแสดงโดยนัยอย่างชัดเจน: java.sun.com/docs/books/jls/second_edition/html/ - person DefLog; 04.03.2009

double + int ส่งกลับ double ดังนั้น double = double + int นั้นถูกต้องตามกฎหมาย ดู JLS 5.1.2 การขยายการแปลงแบบดั้งเดิมในทางกลับกัน int = double + int คือ "การทำให้การแปลงดั้งเดิมแคบลง" และต้องใช้นักแสดงที่ชัดเจน

person devdimi    schedule 04.03.2009

ตามที่ทุกคนระบุไว้แล้ว += มีนักแสดงโดยนัย เพื่อช่วยอธิบาย ฉันจะใช้แอปที่ฉันเขียนไว้เมื่อไม่นานมานี้ซึ่งเหมาะสำหรับคำถามประเภทนี้ มันเป็นตัวแยกส่วนออนไลน์เพื่อให้คุณสามารถตรวจสอบรหัสไบต์จริงที่ผลิต: http://javabytes.herokuapp.com/

และตารางความหมาย: http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings

ลองมาดูที่ bytecode จากโค้ด Java ง่ายๆ:

int i = 5;
long j = 8;
i += j;

รหัสที่ถอดประกอบ ความคิดเห็นของฉันจะมี // นำหน้า

   Code:
        0: iconst_5  //load int 5 onto stack
        1: istore_0  //store int value into variable 0 (we called it i)
        2: ldc2_w #2; //long 8l
                     //load long 8 value onto stack.  Note the long 8l above
                     //is not my comment but how the disassembled code displays 
                     //the value long 8 being used with the ldc2_w instruction
        5: lstore_1  //store long value into variable 1 (we called it j)
        6: iload_0   //load int value from variable 0
        7: i2l       //convert int into a long.  At this point we have 5 long
        8: lload_1   //load value from variable 1
        9: ladd      //add the two values together.  We are adding two longs
                     //so it's no problem
        10: l2i      //THIS IS THE MAGIC.  This converts the sum back to an int
       11: istore_0  //store in variable 0 (we called it i)
person Jonnyman9    schedule 27.02.2013