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()方法,您可以向該方法傳遞一個規則(lambda 函數)來指示要刪除的元素。

例子:

方案二
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
  {
  }
}
你可以做到這一點。主類是一個嵌套類


main()7. 從靜態方法調用類的普通(非靜態)方法

有時,新手程序員會嘗試從方法或其他靜態方法訪問非靜態變量和方法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 方案二
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;
}