ตามที่กล่าวไว้ก่อนที่จะดำเนินการแก้ปัญหาการโอเวอร์โหลดในเวลาคอมไพล์
Java Puzzlersมีตัวอย่างที่ดีสำหรับสิ่งนั้น:
ปริศนา 46: กรณีของตัวสร้างที่สับสน
ปริศนานี้นำเสนอผู้สร้างที่สับสนสองคน วิธีการหลักเรียกใช้ตัวสร้าง แต่วิธีใด? ผลลัพธ์ของโปรแกรมขึ้นอยู่กับคำตอบ โปรแกรมพิมพ์อะไรหรือแม้กระทั่งถูกกฎหมาย?
public class Confusing {
private Confusing(Object o) {
System.out.println("Object");
}
private Confusing(double[] dArray) {
System.out.println("double array");
}
public static void main(String[] args) {
new Confusing(null);
}
}
โซลูชันที่ 46: กรณีของตัวสร้างที่สับสน
... กระบวนการแก้ปัญหาโอเวอร์โหลดของ Java ทำงานในสองขั้นตอน ระยะแรกจะเลือกวิธีการหรือตัวสร้างทั้งหมดที่สามารถเข้าถึงและใช้ได้ ระยะที่สองจะเลือกวิธีการหรือตัวสร้างที่เฉพาะเจาะจงที่สุดที่เลือกไว้ในระยะแรก วิธีการหรือตัวสร้างหนึ่งมีความเฉพาะเจาะจงน้อยกว่าอีกวิธีหนึ่งหากสามารถยอมรับพารามิเตอร์ใด ๆ ที่ส่งผ่านไปยังอีกวิธีหนึ่ง [JLS 15.12.2.5]
ในโปรแกรมของเราผู้สร้างทั้งสองสามารถเข้าถึงและใช้งานได้ ตัวสร้าง
Confusing (Object)ยอมรับพารามิเตอร์ใด ๆ ที่ส่งผ่านไปยังConfusing (double [])ดังนั้น
Confusing (Object)จึงมีความเฉพาะเจาะจงน้อยกว่า ( อาร์เรย์คู่ทุกตัวเป็นObjectแต่ไม่ใช่ทุกObject ที่เป็นอาร์เรย์คู่ ) ตัวสร้างที่เฉพาะเจาะจงที่สุดจึงสับสน (double [])ซึ่งจะอธิบายผลลัพธ์ของโปรแกรม
พฤติกรรมนี้เหมาะสมถ้าคุณส่งค่าประเภทdouble [] ; มันเป็น counterintuitive ถ้าคุณผ่านnull กุญแจสำคัญในการทำความเข้าใจปริศนานี้คือการทดสอบวิธีการหรือตัวสร้างที่เฉพาะเจาะจงที่สุดไม่ใช้พารามิเตอร์จริง : พารามิเตอร์ที่ปรากฏในการเรียกใช้ ใช้เพื่อพิจารณาว่าการบรรทุกเกินพิกัดใดที่ใช้ได้เท่านั้น เมื่อคอมไพลเลอร์พิจารณาว่าการโอเวอร์โหลดใดที่สามารถใช้ได้และสามารถเข้าถึงได้มันจะเลือกการโอเวอร์โหลดที่เฉพาะเจาะจงที่สุดโดยใช้เฉพาะพารามิเตอร์ที่เป็นทางการเท่านั้น: พารามิเตอร์ที่ปรากฏในการประกาศ
หากต้องการเรียกใช้คอนสตรัคเตอร์Confusing (Object)ด้วยพารามิเตอร์nullให้เขียนConfusing ((Object) null)ใหม่ เพื่อให้แน่ใจว่าConfusing (Object)เท่านั้นที่ใช้ได้ โดยทั่วไปในการบังคับให้คอมไพเลอร์เลือกการโอเวอร์โหลดเฉพาะให้ส่งพารามิเตอร์จริงไปยังประเภทพารามิเตอร์ทางการที่ประกาศไว้