JavaRush /จาวาบล็อก /Random-TH /ข้อผิดพลาดของโปรแกรมเมอร์ Java มือใหม่ ส่วนที่ 2
articles
ระดับ

ข้อผิดพลาดของโปรแกรมเมอร์ Java มือใหม่ ส่วนที่ 2

เผยแพร่ในกลุ่ม
ข้อผิดพลาดของโปรแกรมเมอร์ Java มือใหม่ ส่วนที่ 1

9. การเรียกเมธอดคลาสแบบไม่คงที่จากเมธอด main()

จุดเริ่มต้นของโปรแกรม Java ใด ๆ ควรเป็นวิธีการแบบคงที่main:
ข้อผิดพลาดของโปรแกรมเมอร์ Java มือใหม่  ส่วนที่ 2 - 1
public static void main(String[] args) {
  ...
}
เนื่องจากวิธีนี้เป็นแบบคงที่ คุณจึงไม่สามารถเรียกใช้วิธีคลาสที่ไม่คงที่ได้ นักเรียนมักจะลืมเรื่องนี้และพยายามเรียกใช้เมธอดโดยไม่สร้างอินสแตนซ์ของชั้นเรียน ข้อผิดพลาดนี้มักเกิดขึ้นในช่วงเริ่มต้นของการฝึกอบรม เมื่อนักเรียนเขียนโปรแกรมขนาดเล็ก ตัวอย่างที่ไม่ถูกต้อง:
public class DivTest {
    boolean divisible(int x, int y) {
        return (x % y == 0);
    }

    public static void main(String[] args) {
        int v1 = 14;
        int v2 = 9;

        // на следующие строки компилятор выдаст ошибку
        if (divisible(v1, v2)) {
            System.out.println(v1 + " is a multiple of " + v2);
        } else {
            System.out.println(v2 + " does not divide " + v1);
        }
    }
}
มี 2 ​​วิธีในการแก้ไขข้อผิดพลาด: ทำให้วิธีการที่ต้องการคงที่หรือสร้างอินสแตนซ์ของคลาส ในการเลือกวิธีการที่ถูกต้อง ให้ถามตัวเองว่าวิธีการนั้นใช้ field หรือวิธีการเรียนอื่น ๆ ถ้าใช่ คุณควรสร้างอินสแตนซ์ของคลาสและเรียกใช้เมธอดในคลาสนั้น ไม่เช่นนั้นคุณควรทำให้เมธอดเป็นแบบคงที่ ตัวอย่างที่แก้ไข 1:
public class DivTest {
    int modulus;

    public DivTest(int m) {
      modulus = m;
    }

    boolean divisible(int x) {
        return (x % modulus == 0);
    }

    public static void main(String[] args) {
        int v1 = 14;
        int v2 = 9;

        DivTest tester = new DivTest(v2);

        if (tester.divisible(v1) {
            System.out.println(v1 + " is a multiple of " + v2);
        } else {
            System.out.println(v2 + " does not divide " + v1);
        }
    }
}
ตัวอย่างที่แก้ไข 2:
public class DivTest {
    static boolean divisible(int x, int y) {
        return (x % y == 0);
    }

    public static void main(String[] args) {
        int v1 = 14;
        int v2 = 9;

        if (divisible(v1, v2)) {
            System.out.println(v1 + " is a multiple of " + v2);
        } else {
            System.out.println(v2 + " does not divide " + v1);
        }
    }
}

10. การใช้วัตถุคลาส String เป็นพารามิเตอร์วิธีการ

ใน Java คลาสjava.lang.Stringเก็บข้อมูลสตริง อย่างไรก็ตามสตริงใน Java
  1. มีความคงอยู่ (คือ เปลี่ยนแปลงไม่ได้)
  2. เป็นวัตถุ
ดังนั้นจึงไม่สามารถถือว่าเป็นเพียงบัฟเฟอร์อักขระได้ เนื่องจากเป็นอ็อบเจ็กต์ที่ไม่เปลี่ยนรูป บางครั้งนักเรียนส่งสตริงโดยคาดไม่ถึงว่าวัตถุสตริงจะถูกส่งผ่านเป็นอาร์เรย์อักขระโดยการอ้างอิง (เช่นใน C หรือ C++) คอมไพเลอร์มักจะไม่ถือว่านี่เป็นข้อผิดพลาด ตัวอย่างที่ไม่ถูกต้อง
public static void main(String args[]) {
   String test1 = "Today is ";
   appendTodaysDate(test1);
   System.out.println(test1);
}

/* прим. редактора: закомментированный метод должен иметь модификатор
    static (здесь автором допущена ошибка №9)
public void appendTodaysDate(String line) {
    line = line + (new Date()).toString();
}
*/

public static void appendTodaysDate(String line) {
    line = line + (new Date()).toString();
}
ในตัวอย่างข้างต้น นักเรียนต้องการเปลี่ยนค่าของตัวแปรท้องถิ่นโดยtest1การกำหนดค่าใหม่ให้กับพารามิเตอร์lineในเมธอด appendTodaysDateโดยธรรมชาติแล้วสิ่งนี้จะไม่ทำงาน ความหมายlineจะเปลี่ยนไปแต่ความหมายtest1จะคงเดิม ข้อผิดพลาดนี้เกิดขึ้นเนื่องจากความเข้าใจผิดว่า (1) อ็อบเจ็กต์ Java ถูกส่งผ่านโดยการอ้างอิงเสมอ และ (2) สตริงใน Java นั้นไม่เปลี่ยนรูป คุณต้องเข้าใจว่าออบเจ็กต์สตริงไม่เคยเปลี่ยนค่า และการดำเนินการทั้งหมดบนสตริงจะสร้างออบเจ็กต์ใหม่ ในการแก้ไขข้อผิดพลาดในตัวอย่างข้างต้น คุณจะต้องส่งคืนสตริงจากเมธอด หรือส่งออบเจ็กต์StringBufferเป็นพารามิเตอร์ไปยังเมธอดStringแทน ตัวอย่างที่แก้ไข 1:
public static void main(String args[]) {
   String test1 = "Today is ";
   test1 = appendTodaysDate(test1);
   System.out.println(test1);
}

public static String appendTodaysDate(String line) {
    return (line + (new Date()).toString());
}
ตัวอย่างที่แก้ไข 2:
public static void main(String args[]) {
   StringBuffer test1 = new StringBuffer("Today is ");
   appendTodaysDate(test1);
   System.out.println(test1.toString());
}

public static void appendTodaysDate(StringBuffer line) {
    line.append((new Date()).toString());
}

ประมาณ การแปล
จริงๆ แล้วมันไม่ง่ายเลยที่จะเข้าใจว่าข้อผิดพลาดคืออะไร เนื่องจากวัตถุถูกส่งผ่านโดยการอ้างอิง จึงหมายความว่าlineวัตถุนั้นอ้างอิงถึงสถานที่เดียวกันtest1กับ ซึ่งหมายความว่าโดยการสร้างอันใหม่lineเราจึงสร้างอันใหม่test1ในตัวอย่างที่ผิด ทุกอย่างดูเหมือนกับว่าการถ่ายโอนStringเป็นไปตามมูลค่า ไม่ใช่โดยการอ้างอิง

11. การประกาศตัวสร้างเป็นวิธีการ

ตัวสร้างวัตถุใน Java มีลักษณะคล้ายกับวิธีปกติ ข้อแตกต่างเพียงอย่างเดียวคือ Constructor ไม่ได้ระบุประเภทของค่าที่ส่งคืน และชื่อจะเหมือนกับชื่อคลาส น่าเสียดายที่ Java อนุญาตให้ชื่อวิธีการเหมือนกับชื่อคลาส ในตัวอย่างด้านล่าง นักเรียนต้องการเริ่มต้นฟิลด์ของชั้นเรียนVector listเมื่อสร้างชั้นเรียน สิ่งนี้จะไม่เกิดขึ้นเนื่องจากเมธอด'IntList'ไม่ใช่ตัวสร้าง ตัวอย่างที่ไม่ถูกต้อง
public class IntList {
    Vector list;

    // Выглядит How конструктор, но на самом деле это метод
    public void IntList() {
        list = new Vector();
    }

    public append(int n) {
        list.addElement(new Integer(n));
    }
}
รหัสจะส่งข้อยกเว้น ในครั้งแรก ที่NullPointerExceptionมีการเข้าถึงฟิลด์ listข้อผิดพลาดนั้นแก้ไขได้ง่าย: คุณเพียงแค่ต้องลบค่าที่ส่งคืนออกจากส่วนหัวของวิธีการ ตัวอย่างที่แก้ไข:
public class IntList {
    Vector list;

    // Это конструктор
    public IntList() {
        list = new Vector();
    }

    public append(int n) {
        list.addElement(new Integer(n));
    }
}

12. ลืมส่งวัตถุตามประเภทที่ต้องการ

เช่นเดียวกับภาษาเชิงวัตถุอื่น ๆ ใน Java คุณสามารถอ้างถึงอ็อบเจ็กต์เป็นซูเปอร์คลาสได้ สิ่งนี้เรียกว่า'upcasting'มันถูกทำโดยอัตโนมัติใน Java อย่างไรก็ตาม หากมีการประกาศตัวแปร ฟิลด์คลาส หรือค่าส่งคืนเมธอดเป็นซูเปอร์คลาส ฟิลด์และวิธีการของคลาสย่อยจะมองไม่เห็น อ้างถึงซูเปอร์คลาสที่เรียกว่าคลาสย่อย'downcasting'คุณต้องลงทะเบียนมันด้วยตัวเอง (นั่นคือ นำอ็อบเจ็กต์ไปยังคลาสย่อยที่ต้องการ) นักเรียนมักจะลืมเกี่ยวกับคลาสย่อยของวัตถุ สิ่งนี้มักเกิดขึ้นเมื่อใช้อาร์เรย์ของออบเจ็กต์และคอลเลกชันจากแพ็คเกจjava.util(หมายถึงCollection Framework ) ตัวอย่างด้านล่างStringใส่วัตถุลงในอาร์เรย์แล้วลบออกจากอาร์เรย์เพื่อเปรียบเทียบกับสตริงอื่น คอมไพเลอร์จะตรวจพบข้อผิดพลาดและจะไม่คอมไพล์โค้ดจนกว่าจะระบุประเภทการส่งอย่างชัดเจน ตัวอย่างที่ไม่ถูกต้อง
Object arr[] = new Object[10];
arr[0] = "m";
arr[1] = new Character('m');

String arg = args[0];
if (arr[0].compareTo(arg) < 0) {
    System.out.println(arg + " comes before " + arr[0]);
}
ความหมายของการหล่อแบบเป็นเรื่องยากสำหรับบางคน วิธีการแบบไดนามิกมักจะทำให้เกิดปัญหาโดยเฉพาะ ในตัวอย่างด้านบน หากใช้วิธีการนี้equalsแทนcompareToคอมไพเลอร์จะไม่เกิดข้อผิดพลาด และโค้ดจะทำงานได้อย่างถูกต้อง เนื่องจากเมธอดequalsของคลาส จะถูกเรียก Stringคุณต้องเข้าใจว่าการเชื่อมโยงแบบไดนามิกนั้นแตกต่างจากdowncasting. ตัวอย่างที่แก้ไข:
Object arr[] = new Object[10];
arr[0] = "m";
arr[1] = new Character('m');

String arg = args[0];
if ( ((String) arr[0]).compareTo(arg) < 0) {
    System.out.println(arg + " comes before " + arr[0]);
}

13. การใช้อินเทอร์เฟซ

สำหรับนักเรียนหลายๆ คน ความแตกต่างระหว่างชั้นเรียนและอินเทอร์เฟซยังไม่ชัดเจนนัก ดังนั้น นักเรียนบางคนจึงพยายามใช้อิน เทอร์เฟซ เช่นObserverหรือRunnableใช้ คีย์เวิร์ด ขยายแทนการใช้ เพื่อแก้ไขข้อผิดพลาด คุณเพียงแค่ต้องแก้ไขคำหลักให้ถูกต้อง ตัวอย่างที่ไม่ถูกต้อง:
public class SharkSim extends Runnable {
    float length;
    ...
}
ตัวอย่างที่แก้ไข:
public class SharkSim implements Runnable {
    float length;
    ...
}
ข้อผิดพลาดที่เกี่ยวข้อง: ลำดับการขยายและการดำเนิน การบล็อกไม่ถูก ต้อง ตามข้อกำหนดของ Java การประกาศส่วนขยายคลาสจะต้องมาก่อนการประกาศการใช้งานอินเทอร์เฟซ นอกจากนี้ สำหรับอินเทอร์เฟ ซ คีย์เวิร์ดImplementsจะต้องเขียนเพียงครั้งเดียว โดยอินเทอร์เฟซหลายรายการจะถูกคั่นด้วยเครื่องหมายจุลภาค ตัวอย่างที่ผิดพลาดเพิ่มเติม:
// Неправильный порядок
public class SharkSim implements Swimmer extends Animal {
    float length;
    ...
}

// ключевое слово implements встречается несколько раз
public class DiverSim implements Swimmer implements Runnable {
    int airLeft;
    ...
}
ตัวอย่างที่แก้ไข:
// Правильный порядок
public class SharkSim extends Animal implements Swimmer {
    float length;
    ...
}

// Несколько интерфейсов разделяются запятыми
public class DiverSim implements Swimmer, Runnable {
    int airLeft;
    ...
}

14. ลืมใช้ค่าส่งคืนของเมธอดซูเปอร์คลาส

Java อนุญาตให้คุณเรียกใช้เมธอดซูเปอร์คลาสที่คล้ายกันจากคลาสย่อยโดยใช้คีย์เวิร์ดคีย์เวิร์ด บางครั้งนักเรียนต้องเรียกใช้เมธอด superclass แต่มักจะลืมใช้ค่าที่ส่งคืน สิ่งนี้เกิดขึ้นบ่อยครั้งโดยเฉพาะในหมู่นักเรียนที่ยังไม่เข้าใจวิธีการและค่าที่ส่งคืน ในตัวอย่างด้านล่าง นักเรียนต้องการแทรกผลลัพธ์ของtoString()วิธีซูเปอร์คลาสลงในผลลัพธ์ของtoString()วิธีคลาสย่อย อย่างไรก็ตาม จะไม่ใช้ค่าส่งคืนของเมธอดซูเปอร์คลาส ตัวอย่างที่ไม่ถูกต้อง:
public class GraphicalRectangle extends Rectangle {
      Color fillColor;
      boolean beveled;
      ...
      public String toString() {
          super();
          return("color=" + fillColor + ", beveled=" + beveled);
      }
}
เพื่อแก้ไขข้อผิดพลาด โดยปกติแล้วการกำหนดค่าที่ส่งคืนให้กับตัวแปรภายในเครื่องก็เพียงพอแล้ว จากนั้นจึงใช้ตัวแปรนั้นเมื่อคำนวณผลลัพธ์ของเมธอดคลาสย่อย ตัวอย่างที่แก้ไข:
public class GraphicalRectangle extends Rectangle {
      Color fillColor;
      boolean beveled;
      ...
      public String toString() {
          String rectStr = super();
          return(rectStr + " - " +
         "color=" + fillColor + ", beveled=" + beveled);
      }
}

15. ลืมเพิ่มส่วนประกอบ AWT

AWT ใช้โมเดลการออกแบบ GUI แบบง่ายๆ: ส่วนประกอบอินเทอร์เฟซแต่ละส่วนต้องถูกสร้างขึ้นก่อนโดยใช้ตัวสร้างของตัวเอง จากนั้นจึงวางลงในหน้าต่างแอปพลิเคชันโดยใช้วิธีadd()ส่วนประกอบหลัก ดังนั้นอินเทอร์เฟซบน AWT จึงได้รับโครงสร้างแบบลำดับชั้น บางครั้งนักเรียนก็ลืม 2 ขั้นตอนนี้ไป พวกเขาสร้างส่วนประกอบแต่ลืมวางไว้ในหน้าต่างขยาย สิ่งนี้จะไม่ทำให้เกิดข้อผิดพลาดในขั้นตอนการคอมไพล์ ส่วนประกอบจะไม่ปรากฏในหน้าต่างแอปพลิเคชัน ตัวอย่างที่ไม่ถูกต้อง
public class TestFrame extends Frame implements ActionListener {
    public Button exit;

    public TestFrame() {
        super("Test Frame");
        exit = new Button("Quit");
    }
}
เพื่อแก้ไขข้อผิดพลาดนี้ คุณเพียงแค่ต้องเพิ่มคอมโพเนนต์ให้กับพาเรนต์ ตัวอย่างด้านล่างแสดงวิธีการทำเช่นนี้ ควรสังเกตว่าบ่อยครั้งที่นักเรียนที่ลืมเพิ่มส่วนประกอบลงในหน้าต่างแอปพลิเคชันก็ลืมกำหนดผู้ฟังเหตุการณ์ให้กับส่วนประกอบนั้นด้วย ตัวอย่างที่แก้ไข:
public class TestFrame extends Frame implements ActionListener {
    public Button exit;

    public TestFrame() {
        super("Test Frame");

        exit = new Button("Quit");

        Panel controlPanel = new Panel();
        controlPanel.add(exit);

        add("Center", controlPanel);

        exit.addActionListener(this);
    }

    public void actionPerformed(ActionEvent e) {
        System.exit(0);
    }
}

17. ลืมเริ่มสตรีม

มัลติเธรดใน Java ถูกนำมาใช้โดยใช้นามสกุลjava.lang.Thread. วงจรชีวิตของเธรดประกอบด้วย 4 ขั้นตอน: เริ่มต้น เริ่มต้น บล็อก และหยุด เธรดที่สร้างขึ้นใหม่อยู่ในสถานะเตรียมใช้งาน หากต้องการทำให้มันอยู่ในสถานะกำลังทำงาน คุณต้องเรียกมันว่าstart(). บางครั้งนักเรียนตั้งกระทู้แต่ลืมเริ่มกระทู้ โดยปกติแล้วข้อผิดพลาดจะเกิดขึ้นเมื่อนักเรียนมีความรู้ไม่เพียงพอเกี่ยวกับการเขียนโปรแกรมแบบขนานและมัลติเธรด (แปลโดยประมาณ: ฉันไม่เห็นการเชื่อมต่อ) หากต้องการแก้ไขข้อผิดพลาด คุณเพียงแค่ต้องเริ่มเธรด ในตัวอย่างด้านล่าง นักเรียนต้องการสร้างภาพเคลื่อนไหวของรูปภาพโดยใช้อินเทอร์เฟซRunnableแต่เขาลืมเริ่มหัวข้อ ตัวอย่างที่ไม่ถูกต้อง
public class AnimCanvas extends Canvas implements Runnable {
        protected Thread myThread;
        public AnimCanvas() {
                myThread = new Thread(this);
        }

        // метод run() не будет вызван,
        // потому что поток не запущен.
        public void run() {
                for(int n = 0; n < 10000; n++) {
                   try {
                     Thread.sleep(100);
                   } catch (InterruptedException e) { }

                   animateStep(n);
                }
        }
        ...
}
ตัวอย่างที่แก้ไข:
public class AnimCanvas extends Canvas implements Runnable {
        static final int LIMIT = 10000;
        protected Thread myThread;

        public AnimCanvas() {
                myThread = new Thread(this);
                myThread.start();
        }

        public void run() {
                for(int n = 0; n < LIMIT; n++) {
                        try {
                          Thread.sleep(100);
                        } catch (InterruptedException e) { }

                        animateStep(n);
                }
        }
        ...
}
วงจรชีวิตของเธรดและความสัมพันธ์ระหว่างเธรดและคลาสที่ใช้อินเทอร์เฟซRunnableเป็นส่วนที่สำคัญมากของการเขียนโปรแกรม Java และจะเป็นประโยชน์หากมุ่งเน้นไปที่สิ่งนี้

18. การใช้เมธอดreadLine() ที่ต้องห้ามของ คลาสjava.io.DataInputStream

readLine()ใน Java เวอร์ชัน 1.0 คุณต้องใช้วิธี การเรียนjava.io.DataInputStreamเพื่ออ่านสตริงข้อความ Java เวอร์ชัน 1.1 ได้เพิ่มคลาส I/O ทั้งชุดเพื่อให้การดำเนินการ I/O สำหรับข้อความ: the ReaderและWriter. ดังนั้นตั้งแต่เวอร์ชัน 1.1 ถึง อ่านบรรทัดข้อความ คุณต้องใช้ เมธอด readLine()class java.io.BufferedReaderนักเรียนอาจไม่ตระหนักถึงการเปลี่ยนแปลงนี้ โดยเฉพาะอย่างยิ่งหากพวกเขาสอนจากหนังสือเก่าๆ (คำแปลโดยประมาณ: จริงๆ แล้วไม่มีความเกี่ยวข้องอีกต่อไป ไม่น่าจะมีใครเรียนจากหนังสือที่มีอายุ 10 ขวบแล้ว) วิธีการแบบเก่าreadLine()ยังคงอยู่ใน JDK แต่ได้รับการประกาศว่าผิดกฎหมาย ซึ่งมักทำให้นักเรียนสับสน สิ่งที่คุณต้องเข้าใจก็คือการใช้readLine()class method java.io.DataInputStreamไม่ใช่เรื่องผิด แต่แค่ล้าสมัย BufferedReaderคุณต้อง ใช้ คลาส ตัวอย่างที่ไม่ถูกต้อง:
public class LineReader {
    private DataInputStream dis;

    public LineReader(InputStream is) {
        dis = new DataInputStream(is);
    }

    public String getLine() {
        String ret = null;

        try {
          ret = dis.readLine();  // Неправильно! Запрещено.
        } catch (IOException ie) { }

        return ret;
    }
}
ตัวอย่างที่แก้ไข:
public class LineReader {
    private BufferedReader br;

    public LineReader(InputStream is) {
        br = new BufferedReader(new InputStreamReader(is));
    }

    public String getLine() {
        String ret = null;

        try {
          ret = br.readLine();
        } catch (IOException ie) { }

        return ret;
    }
}
มีวิธีการที่ต้องห้ามอื่นๆ ในเวอร์ชันที่ใหม่กว่า 1.0 แต่วิธีนี้เป็นวิธีที่พบได้บ่อยที่สุด

19. ใช้ double เป็น float

เช่นเดียวกับภาษาอื่นๆ ส่วนใหญ่ Java รองรับการดำเนินการกับตัวเลขทศนิยม (ตัวเลขเศษส่วน) Java มีสองประเภทดั้งเดิมสำหรับตัวเลขทศนิยม: doubleความแม่นยำ IEEE 64 บิต และfloatความแม่นยำ IEEE 32 บิต ความยากคือเมื่อใช้ตัวเลขทศนิยมเช่น 1.75, 12.9e17 หรือ -0.00003 - คอมไพเลอร์กำหนดให้doubleพิมพ์ Java ไม่ดำเนินการพิมพ์ประเภทในการดำเนินการที่อาจสูญเสียความแม่นยำ การหล่อประเภทนี้จะต้องทำโดยโปรแกรมเมอร์ ตัวอย่างเช่น Java จะไม่อนุญาตให้คุณกำหนดค่าประเภทให้กับintตัวแปร ประเภท byteโดยไม่ต้องแปลงประเภท ดังที่แสดงในตัวอย่างด้านล่าง
byte byteValue1 = 17; /* неправильно! */
byte byteValue2 = (byte)19; /* правильно */
เนื่องจากตัวเลขเศษส่วนจะแสดงตามประเภทdoubleและการกำหนดให้doubleกับตัวแปรประเภทfloatอาจทำให้สูญเสียความแม่นยำ คอมไพเลอร์จะบ่นเกี่ยวกับความพยายามใดๆ ในการใช้ตัวเลขเศษส่วนfloatเป็น ดังนั้นการใช้การบ้านด้านล่างจะป้องกันไม่ให้ชั้นเรียนรวบรวม
float realValue1 = -1.7;          /* неправильно! */
float realValue2 = (float)(-1.9); /* правильно */
งานนี้จะทำงานได้ในภาษา C หรือ C++ แต่ใน Java จะเข้มงวดกว่ามาก มี 3 วิธีในการกำจัดข้อผิดพลาดนี้ คุณสามารถใช้ type doubleแทนfloat. นี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุด ในความเป็นจริง มีประโยชน์เพียงเล็กน้อยในการใช้เลขคณิตแบบ 32 บิตแทนที่จะเป็น 64 บิต JVM ยังคงกินความแตกต่างของความเร็ว (นอกจากนี้ในโปรเซสเซอร์สมัยใหม่ ตัวเลขเศษส่วนทั้งหมดจะถูกแปลงเป็นรูปแบบของโปรเซสเซอร์ 80 บิต ลงทะเบียนก่อนดำเนินการใดๆ) ข้อดีเพียงอย่างเดียวของการใช้งานfloatคือใช้หน่วยความจำน้อยลง ซึ่งมีประโยชน์เมื่อทำงานกับตัวแปรเศษส่วนจำนวนมาก คุณสามารถใช้ตัวแก้ไขประเภทตัวเลขเพื่อบอกคอมไพเลอร์ถึงวิธีการจัดเก็บหมายเลข ตัวแก้ไขสำหรับfloat - 'f'ประเภท ดังนั้นคอมไพลเลอร์จะ กำหนดประเภท 1.75 ให้กับdoubleและ 1.75f - floatตัวอย่างเช่น:
float realValue1 = 1.7;    /* неправильно! */
float realValue2 = 1.9f;   /* правильно */
คุณสามารถใช้การหล่อประเภทที่ชัดเจนได้ นี่เป็นวิธีที่หรูหราน้อยที่สุด แต่จะมีประโยชน์เมื่อแปลงตัวแปร type doubleเป็น type floatตัวอย่าง:
float realValue1 = 1.7f;
double realValue2 = 1.9;
realValue1 = (float)realValue2;
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับตัวเลขทศนิยมได้ ที่นี่ และ ที่นี่

--ความเห็นนักแปล--
ก็แค่นั้นแหละ..
ในตัวอย่างที่ 10 เกิดข้อผิดพลาด 9 จริงๆ ฉันสังเกตเห็นทันทีแต่ลืมเขียนบันทึก แต่ไม่ได้แก้ไขให้ถูกต้องเพื่อไม่ให้เกิดความคลาดเคลื่อนกับต้นฉบับ

ผู้แต่ง: A.Grasoff™ ลิงก์ไปยังแหล่งที่มา: ข้อผิดพลาดของโปรแกรมเมอร์ Java มือใหม่
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION