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

Този code никога няма да покаже „Низовете са равни“, защото ifоператорът сравнява препратки към два различни обекта на низ.

Ето правилната version на codeа:

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

Този code е много подобен на правилния code, но няма да работи според очакванията. Методът toUpperCase()не променя обекта, на който е извикан. Правилният code ще изглежда така:

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


3. Забравяне на инициализиране на обекти, които са елементи на масив

Друга често срещана грешка е да забравите да инициализирате променлива на масив. Пример:

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

Този code няма да работи: трябва изрично да зададете променливата на масива, равна на препратка към контейнерния обект, който ще съхранява елементите на масива.

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


4. Използване на локална променлива instead of променлива на екземпляр.

Новаците не обичат да измислят дълги и смислени имена за променливи. Те често използват еднобуквени имена: a, b, iи т.н. Това е жестоко нещо, когато codeът има няколко променливи като тази:

Поставете числото 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;
    }
  }
}

Горният code няма да се компorра. Правилната version изглежда така:

Поставете числото 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);

Този code няма да работи, защото не можете да използвате цикъл 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модификатора в един файл

Във файл може да има само един публичен клас. Повече класове могат да бъдат декларирани във файл, но те трябва or да са вътрешни класове на публичен клас, or да нямат модификатора public. Пример:

Съдържание на file Solution.java Забележка
public class Solution
{
}
public class Main
{
}
Това не е позволено: два публични класа в един файл.
public class Solution
{
}
class Main
{
}
Но можете да направите това. Основният клас не е публичен
public class Solution
{
  public static class Main
  {
  }
}
И вие можете да направите това. Основният клас е вложен клас


7. Извикване на обикновени (нестатични) методи на клас от статичен main()метод

Понякога начинаещи програмисти се опитват да получат достъп до нестатични променливи и методи от метода main()or други статични методи. Такъв code няма да работи, разбира се.

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

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

Основният метод може да се отнася само за статични методи/променливи. Е, or първо трябва да създаде екземпляр на 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;
}