"Xin chào, Amigo! Hãy tiếp tục nói về những sai lầm. Lần này, chúng ta sẽ khám phá những lỗi mà trình biên dịch không phải lúc nào cũng giúp bạn. Hãy chú ý và bạn sẽ học được điều gì đó về bản thân."

"Tôi sẵn sàng lắng nghe, Diego. Tôi hy vọng điều này sẽ không quá xấu hổ đối với tôi."

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

"Danh sách các lỗi lập trình viên mới yêu thích hàng đầu của chúng tôi bắt đầu bằng việc so sánh các đối tượng (đặc biệt là các chuỗi) bằ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");
}

"Tôi đã làm điều đó khá thường xuyên. Bây giờ tôi có thể thấy rõ ràng rằng mã này sẽ không bao giờ hiển thị "Các chuỗi bằng nhau", bởi vì câu iflệnh so sánh các tham chiếu đến hai đối tượng chuỗi khác nhau."

"Vâng. Đó là lý do tại sao lựa chọn chính xác sẽ là:

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

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."

"Cách đây không lâu tôi đã học được ý nghĩa của bất biến , nhưng tôi nghĩ tôi đã làm được điều này.

"Tôi khá chắc chắn về điều đó. Ví dụ:

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

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

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

"Chính xác. Tôi đã làm điều đó, nhưng tôi thậm chí không thực sự hiểu điều gì sai. Cảm ơn bạn đã giải thích!"

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

"Một lỗi 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 tham chiếu đến đối tượng vùng chứa sẽ lưu trữ các phần tử của mảng. Phiên bản chính xác:

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

Sử dụng một biến cục bộ thay vì một 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."

"Điều đó rất đúng. Để hoàn thành công việc nhanh chóng, đôi khi tôi đặt các tên biến như a, b, và i."

"Đừng làm thế. Đó 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;
    }
  }
}

"Sẽ khó mắc lỗi hơn nhiều trong mã có tên riêng. 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 < 10; i++)
      {
         a[i] = value;
      }
   }
}

Xóa một mục bộ sưu tập

"Bạn đã xem qua các bộ sưu tập chưa?"

"Nghĩa đen chỉ bằng một con mắt."

"Nếu bạn không biết tôi đang nói về điều gì, thì hãy ghi chú lại cho chính mình để xem lại trong tương lai. 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. Đoạn mã trông giống như cái 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 for-eachvòng lặp để duyệt đồng thời các phần tử của bộ sưu tập và sửa đổi bộ sưu tậ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 );

Đặ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 hơn có thể được khai báo trong một tệp, nhưng chúng phải là các lớp bên trong của một lớp công khai hoặc không có công cụ sửa đổi. Ví dụ public:

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

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

" mainPhương thức 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 lớp Solutionvà 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();
  }
}

Khai báo một hàm tạo 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ó loại kết quả. Các lỗi phổ biến nhất có dạng như sau:

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ệ. Nó phải khớp 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ả các chính xác.

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, hay chính xác hơn là triển khai giao diện đó, bạn cần sử dụng từ implementskhó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 Meov
{
}

Bỏ qua breaktrong một switchtuyên bố

"Và sai lầm cuối cùng của ngày hôm nay, nhưng không phải là sai lầm cuối cùng đối với người mới bắt đầu, là không bao gồm một breakmệnh đề 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;
}

"Bạn biết đấy, Diego... Đánh giá về hàng loạt lỗi mà bạn trình bày ở đây, có vẻ như bạn đang đọc nhật ký cá nhân của tôi... Hoặc bạn đang xem tôi giải quyết các nhiệm vụ."

"Ha! Đừng nghi ngờ gì về điều đó. Tôi đã đọc, theo dõi và tiếp tục làm như vậy. Vì vậy, hãy cảnh giác!"

"???"

"Đừng lo lắng. Tôi chỉ đùa thôi. Hãy cảnh giác và mắc ít sai lầm ngu ngốc hơn."