Exception in thread "main" java.lang.ClassCastException

| ไอที | Java | 1950

Exception in thread "main" java.lang.ClassCastException

บทความนี้เรามาทำความรู้จักกับ Exception ที่ชื่อว่า ClassCastException กัน ซึ่ง Exception ที่เกิดขึ้นจะแสดงข้อความประมาณด้านล่าง
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.math.BigDecimal
	at com.doesystem.CodeFromDoesystem.addOne(CodeFromDoesystem.java:13)
	at com.doesystem.CodeFromDoesystem.main(CodeFromDoesystem.java:8)

จากข้อความ Exception ข้างบนเราสามารถแปลข้อความบางส่วนได้ ดังนี้
Exception เกิด Exception
thread "main" ก็คือ thread ที่ชื่อว่า main
ClassCastException เกิด Exception ที่ชื่อว่า ClassCastException
java.lang.String ก็คือ Class ที่ชื่อว่า String อยู่ใน package java.lang
cannot be cast to ไม่สามารถแปลงเป็น/โยนเป็น
java.math.BigDecimal ก็คือ Class ที่ชื่อว่า BigDecimal อยู่ใน package java.math

เมื่อเรานำข้อความที่แจ้งเตือน Exception มารวม ๆ กัน ก็อาจจะคาดเดาได้ว่า เกิด Exception ใน thread ที่ชื่อว่า main เป็น Exception ชนิด ClassCastException ซึ่งก็คือการ cast ของ Class ผิด ซึ่งเป็นการ cast String ไปเป็น BigDecimal

ดังนั้นลองมาดูโค้ดที่ทำให้เกิด Exception กัน
package com.doesystem;

import java.math.BigDecimal;

public class CodeFromDoesystem {
	public static void main(String[] args) throws Exception {
		String objStr = "123";
		BigDecimal result = addOne(objStr);
		System.out.println(result);
	}
	
	public static BigDecimal addOne(Object obj){
		BigDecimal a = (BigDecimal)obj;
		return a.add(BigDecimal.ONE);
	}
}

จากข้อความแจ้งเตือน Exception
com.doesystem.CodeFromDoesystem.main(CodeFromDoesystem.java:8) ให้ดูบรรทัดที่ 8 มี method main บรรทัดที่ 8 จะเห็นว่ามีการเรียก method ที่ชื่อว่า addOne
com.doesystem.CodeFromDoesystem.addOne(CodeFromDoesystem.java:13) จากบรรทัดที่ 8 มีการเรียก method addOne ส่วนนี้อยู่ใน method addOne ให้ไปดูที่บรรทัดที่ 13 BigDecimal a = (BigDecimal)obj; จะเห็นว่ามีการ cast Object ให้เป็น BigDecimal ซึ่งตอน Compile นั้นจะไม่เกิด Exception แต่เวลารันโปรแกรมจะเกิด Exception เพราะตอนรันเราได้ส่ง String เข้าไป แต่ข้างใน method มีการแปลง Object ให้เป็น BigDecimal

ตัวอย่างวิธีการแก้ไข

ตัวอย่างการแก้ไขให้ถูกต้อง ตัวอย่างนี้เป็นการเปลี่ยนจากที่จะส่ง String เข้าไป เราก็ส่งเป็น BigDecimal เข้าไปแทน
package com.doesystem;

import java.math.BigDecimal;

public class CodeFromDoesystem {
	public static void main(String[] args) throws Exception {
		BigDecimal objStr = new BigDecimal("123");
		BigDecimal result = addOne(objStr);
		System.out.println(result);
	}
	
	public static BigDecimal addOne(Object obj){
		BigDecimal a = (BigDecimal)obj;
		return a.add(BigDecimal.ONE);
	}
}
จากตัวอย่างข้างบนก็ถือว่าใช้ได้ แต่ว่าเราสามาถเป็น method ที่ทำการรับเป็น Object ทำไมเราไม่เปลี่ยนให้มันรับเป็น BigDecimal ละ อย่างเช่นตัวอย่าง
package com.doesystem;

import java.math.BigDecimal;

public class CodeFromDoesystem {
	public static void main(String[] args) throws Exception {
		BigDecimal objStr = new BigDecimal("123");
		BigDecimal result = addOne(objStr);
		System.out.println(result);
	}
	
	public static BigDecimal addOne(BigDecimal obj){
		return obj.add(BigDecimal.ONE);
	}
}

แต่ถ้าเราอยากรับพารามิเตอร์ที่เป็น String ละ ก็ทำได้ดังตัวอย่างด้านล่าง
package com.doesystem;

import java.math.BigDecimal;

public class CodeFromDoesystem {
	public static void main(String[] args) throws Exception {
		String objStr = "123";
		BigDecimal result = addOne(objStr);
		System.out.println(result);
	}
	
	public static BigDecimal addOne(String val){
		BigDecimal a = (new BigDecimal(val));
		return a.add(BigDecimal.ONE);
	}
}


comments