1. So sánh đối tượng với==

Lỗi yêu thích của các lập trình viên mới là so sánh các đối tượng (đặc biệt là các chuỗi) bằng cách sử dụng ==toán tử. Ví dụ:

Scanner console = new Scanner(System.in);
String s1 = console.nextLine();
String s2 = console.nextLine();
if (s1 == s2)
{
   System.out.println("The strings are equal");
}

Mã này sẽ không bao giờ hiển thị "Các chuỗi bằng nhau", bởi vì ifcâu lệnh so sánh các tham chiếu đến hai đối tượng chuỗi khác nhau.

Đây là phiên bản chính xác của mã:

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. Thay đổi Stringđối tượng

Những người mới lập trình thường quên rằng tất cả các đối tượng của lớp là bất biến và mọi phương thức của Stringlớp đều trả về một đối tượng mới — đối tượng hiện tại không bao giờ thay đổi.

Ví dụ:

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

Mã này rất giống với mã chính xác, nhưng nó sẽ không hoạt động như mong đợi. Phương thức này toUpperCase()không thay đổi đối tượng mà nó được gọi. Mã chính xác sẽ trông như thế này:

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


3. Quên khởi tạo các đối tượng là phần tử của mảng

Một sai lầm phổ biến khác là quên khởi tạo biến mảng. Ví dụ:

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

Mã này sẽ không hoạt động: bạn cần đặt rõ ràng biến mảng bằng một tham chiếu đến đối tượng vùng chứa sẽ lưu trữ các phần tử của mảng.

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


4. Sử dụng biến cục bộ thay vì biến thể hiện.

Người mới không thích nghĩ ra những cái tên dài và có ý nghĩa cho các biến. Họ thường sử dụng các tên có một chữ cái: a, b, iv.v. Đó là một điều tàn nhẫn khi mã có nhiều biến như thế:

Đưa số 99 vào 100 ô của mảng
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;
    }
  }
}

Đoạn mã trên sẽ không được biên dịch. Phiên bản chính xác trông như thế này:

Đưa số 99 vào 100 ô của mảng
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. Xóa mục bộ sưu tập

Rất thường có những tình huống khi một phần tử nhất định cần được xóa khỏi bộ sưu tập. Mã trông đại khái như thế này:

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

Mã này sẽ không hoạt động vì bạn không thể sử dụng vòng lặp for-each để duyệt đồng thời các phần tử của tập hợp và sửa đổi tập hợp đó.

Có một số giải pháp. Đầu tiên, bạn có thể duyệt qua một bộ sưu tập và thay đổi một bộ sưu tập khác:

Giải pháp 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);

Thứ hai, kể từ Java 8, các bộ sưu tập có một removeIf()phương thức mà bạn có thể chuyển một quy tắc (hàm lambda) cho biết phần tử nào cần xóa.

Ví dụ:

Giải pháp 2
ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 0, -5, -7, -12, 5, 15);

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


6. Đặt một số lớp với publiccông cụ sửa đổi vào một tệp

Chỉ có thể có một lớp công khai trong một tệp. Nhiều lớp có thể được khai báo trong một tệp, nhưng chúng phải là lớp bên trong của lớp công khai hoặc không có công publiccụ sửa đổi. Ví dụ:

Nội dung của tệp Solution.java Ghi chú
public class Solution
{
}
public class Main
{
}
Điều này không được phép: hai lớp công khai trong một tệp.
public class Solution
{
}
class Main
{
}
Nhưng bạn có thể làm điều này. Lớp chính không công khai
public class Solution
{
  public static class Main
  {
  }
}
Và bạn có thể làm điều này. Lớp chính là một lớp lồng nhau


7. Gọi các phương thức thông thường (không tĩnh) của một lớp từ main()phương thức tĩnh

Đôi khi các lập trình viên mới cố gắng truy cập các biến và phương thức không tĩnh từ main()phương thức hoặc các phương thức tĩnh khác. Tất nhiên, mã như vậy sẽ không hoạt động.

public class Solution
{
   public int n = 100;
   public int[] createArray()
   {
      return new int[n];
   }

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

Phương thức chính chỉ có thể tham chiếu đến các phương thức/biến tĩnh. Chà, hoặc trước tiên nó phải tạo một thể hiện của Solutionlớp và chỉ sau đó mới gọi các phương thức không tĩnh của đối tượng đó. Ví dụ:

Giải pháp 1 Giải pháp 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. Khai báo constructor giống như một phương thức

Một lỗi phổ biến khác là khai báo sai hàm tạo của lớp. Tên của hàm tạo phải giống với tên của lớp và hàm tạo không có kiểu kết quả. Những sai lầm phổ biến nhất trông như thế này:

public class Person
{
   private String value;

   void Person(String value)
   {
      this.value = value;
   }
}




Không nên có một loại trả lại ở đây
public class Person
{
   private String value;

   constructor(String value)
   {
      this.value = value;
   }
}




Tên hàm tạo không hợp lệ. Tên của hàm tạo phải trùng với tên lớp
public class Person
{
   private String value;

   Person(String value)
   {
      value = value;
   }
}






this đang mất tích. Biến valuesẽ được gán cho chính nó
public class Person
{
   private String value;

   Person(String value)
   {
      this.value = value;
   }
}




Đó là tất cả chính xác


9. Kế thừa giao diện không chính xác

Những người tạo ra Java đã cố gắng làm cho nó gần với tiếng Anh, vì vậy họ đã chọn các từ khóa khác nhau cho một số khái niệm liên quan.

Khi một lớp kế thừa một lớp, bạn phải sử dụng extendstừ khóa:

class Pet
{
}

class Cat extends Pet
{
}

Khi một lớp kế thừa một giao diện, bạn cần sử dụng implementstừ khóa:

interface Meow
{
}

class Cat implements Meow
{
}

Khi một giao diện kế thừa một giao diện, hãy sử dụng extendstừ khóa:

interface Meow
{
}

interface Voice extends Meow
{
}


10. Bỏ qua breaktrong switchcâu lệnh

Và sai lầm cuối cùng đối với chúng ta hôm nay, nhưng không phải là sai lầm cuối cùng đối với những người mới bắt đầu, là không đưa được một breakmệnh đề vào trong một switchmệnh đề. Ví dụ

Sai Phải
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;
}