ข้อผิดพลาดรันไทม์ของ Java ที่พบบ่อยที่สุด

Feb 27 2023
ข้อผิดพลาดรันไทม์เกิดขึ้นเมื่อโปรแกรมไม่มีข้อผิดพลาดทางไวยากรณ์ แต่ขอให้คอมพิวเตอร์ทำบางสิ่งที่คอมพิวเตอร์ไม่สามารถทำได้ ระหว่างการคอมไพล์ คอมไพเลอร์ไม่มีเทคนิคในการตรวจหาข้อผิดพลาดประเภทนี้

ข้อผิดพลาดรันไทม์เกิดขึ้นเมื่อโปรแกรมไม่มีข้อผิดพลาดทางไวยากรณ์ แต่ขอให้คอมพิวเตอร์ทำบางสิ่งที่คอมพิวเตอร์ไม่สามารถทำได้ ระหว่างการคอมไพล์ คอมไพเลอร์ไม่มีเทคนิคในการตรวจหาข้อผิดพลาดประเภทนี้ เป็น JVM (Java Virtual Machine) ที่ตรวจพบในขณะที่โปรแกรมกำลังทำงาน

· ข้อยกเว้น StackOverflowError
· ข้อยกเว้น OutOfMemoryError
· NegativeArraySizeException
· ArithmeticException
· ArrayIndexOutOfBoundsException
· ArrayStoreException
· UnsupportedOperationException
· NoSuchElementException
· ClassCastException
· DateTimeException
· ConcurrentModificationException
· InputMismatchException
· IllegalFormatConversionException
· NumberFormatException
· InvalidPara meterException
· NullPointerException

ข้อยกเว้น StackOverflowError

StackOverflowErrorเป็นข้อผิดพลาดที่ Java ไม่อนุญาตให้ตรวจจับ เช่น สแต็กไม่มีพื้นที่ว่าง เนื่องจากเป็นข้อผิดพลาดรันไทม์ที่พบได้ บ่อยที่สุด

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

// Java program to demonstrate
// infinite recursion error
public class StackOverflowErrorClass {
 static int i = 0;
 // Method to print numbers
 public static int printNumber(int x)
 {
  i = i + 2;
  System.out.println(i);
  return i + printNumber(i + 2);
 }
 public static void main(String[] args)
 {
  // Recursive call without any
  // terminating condition
  StackOverflowErrorClass.printNumber(i);
 }
}

RunTime Error in java code :- Exception in thread “main” java.lang.StackOverflowError
at java.io.PrintStream.write(PrintStream.java:526)
at java.io.PrintStream.print(PrintStream.java:597)
at java.io.PrintStream.println(PrintStream.java:736)
at StackOverflowErrorClass.printNumber(StackOverflowErrorClass.java:13)
at StackOverflowErrorClass.printNumber(StackOverflowErrorClass.java:14)
at StackOverflowErrorClass.printNumber(StackOverflowErrorClass.java:14)
.
.
.

ข้อยกเว้น OutOfMemoryError

ข้อผิดพลาดพื้นที่/หน่วยความจำไม่เพียงพอ (java.lang.OutOfMemoryError) ในเธรด

java.lang.OutOfMemoryError เป็นข้อผิดพลาดรันไทม์ใน Java ซึ่งเกิดขึ้นเมื่อ Java Virtual Machine ( JVM ) ไม่สามารถจัดสรรวัตถุได้เนื่องจากพื้นที่ไม่เพียงพอใน Java heap Java Garbage Collector ( GC ) ไม่สามารถเพิ่มพื้นที่ว่างที่จำเป็นสำหรับออบเจกต์ใหม่ ซึ่งทำให้เกิดjava.lang.OutOfMemoryError ข้อผิดพลาดนี้อาจเกิดขึ้นได้เมื่อหน่วยความจำภายในไม่เพียงพอที่จะรองรับการโหลดคลาส Java

นี่คือตัวอย่างของการโยนเนื่องจากพื้นที่ฮีป Java ไม่เพียงพอ:

public class OutOfMemoryErrorExample {
    public static void main(String[] args) {
        Integer[] myArray = new Integer[1000 * 1000 * 1000];
    }
}

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at OutOfMemoryErrorExample.main(OutOfMemoryErrorExample.java:8)

NegativeArraySizeException

NegativeArraySizeException เป็นข้อยกเว้นรันไทม์ใน Java ที่เกิดขึ้นเมื่อแอปพลิเคชันพยายามสร้างอาร์เรย์ที่มีขนาดเป็นค่าลบ เนื่องจาก NegativeArraySizeException เป็นข้อยกเว้นที่ไม่ได้ตรวจสอบ (ขยายRuntimeException ) จึงไม่จำเป็นต้องประกาศในส่วนคำสั่งการโยนของเมธอดหรือตัวสร้าง

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

class JavaError {
public static void main(String[] args) {
    int[] arr = new int[-5]; // Negative size of the array
    arr[8] = 89;
    System.out.println("Something went wrong!");
  }
}

java -cp /tmp/UDRgGsLLQ6 JavaError
Exception in thread "main" java.lang.NegativeArraySizeException: -5
at JavaError.main(JavaError.java:4)

ข้อยกเว้นเลขคณิต

อดีต. หารด้วยศูนย์ข้อผิดพลาด

การจัดการข้อมูลเป็นฟังก์ชันหลักของแอปพลิเคชัน Java ส่วนใหญ่ เมื่อการจัดการข้อมูลรวมถึงการ หารนักพัฒนาต้องระวังการหารด้วยศูนย์ หากศูนย์กลายเป็นตัวส่วนในการคำนวณ Java จะโยน ArithmeticException ดังนั้นเราจึงไม่สามารถหารอะไรออกจากศูนย์ได้ ดังนั้นเมื่อเราพยายามทำเช่นนั้น เราจะได้รับข้อยกเว้นเลขคณิตที่รันไทม์

class JavaError {
public static void main(String[] args) {
    int a = 23;
    int b = 0;
    System.out.println(a / b);
  }
}

java -cp /tmp/UDRgGsLLQ6 JavaError
Exception in thread "main" java.lang.ArithmeticException: / by zeroat JavaError.main(JavaError.java:7)

ArrayIndexOutOfBoundsException

เมื่อเข้าถึงองค์ประกอบที่ไม่มีอยู่ในอาร์เรย์

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

การเข้าถึงดัชนีอาร์เรย์ที่ไม่มีอยู่ :

class JavaError {
public static void main(String[] args) {
    String[] arr = new String[5];
    arr[6] = "Hi"; // Accessing array index that does not exsist
    System.out.println("Something went wrong!");
  }
}

java -cp /tmp/UDRgGsLLQ6 JavaError
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 6 out of bounds for length 5
at JavaError.main(JavaError.java:6)

Java ใช้การนับตามศูนย์กับองค์ประกอบในอาร์เรย์ ดังนั้นดัชนี 6 ของอาร์เรย์จะอ้างถึงองค์ประกอบที่เจ็ด แม้รหัสต่อไปนี้จะทริกเกอร์ ArrayIndexOutOfBoundsException ใน Java เนื่องจากดัชนี 4 เป็นการอ้างอิงถึงองค์ประกอบที่ห้าของอาร์เรย์:

String[] arr = new String[5];
arr[5] = "Hi"; // Accessing array index that does not exsist

ArrayStoreException

ArrayStoreException แบ่งปันความคล้ายคลึงกันกับ ClassCastException ข้อยกเว้นรันไทม์ของ Java นี้เกิดขึ้นเมื่อวางวัตถุผิดประเภทในอาร์เรย์

ในตัวอย่างด้านล่าง อาร์เรย์ BigInteger จะถูกสร้างขึ้น ตามด้วยการพยายามเพิ่ม Double Double ไม่แบ่งปันความสัมพันธ์กับ BigInteger ดังนั้นสิ่งนี้จึงทริกเกอร์ ArrayStoreException เมื่อรันไทม์

Number[] bigInt = new BigInteger[5];
bigInt[0] = Double.valueOf(12345);

BigInteger[] bigInt = new BigInteger[5];
bigInt[0] = Double.valueOf(12345); // Java compile error

ไม่รองรับ OperationException

โปรแกรมเมอร์ Java มักใช้คลาส Arrays เพื่อแปลงอาร์เรย์ Java เป็นรายการที่ใช้งานง่ายกว่า อย่างไรก็ตาม รายการที่ Java ส่งคืนเป็นแบบอ่านอย่างเดียว นักพัฒนาที่ไม่ทราบข้อเท็จจริงนี้และพยายามเพิ่มองค์ประกอบใหม่จะเรียกใช้ใน UnsupportedOperationException ตัวอย่างนี้แสดงให้เห็นว่าสิ่งนี้เกิดขึ้นได้อย่างไร:

Integer[] data = {1,2,3,5,8,13,21};
List<Integer> list = Arrays.asList(data);
list.add(new Integer(0));

NoSuchElementException

คุณไม่สามารถวนซ้ำผ่านตัววนซ้ำที่ว่างเปล่า รหัสต่อไปนี้ซึ่งพยายามรับองค์ประกอบถัดไปใน HashSet ที่ว่างเปล่า จะโยน NoSuchElementException

Set set = new HashSet();
set.iterator().next(); // Java runtime exception thrown

if (!set.isEmpty()) {
  set.iterator().next();
}

สำหรับข้อผิดพลาดในการแปลงประเภทข้อมูล

Java เป็นภาษาที่มีการพิมพ์สูง มันบังคับใช้ลำดับชั้นของประเภทอย่างเข้มงวด และจะไม่ส่งออบเจกต์หนึ่งไปยังอีกออบเจกต์หนึ่ง เว้นแต่ว่าออบเจกต์เหล่านั้นจะแบ่งปันความสัมพันธ์แบบโพลิมอร์ฟิก ดังนั้นClassCastExceptionจึงเกิดขึ้นเมื่อคุณพยายามส่งวัตถุไปยังคลาสใดคลาสหนึ่งอย่างไม่ถูกต้อง ซึ่งหมายความว่าวัตถุของคุณไม่ใช่อินสแตนซ์หรือคลาสย่อยของคลาสนี้

ในโค้ดต่อไปนี้ ความพยายามที่จะส่งวัตถุ Date ลงใน Timestamp ทำให้เกิด ข้อผิดพลาด ClassCastExceptionที่รันไทม์

Date today = new Date();Timestamp time = (Timestamp)today;

long seconds = System.currentTimeMillis();
Timestamp time = new Timestamp(seconds);
Date today = (Date)time; // this cast works

วันที่เวลาข้อยกเว้น

การจัดการข้อมูลเป็นความพยายามที่ยุ่งยาก โซนเวลา เส้นวันที่ และรูปแบบวันที่ที่ไม่สอดคล้องกันอาจทำให้ Java โยน DateTimeExceptions ต่างๆ ในรันไทม์ได้

ตัวอย่างเช่น คอมไพล์โค้ดต่อไปนี้ แต่ฟิลด์ HourOfDay ของคลาส LocalDate จะทำให้ความพยายามในการจัดรูปแบบวันที่ล้มเหลว

LocalDate now = LocalDate.now();
DateTimeFormatter.RFC_1123_DATE_TIME.format(now);

LocalDate now = LocalDate.now();
DateTimeFormatter.ISO_DATE.format(now);

สำหรับการคำนวณแบบขนานที่ใช้งานไม่ถูกต้อง

เมธอด asList ของคลาส Arrays ไม่ใช่ครั้งเดียวที่การรวบรวมต้องการการรักษาแบบอ่านอย่างเดียว

เมื่อคุณวนซ้ำรายการ คอลเล็กชันพื้นฐานต้องได้รับการแก้ไขและไม่อัปเดต ดังนั้น วิธีการเพิ่มภายในส่วนย่อยของโค้ดต่อไปนี้จะส่ง ConcurrentModificationException

List servers = new ArrayList();
servers.add("Tomcat");
                   
Iterator<String> iterator = servers.iterator();
while (iterator.hasNext()) {
  String server = iterator.next();
  servers.add("Jetty");  // throws a Runtime Exception
}

InputMismatchException

โดย ทั่วไป InputMismatchExceptionเกิดขึ้นเมื่อทำงานกับโปรแกรม Java ที่แจ้งผู้ใช้ให้ป้อนข้อมูลโดยใช้คลาสScanner ข้อยกเว้นนี้มักเกิดขึ้นระหว่างอินพุตของผู้ใช้ เมื่อคุณคาดหวังอินพุตบางประเภท และผู้ใช้ป้อนอินพุตประเภทอื่น กล่าวอีกนัยหนึ่ง ข้อยกเว้นนี้อาจเกิดขึ้นเมื่ออินพุตไม่ถูกต้องสำหรับประเภทที่คาดไว้ อินพุตไม่ตรงกับรูปแบบสำหรับประเภทที่คาดไว้ หรืออยู่นอกช่วง

เช่นเดียวกับการส่งข้อมูลที่ไม่ถูกต้อง เช่น การส่งค่าตัวเลขไปยังฟิลด์ที่ไม่ใช่ตัวเลข ตัวอย่างเช่น หากโปรแกรมต้องการ ค่า Integerสำหรับอินพุต แต่ผู้ใช้ป้อน ค่า StringแทนInputMismatchExceptionจะถูกโยนทิ้ง

วิธีแก้ไข : ล้อมรหัสที่ขอให้ผู้ใช้ป้อนข้อมูลในลูป while ซึ่งจะแจ้งให้ผู้ใช้ป้อนข้อมูลที่ถูกต้องอย่างต่อเนื่อง

ข้อยกเว้นการแปลงรูปแบบที่ผิดกฎหมาย

คำอธิบาย : สิ่งนี้เกี่ยวข้องกับprintf()และString.format( ) หมายความว่ามีตัวยึดตำแหน่งที่ไม่เกี่ยวข้อง (ตัวยึดมากเกินไป ไม่มีอาร์กิวเมนต์เพียงพอ) หรือเป็นตัวยึดตำแหน่งที่ไม่ถูกต้องสำหรับประเภทในอาร์กิวเมนต์ ตัวอย่างเช่น%sที่เป็นตัวยึดตำแหน่งสำหรับจำนวนเต็มจะทำให้เกิดข้อผิดพลาดนี้

วิธีแก้ไข : ตรวจสอบให้แน่ใจว่าจำนวนตัวยึดตรงกับจำนวนอาร์กิวเมนต์ และตรวจสอบว่าตัวยึดเป็นประเภทที่ถูกต้อง

NumberFormatException

พยายามแปลงสตริงที่ไม่ถูกต้องเป็นตัวเลข

NumberFormatException เกิดขึ้นเมื่อมีความพยายามที่จะแปลงสตริงที่มีรูปแบบไม่เหมาะสมเป็นค่าตัวเลข ซึ่งหมายความว่า เมื่อไม่สามารถแปลงสตริงในรูปแบบตัวเลขใดๆ ได้ (float, int ฯลฯ) ข้อยกเว้นนี้จะหายไป เป็นข้อยกเว้นรันไทม์ (ข้อยกเว้นที่ไม่ได้ตรวจสอบ) ใน Java เป็นคลาสย่อยของคลาสIllegalArgumentException

InvalidParameterException

ส่งผ่านพารามิเตอร์/อาร์กิวเมนต์ที่ไม่ถูกต้องไปยังเมธอด

ข้อยกเว้นนี้เป็นคลาสย่อยของIllegalArgumentExceptionที่ออกแบบมาสำหรับใช้โดยคลาสเอ็นจิน JCA/JCE ซึ่งจะถูกส่งออกเมื่อพารามิเตอร์ที่ไม่ถูกต้องถูกส่งไปยังเมธอด

NullPointerException

NullPointerException เป็น RuntimeException ทั่วไปที่แอปพลิเคชัน Java พบ ข้อยกเว้นนี้เกิดขึ้นเมื่อ Java พบการอ้างอิงที่เป็นโมฆะเมื่อไม่ได้คาดหวังไว้ และผู้พัฒนาจาวาเขียนโค้ดที่เรียกใช้เมธอดในการอ้างอิงนี้ (วัตถุที่ไม่ได้เตรียมใช้งาน)

String data = null;
System.out.println( data.length() ); // throws NullPointerException

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

สนับสนุนสิ่งพิมพ์ของเราโดยติดตาม

พิจารณาข้อผิดพลาดรันไทม์ของ Java การเพิ่มศักยภาพของทีมของคุณให้สูงสุด: วิธีทำให้ทีมจัดส่งซอฟต์แวร์ของคุณไม่ว่าง คำถามสัมภาษณ์ที่ใช้ Java8 Stream ถามบ่อยที่สุด — ส่วนสุดท้าย วิธีสร้างโครงการ Quarkus อย่างง่ายด้วยการรวมฐานข้อมูล ข้อยกเว้นผูกมัดใน Java คืออะไร | การจัดการข้อยกเว้น ฉันได้รับ $300 จากการเขียนหนังสือใน 2 วัน — นี่คือวิธีที่ ง่ายแต่ได้ผล 10 วิธีในการปรับปรุงคุณภาพชีวิตของคุณ เริ่มต้นใช้งาน Spring Boot: บทช่วยสอนที่ครอบคลุมสำหรับผู้เริ่มต้น