"สวัสดี Amigo! เรามาพูดถึงข้อผิดพลาดกันต่อไป ครั้งนี้เราจะสำรวจข้อผิดพลาดที่ตัวแปลไม่สามารถช่วยคุณได้เสมอไป ให้ความสนใจและคุณจะได้เรียนรู้บางอย่างเกี่ยวกับตัวคุณเอง"
"ฉันพร้อมที่จะฟัง ดิเอโก ฉันหวังว่าเรื่องนี้จะไม่น่าอายเกินไปสำหรับฉัน"
การเปรียบเทียบวัตถุกับ==
"รายการข้อผิดพลาดของโปรแกรมเมอร์มือใหม่ยอดนิยมของเราเริ่มต้นด้วยการเปรียบเทียบวัตถุ (โดยเฉพาะสตริง) โดยใช้==
ตัวดำเนินการ"
ตัวอย่าง:
Scanner console = new Scanner(System.in);
String s1 = console.nextLine();
String s2 = console.nextLine();
if (s1 == s2)
{
System.out.println("The strings are equal");
}
"ฉันทำแบบนั้นค่อนข้างบ่อย ตอนนี้ฉันเห็นได้อย่างชัดเจนว่าโค้ดนี้จะไม่แสดงข้อความว่า "สตริงเท่ากัน" เพราะคำสั่งจะif
เปรียบเทียบการอ้างอิงถึงอ็อบเจกต์สตริงสองตัวที่แตกต่างกัน"
"ใช่ นั่นเป็นเหตุผลที่ตัวเลือกที่ถูกต้องคือ:
Scanner console = new Scanner(System.in);
String s1 = console.nextLine();
String s2 = console.nextLine();
if (s1.equals(s2))
{
System.out.println("The strings are equal");
}
การเปลี่ยนString
วัตถุ
"โปรแกรมเมอร์มือใหม่มักลืมไปว่าออบเจกต์ทั้งหมดของคลาสนั้นเปลี่ยนรูปไม่ได้และทุกเมธอดของString
คลาสจะส่งคืนออบเจกต์ใหม่ - ออบเจ็กต์ปัจจุบันไม่เคยเปลี่ยนแปลง"
"ไม่นานมานี้ที่ฉันได้เรียนรู้ว่าการเปลี่ยนแปลงไม่ได้หมายถึงอะไร แต่ฉันคิดว่าฉันได้ทำสิ่งนี้แล้ว
"ฉันค่อนข้างแน่ใจ ตัวอย่าง:
String s = "Hello";
s.toUpperCase (); // Convert to uppercase
"โค้ดนี้คล้ายกับโค้ดที่ถูกต้องมาก แต่จะใช้งานไม่ได้ตามที่คาดไว้ เมธอดนี้toUpperCase()
จะไม่เปลี่ยนแปลงออบเจกต์ที่เรียกใช้ โค้ดที่ถูกต้องจะมีลักษณะดังนี้:
String s = "Hello";
String result = s.toUpperCase(); // Convert to uppercase
"ถูกต้อง ฉันทำอย่างนั้น แต่ฉันไม่เข้าใจด้วยซ้ำว่ามีอะไรผิดพลาด ขอบคุณที่ชี้แจง!"
ลืมที่จะเริ่มต้นวัตถุที่เป็นองค์ประกอบของอาร์เรย์
"ข้อผิดพลาดทั่วไปอีกประการหนึ่งคือการลืมกำหนดค่าเริ่มต้นให้กับตัวแปรอาร์เรย์ ตัวอย่าง:
int[] array;
array[0] = 1;
array[0] = 2;
"รหัสนี้ใช้ไม่ได้: คุณต้องตั้งค่าตัวแปรอาร์เรย์อย่างชัดเจนให้เท่ากับการอ้างอิงไปยังวัตถุคอนเทนเนอร์ที่จะเก็บองค์ประกอบของอาร์เรย์ เวอร์ชันที่ถูกต้อง:
int[] array = new int[10];
array[0] = 1;
array[0] = 2;
การใช้ตัวแปรโลคัลแทนตัวแปรอินสแตนซ์
"มือใหม่ไม่ชอบตั้งชื่อตัวแปรที่ยาวและมีความหมาย"
"จริงมาก เพื่อให้งานลุล่วงอย่างรวดเร็ว บางครั้งฉันก็ตั้งชื่อตัวแปรเช่นa
, b
, และi
"
"อย่าทำอย่างนั้น นั่นเป็นสิ่งที่โหดร้ายที่ต้องทำเมื่อโค้ดมีหลายตัวแปรเช่นนั้น:
ใส่หมายเลข 99 ลงใน 100 เซลล์ของอาร์เรย์ |
---|
|
"การทำรหัสผิดด้วยชื่อที่ถูกต้องนั้นยากกว่ามาก เวอร์ชันที่ถูกต้องมีลักษณะดังนี้:
ใส่หมายเลข 99 ลงใน 100 เซลล์ของอาร์เรย์ |
---|
|
การลบรายการคอลเลกชัน
"คุณดูคอลเลกชันแล้วหรือยัง"
"แท้จริงด้วยตาเพียงข้างเดียว"
"ถ้าคุณไม่รู้ว่าฉันกำลังพูดถึงอะไร ให้จดบันทึกไว้กับตัวเองเพื่อพิจารณาในอนาคต บ่อยครั้งมีสถานการณ์ที่ต้องลบองค์ประกอบบางอย่างออกจากคอลเล็กชัน รหัสมีลักษณะคร่าวๆ เช่น นี้:
ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 0, -5, -7, -12, 5, 15);
for (Integer value: list)
if (value < 0)
list.remove(value);
"รหัสนี้จะใช้งานไม่ได้ เนื่องจากคุณไม่สามารถใช้for-each
การวนซ้ำเพื่อสำรวจองค์ประกอบของคอลเลกชันและแก้ไขคอลเลกชันนั้นพร้อมกันได้
"มีวิธีแก้ไขหลายวิธี ขั้นแรก คุณสามารถสำรวจคอลเลกชั่นหนึ่งและเปลี่ยนคอลเลกชั่นอื่นได้:
วิธีแก้ปัญหา 1 |
---|
|
"อย่างที่สอง เนื่องจาก Java 8 คอลเล็กชันมีremoveIf()
เมธอดซึ่งคุณสามารถส่งกฎ (ฟังก์ชันแลมบ์ดา) ที่ระบุองค์ประกอบที่จะลบได้ ตัวอย่าง:
โซลูชันที่ 2 |
---|
|
การวางหลายคลาสด้วยpublic
ตัวดัดแปลงเป็นไฟล์เดียว
"สามารถมีคลาสสาธารณะได้เพียงคลาสเดียวในไฟล์ สามารถประกาศคลาสเพิ่มเติมในไฟล์ได้ แต่ต้องเป็นคลาสภายในของคลาสสาธารณะ หรือไม่มีตัวแก้ไขpublic
ตัวอย่าง:
เนื้อหาของไฟล์ Solution.java | บันทึก |
---|---|
|
ไม่อนุญาต: คลาสสาธารณะสองคลาสในไฟล์เดียว |
|
แต่คุณสามารถทำได้ คลาสหลักไม่เปิดเผยต่อสาธารณะ |
|
และคุณสามารถทำได้ คลาสหลักเป็นคลาสที่ซ้อนกัน |
การเรียกเมธอดสามัญ (ไม่คงที่) ของคลาสจากmain()
เมธอด สแตติก
"บางครั้งโปรแกรมเมอร์มือใหม่พยายามเข้าถึงตัวแปรและเมธอดที่ไม่ใช่สแตติกจากmain()
เมธอดหรือเมธอดสแตติกอื่นๆ แน่นอนว่าโค้ดดังกล่าวจะไม่ทำงาน
public class Solution
{
public int n = 100;
public int[] createArray()
{
return new int[n];
}
public static void main(String[]args)
{
int[] array = createArray();
}
}
" main
เมธอดสามารถอ้างถึงเมธอด/ตัวแปรแบบสแตติกเท่านั้น หรือไม่ก็ต้องสร้างอินสแตนซ์ของSolution
คลาสก่อน แล้วจึงเรียกเมธอดแบบไม่คงที่ของอ็อบเจกต์นั้น ตัวอย่าง:
วิธีแก้ปัญหา 1 | โซลูชันที่ 2 |
---|---|
|
|
ประกาศตัวสร้างเช่นวิธีการ
"ข้อผิดพลาดทั่วไปอีกประการหนึ่งคือการประกาศคลาสคอนสตรัคเตอร์อย่างไม่ถูกต้อง ชื่อคอนสตรัคเตอร์ต้องเหมือนกับชื่อของคลาส และคอนสตรัคเตอร์ไม่มีประเภทผลลัพธ์ ข้อผิดพลาดที่พบบ่อยที่สุดมีลักษณะดังนี้:
|
ไม่ควรมีประเภทส่งคืนที่นี่ |
|
ชื่อตัวสร้างไม่ถูกต้อง จะต้องตรงกับชื่อชั้น |
|
this ที่ขาดหายไป. ตัวแปรvalue จะถูกกำหนดให้กับตัวเอง |
|
ถูกต้องทั้งหมด |
การสืบทอดอินเทอร์เฟซไม่ถูกต้อง
"ผู้สร้างของ Java พยายามทำให้ใกล้เคียงกับภาษาอังกฤษมาก ดังนั้นพวกเขาจึงเลือกคำหลักที่แตกต่างกันสำหรับแนวคิดที่เกี่ยวข้องบางอย่าง
เมื่อคลาสสืบทอดคลาส คุณต้องใช้คีย์เวิร์ดextends
:
class Pet
{
}
class Cat extends Pet
{
}
"เมื่อคลาสสืบทอดอินเทอร์เฟซ หรือนำไปใช้จริง คุณต้องใช้คีย์เวิร์ดimplements
:
interface Meow
{
}
class Cat implements Meow
{
}
"เมื่ออินเทอร์เฟซสืบทอดอินเทอร์เฟซ ให้ใช้extends
คำหลัก:
interface Meow
{
}
interface Voice extends Meov
{
}
ละเว้นbreak
ในswitch
คำสั่ง
"และข้อผิดพลาดสุดท้ายสำหรับวันนี้ แต่ไม่ใช่ข้อผิดพลาดสุดท้ายสำหรับผู้เริ่มต้น คือการไม่รวมคำbreak
สั่งในswitch
คำสั่ง ตัวอย่าง:
ผิด | ขวา |
---|---|
|
|
"คุณรู้ไหม ดิเอโก... ตัดสินจากชุดของข้อผิดพลาดที่คุณนำเสนอที่นี่ มันให้ความรู้สึกเหมือนคุณกำลังอ่านบันทึกส่วนตัวของฉัน... หรือคุณกำลังดูฉันแก้ปัญหา"
"ฮ่า! ไม่ต้องสงสัยเลย ฉันได้อ่าน ติดตาม และดำเนินการต่อ ดังนั้น ระวังตัวไว้!"
"???"
“อย่ากังวลไป ฉันล้อเล่น ระวังตัวและทำผิดพลาดโง่ๆ ให้น้อยลง”
GO TO FULL VERSION