Java — это язык объектно-ориентированного программирования (ООП), разработанный Oracle. Один из самых популярных языков программирования в мире, Java используется для создания приложений Android, веб-приложений, игр и программного обеспечения на основе баз данных.
Сегодня мы рассмотрим 10 распространенных ошибок разработчиков Java, а также способы их исправления.
- Неправильное использование изменяемых и неизменяемых объектов
- Confusing =, ==, and .equals()
- Использование ArrayList вместо LinkedList
- Не обрабатывает нулевые значения
- Забывая о бесплатных ресурсах
- Игнорирование видимости метода
- Доступ к нестатическим переменным из статических методов
- Удаление элемента из массива внутри цикла
- Неэффективная конкатенация строк
- Игнорирование исключений
- Что изучать дальше
Неправильное использование изменяемых и неизменяемых объектов
При выборе между созданием изменяемого или неизменяемого объекта необходимо соблюдать тщательный баланс. Изменяемый объект может быть изменен после создания, а неизменяемый объект — нет. Хотя неизменяемые объекты предлагают такие преимущества, как безопасность, простота и меньший объем памяти, они создают сборку мусора, когда требуется отдельный объект для каждого отдельного значения.
Ниже приведены некоторые ключевые различия между изменяемыми и неизменяемыми объектами, чтобы определить, какие из них использовать при создании объекта.
Мутабельный:
- Когда в объект вносятся изменения, новый объект не формируется.
- Предоставляются методы для изменения содержимого объекта.
- Присутствуют как методы получения, так и методы установки.
- Типичные примеры включают StringBuffer, StringBuilderи java.util.date.
Неизменный:
- Новый объект формируется при изменении существующего объекта.
- Никаких методов для изменения содержимого объекта не предусмотрено.
- Присутствуют только методы получения. Нет никаких сеттерных методов.
- Общие примеры включают все унаследованные классы, классы-оболочки и классы String.
Confusing =
, ==
, and .equals()
Ошибиться между этими тремя операторами легко, особенно между двумя последними. Помните, что =это используется для задания. ==является сравнительным сравнением на равенство, то есть проверяет, указывают ли оба объекта на одну и ту же ячейку памяти..equals()оценивает, равны ли два объекта по стоимости.
Как правило, придерживайтесь правила.equals()сравнения объектов, особенно строк.
1 String a = "hello"; 2 String b = "world"; 3 4 if ( (a+b).equals("helloworld") ) 5 { 6 System.out.println("hellowworld"); 7 }
Использование ArrayList вместо LinkedList
По умолчанию легко использовать списки ArrayLists, поскольку они более распространены и знакомы. Однако во многих случаях LinkedLists работают значительно лучше, чем ArrayLists.
В общем, списки ArrayLists лучше подходят, когда приложение требует хранения данных и доступа к ним. LinkedLists лучше, когда приложение требует манипулирования сохраненными данными.
ArrayList
- Использует динамический массив для хранения элементов.
- Требуется больше времени для манипулирования ArrayList из-за внутренней реализации сдвига битов памяти.
- Реализует интерфейс List и поэтому действует как список.
LinkedList
- Использует двусвязный список для хранения элементов.
- Требуется меньше времени для управления LinkedList по сравнению с ArrayList, поскольку в двусвязном списке нет сдвигаемых битов памяти.
- Реализует как интерфейс List, так и интерфейс Deque, поэтому может действовать как в качестве списка, так и в качестве двухсторонней очереди.
Не обрабатывает нулевые значения
Большинство разработчиков Java NullPointerExceptionв какой-то момент сталкивались с проблемой. Исключение NullPointerException возникает, когда переменная объявляется, но перед попыткой использования содержимого переменной ей не назначен объект.
Распространенная ошибка заключается в создании catchфразы для NullPointerException, а не в написании кода для обработки разыменования базового нулевого указателя. Программы, которые ловят или подавляют
NullPointerExceptions вместо обработки разыменования нулевого указателя может чрезвычайно затруднить определение того, какое выражение вызывает исключение в tryблоке или вызвать ненужные издержки производительности.
Хотя существует множество способов обработки нулевых значений, вот два решения при работе с Stringаргументом.
Проверить Stringаргумент для null
boolean isName(String s){if (s == null) {retrun false;}String names[] = s.split(» «);if (names.length != 2) {return false;}return (isCapitalized(names[0]) && is Capitalized(names[1]));}
Вместо явной проверки целенаправленно бросайте NullPointerException
boolean isName(String s) /* Throws NullPointerException */ {String names[] = s.split(» «);if (names.length !=2) {return false;}return (isCapitalized(names[0]) && isCapitalized(names[1]));}
Забывая о бесплатных ресурсах
Если забыть освободить ресурсы, это приведет к заполнению памяти и сбору неиспользуемых объектов из сетевых подключений и файловых потоков.
Вы можете столкнуться с проблемой утечки памяти, если ваша программа Java начинает замедляться или наблюдается заметное снижение производительности с большим количеством файлов по сравнению с небольшим количеством файлов.
Чтобы избежать этой ошибки, используйте tryоператор -with-resources для реализации интерфейса Closeableили, AutoClosableчтобы гарантировать закрытие ресурсов после использования.
В качестве уловки напомните себе о необходимости реализовывать этот оператор всякий раз, когда вы открываете соединение с файлом или ресурсом с вашей программой.
Игнорирование видимости метода
При создании методов обращайте пристальное внимание на то, какие из них вы создаете, publicа какие — private. Открытые методы в приложении — это видимый API, поэтому они должны быть как можно более компактными и удобочитаемыми.
Когда методы, которые должны быть privateобъявлены public, раскрываются общественности о внутренних тонкостях и деталях реализации. И наоборот, когда методы, которые должны быть publicобъявлены private, вы рискуете создать пробелы в API и запустить необходимые модульные тесты.
Доступ к нестатическим переменным из статических методов
Напомним, что статической переменной требуется класс для вызова переменных и методов, а нестатической переменной требуется объект или экземпляр для вызова переменных и методов. Подумайте об аналогии квадрата с прямоугольником, но прямоугольник не является квадратом.
Точно так же статическая переменная может быть доступна как статическим, так и нестатическим функциям-членам, в то время как нестатическая переменная не может быть доступна статической функции-члену.
Чтобы получить доступ к нестатической переменной, создайте объект с собственным значением экземпляра.
class A {int num1;static int num2;public void show() {num2 = 10;}}public class b{public static void main(String args [])}A.num2 = 5;A obj1 = newA();obj1.num1 = 2;
Удаление элемента из массива внутри цикла
При итерации по массиву одной из распространенных ошибок является удаление или удаление элемента в цикле. Это приведет к уменьшению длины массива и неправильному смещению индекса. Следовательно, вы увидите ConcurrentModificationExceptionошибку.
Чтобы избежать этого исключения, используйте Iteratorв следующий раз, когда вы захотите удалить элемент в цикле. Ниже приведен пример правильного удаления элемента из массива внутри цикла.
ArrayList<String. l = new ArrayLists<String>(Arrays.asList(«a», «b», «c», «d»));Iterator<String> iter = l.iterator();while (iter.hasNext()) {String s = iter.next();if (s.equals(«c»)) {iter.remove();}}
Неэффективная конкатенация строк
При построении большой Stringнеэффективной конкатенации строк может произойти чрезмерное использование памяти и снижение производительности.
Хотя существует несколько способов объединения строк, основное практическое правило — по возможности избегать использования, String.format()поскольку это снижает удобочитаемость при работе с более чем двумя переменными. Вместо этого оптимизируйте свой код, используя StringBuilder.
StringBuilder sb = new StringBuilder();for(int i = 0; i < 1,000; i++) {sb.append(i);}String final = sb.toString();
Игнорирование исключений
Распространенная ошибка новичков в Java — это не писать код для обработки исключений. На первый взгляд может показаться нормальным, если код выполняется без каких-либо исключений, но это может привести к тому, что код замолчит в случае возникновения исключения.
Чтобы избежать этой ошибки, убедитесь, что вы правильно обработали исключения с помощью Try-Catch-finally, который состоит из трех операторов:
- Try: включает блок кода, который может содержать исключение
- Catch: один или несколько блоков, обрабатывающих исключение
- Finally: блок, который выполняется после успешного выполнения блока try или обработки возникшего исключения.
Ниже приведен пример обработки исключений для входного потока файла с помощью Try-Catch-finally.
FileInputStream input = null;try{File file = new File(«./index.txt»);input = new FileInputStream(file);} catch (FileNotFoundException e) {e.printStackTrace();finally {if (input !=null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}}}}}
Что изучать дальше
Теперь, когда вы рассмотрели десять основных ошибок разработчиков Java, пришло время освежить свои знания Java с помощью некоторой практической практики. Таким образом, вы сможете применить навыки, которые вы узнали здесь сегодня.
Независимо от вашего уровня владения Java, полезно освежить следующие концепции:
- Объектно-ориентированное программирование на Java
- Лямбда-выражение Java
- Возможности Java 8
- Основы многопоточности
Чтобы познакомиться с этими и другими концепциями, ознакомьтесь с учебной программой » Java для программистов» от Educative . Этот путь идеально подходит для вас, если у вас уже есть опыт программирования, но вы нуждаетесь в переподготовке по Java. Вы охватите все, от типов данных до Stream API, с упражнениями по кодированию в браузере.