"สวัสดี 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 เซลล์ของอาร์เรย์
class Solution
{
  public static int a = 99;
  public static int i = 100;

  public static void main(String[] args)
  {
    int[] a = new int[i];
    for (int i = 0; i < 10; i++)
    {
      a[i] = a;
    }
  }
}

"การทำรหัสผิดด้วยชื่อที่ถูกต้องนั้นยากกว่ามาก เวอร์ชันที่ถูกต้องมีลักษณะดังนี้:

ใส่หมายเลข 99 ลงใน 100 เซลล์ของอาร์เรย์
class Solution
{
   public static int value = 99;
   public static int count = 100;

   public static void main(String[] args)
   {
      int[] a = new int[count];
      for (int i = 0; i < 10; i++)
      {
         a[i] = value;
      }
   }
}

การลบรายการคอลเลกชัน

"คุณดูคอลเลกชันแล้วหรือยัง"

"แท้จริงด้วยตาเพียงข้างเดียว"

"ถ้าคุณไม่รู้ว่าฉันกำลังพูดถึงอะไร ให้จดบันทึกไว้กับตัวเองเพื่อพิจารณาในอนาคต บ่อยครั้งมีสถานการณ์ที่ต้องลบองค์ประกอบบางอย่างออกจากคอลเล็กชัน รหัสมีลักษณะคร่าวๆ เช่น นี้:

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
ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 0, -5, -7, -12, 5, 15);

ArrayList<Integer> copy = new ArrayList<Integer>(list);
for (Integer value: copy)
   if (value < 0)
      list.remove(value);

"อย่างที่สอง เนื่องจาก Java 8 คอลเล็กชันมีremoveIf()เมธอดซึ่งคุณสามารถส่งกฎ (ฟังก์ชันแลมบ์ดา) ที่ระบุองค์ประกอบที่จะลบได้ ตัวอย่าง:

โซลูชันที่ 2
ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 0, -5, -7, -12, 5, 15);

list.removeIf( x-> x<0 );

การวางหลายคลาสด้วยpublicตัวดัดแปลงเป็นไฟล์เดียว

"สามารถมีคลาสสาธารณะได้เพียงคลาสเดียวในไฟล์ สามารถประกาศคลาสเพิ่มเติมในไฟล์ได้ แต่ต้องเป็นคลาสภายในของคลาสสาธารณะ หรือไม่มีตัวแก้ไขpublicตัวอย่าง:

เนื้อหาของไฟล์ Solution.java บันทึก
public class Solution
{
}
public class Main
{
}
ไม่อนุญาต: คลาสสาธารณะสองคลาสในไฟล์เดียว
public class Solution
{
}
class Main
{
}
แต่คุณสามารถทำได้ คลาสหลักไม่เปิดเผยต่อสาธารณะ
public class Solution
{
  public static class Main
  {
  }
}
และคุณสามารถทำได้ คลาสหลักเป็นคลาสที่ซ้อนกัน

การเรียกเมธอดสามัญ (ไม่คงที่) ของคลาสจาก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
public class Solution
{
  public static int n = 100;

  public static int[] createArray()
  {
    return new int[n];
  }

  public static void main(String[]args)
  {
    int[] array = createArray();
  }
}
public class Solution
{
  public int n = 100;

  public int[] createArray()
  {
    return new int[n];
  }

  public static void main(String[]args)
  {
    Solution sol = new Solution();
    int[] array = sol.createArray();
  }
}

ประกาศตัวสร้างเช่นวิธีการ

"ข้อผิดพลาดทั่วไปอีกประการหนึ่งคือการประกาศคลาสคอนสตรัคเตอร์อย่างไม่ถูกต้อง ชื่อคอนสตรัคเตอร์ต้องเหมือนกับชื่อของคลาส และคอนสตรัคเตอร์ไม่มีประเภทผลลัพธ์ ข้อผิดพลาดที่พบบ่อยที่สุดมีลักษณะดังนี้:

public class Person
{
   private String value;

   void Person(String value)
   {
      this.value = value;
   }
}
ไม่ควรมีประเภทส่งคืนที่นี่
public class Person
{
   private String value;

   constructor(String value)
   {
      this.value = value;
   }
}
ชื่อตัวสร้างไม่ถูกต้อง จะต้องตรงกับชื่อชั้น
public class Person
{
   private String value;

   Person(String value)
   {
      value = value;
   }
}
this ที่ขาดหายไป. ตัวแปรvalueจะถูกกำหนดให้กับตัวเอง
public class Person
{
   private String value;

   Person(String value)
   {
      this.value = 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คำสั่ง ตัวอย่าง:

ผิด ขวา
LocalDate date = LocalDate.now();
DayOfWeek day = date.getDayOfWeek();
switch (day)
{
   case MONDAY:
      System.out.println("Monday");
   case TUESDAY:
      System.out.println("Tuesday");
   case WEDNESDAY:
      System.out.println("Wednesday");
   case THURSDAY:
      System.out.println("Thursday");
   case FRIDAY:
      System.out.println("Friday");
   case SATURDAY:
      System.out.println("Saturday");
   case SUNDAY:
      System.out.println("Sunday");
}
LocalDate date = LocalDate.now();
DayOfWeek day = date.getDayOfWeek();
switch (day)
{
   case MONDAY:
      System.out.println("Monday");
      break;
   case TUESDAY:
      System.out.println("Tuesday");
      break;
   case WEDNESDAY:
      System.out.println("Wednesday");
      break;
   case THURSDAY:
      System.out.println("Thursday");
      break;
   case FRIDAY:
      System.out.println("Friday");
      break;
   case SATURDAY:
      System.out.println("Saturday");
      break;
   case SUNDAY:
      System.out.println("Sunday");
      break;
}

"คุณรู้ไหม ดิเอโก... ตัดสินจากชุดของข้อผิดพลาดที่คุณนำเสนอที่นี่ มันให้ความรู้สึกเหมือนคุณกำลังอ่านบันทึกส่วนตัวของฉัน... หรือคุณกำลังดูฉันแก้ปัญหา"

"ฮ่า! ไม่ต้องสงสัยเลย ฉันได้อ่าน ติดตาม และดำเนินการต่อ ดังนั้น ระวังตัวไว้!"

"???"

“อย่ากังวลไป ฉันล้อเล่น ระวังตัวและทำผิดพลาดโง่ๆ ให้น้อยลง”