1. การเปรียบเทียบวัตถุกับ==

ข้อผิดพลาดยอดนิยมของโปรแกรมเมอร์มือใหม่คือการเปรียบเทียบวัตถุ (โดยเฉพาะสตริง) โดยใช้==ตัวดำเนินการ ตัวอย่างเช่น:

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");
}


2. การเปลี่ยนStringวัตถุ

โปรแกรมเมอร์มือใหม่มักลืมไปว่าออบเจกต์ทั้งหมดของคลาสนั้นเปลี่ยนรูปไม่ได้และทุกเมธอดของStringคลาสจะส่งคืนออบเจกต์ใหม่ — ออบเจ็กต์ปัจจุบันไม่เคยเปลี่ยนแปลง

ตัวอย่าง:

String s = "Hello";
s.toUpperCase (); // Convert to uppercase

รหัสนี้คล้ายกับรหัสที่ถูกต้อง แต่จะไม่ทำงานตามที่คาดไว้ เมธอดtoUpperCase()ไม่เปลี่ยนอ็อบเจกต์ที่เรียก รหัสที่ถูกต้องจะมีลักษณะดังนี้:

String s = "Hello";
String result = s.toUpperCase(); // Convert to uppercase


3. ลืมที่จะเริ่มต้นวัตถุที่เป็นองค์ประกอบของอาร์เรย์

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

int[] array;
array[0] = 1;
array[0] = 2;

รหัสนี้ใช้ไม่ได้: คุณต้องตั้งค่าตัวแปรอาร์เรย์อย่างชัดเจนให้เท่ากับการอ้างอิงไปยังวัตถุคอนเทนเนอร์ที่จะเก็บองค์ประกอบของอาร์เรย์

int[] array = new int[10];
array[0] = 1;
array[0] = 2;


4. การใช้ตัวแปรโลคัลแทนตัวแปรอินสแตนซ์

มือใหม่ไม่ชอบตั้งชื่อตัวแปรที่ยาวและมีความหมาย พวกเขามักจะใช้ชื่อที่มีตัวอักษรเดียว: 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 < count; i++)
      {
         a[i] = value;
      }
   }
}


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

บ่อยครั้งที่มีสถานการณ์ที่ต้องลบองค์ประกอบบางอย่างออกจากคอลเล็กชัน รหัสมีลักษณะดังนี้:

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 );


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

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

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


7. การเรียกเมธอดธรรมดา (ไม่คงที่) ของคลาสจาก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();
   }
}

เมธอดหลักสามารถอ้างถึงเมธอด/ตัวแปรแบบสแตติกเท่านั้น มิฉะนั้นจะต้องสร้างอินสแตนซ์ของ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();
  }
}


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

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

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;
   }
}




ถูกต้องทั้งหมด


9. การสืบทอดอินเทอร์เฟซที่ไม่ถูกต้อง

ผู้สร้าง Java พยายามทำให้ใกล้เคียงกับภาษาอังกฤษมาก ดังนั้นพวกเขาจึงเลือกคำหลักที่แตกต่างกันสำหรับแนวคิดที่เกี่ยวข้องบางอย่าง

เมื่อคลาสสืบทอดคลาส คุณต้องใช้คีย์เวิร์ดextends:

class Pet
{
}

class Cat extends Pet
{
}

เมื่อคลาสสืบทอดอินเทอร์เฟซ คุณต้องใช้คีย์เวิร์ดimplements:

interface Meow
{
}

class Cat implements Meow
{
}

เมื่ออินเทอร์เฟซสืบทอดอินเทอร์เฟซ ให้ใช้extendsคีย์เวิร์ด:

interface Meow
{
}

interface Voice extends Meow
{
}


10. การละเว้น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;
}