В старые времена Ван Сиетан был перед Яном, Летайте в дома простых людей. Редактор поможет вам проанализировать Руководство по разработке Java для Alibaba!
задний план
Руководство по разработке Java для Alibaba представляет собой обобщение коллективного опыта и знаний технической команды Alibaba Group.С точки зрения разработчиков Java оно разделено на шесть аспектов: спецификация программирования, журнал исключений, модульное тестирование, спецификация безопасности, инженерная структура и база данных MySQL. Видение руководства состоит в том, чтобы кодировать эффективно, качество кода, эффективность в первую очередь и качество в первую очередь.
Цель
Причина, по которой я хочу написать эту серию статей, заключается в том, чтобы сначала изучить и обобщить, затем подумать и понять, и, что более важно, поделиться и общаться.Каждый пункт в руководстве имеет свои скрытые принципы и опыт.То, что мы видим, Это всего лишь верхушка айсберга, углубление в знания, лежащие в основе этого, полезно для более глубокого понимания и улучшения вашей базовой технической грамотности в реальном программировании.
тема
- [Рекомендуется] При выражении аномальных ветвей меньше используйте метод if-else.Этот метод можно переписать как:
if (condition) {
...
return obj;
}
// 接着写 else 的业务逻辑代码;
Примечание. Если вам нужно использовать if()...else if()...else... для выражения логики, [Обязательно] Избегайте последующего измерения кода. Трудно защитить, не превышайте 3 слоя. Положительный пример: код логического суждения if-else с более чем 3 уровнями может быть реализован с использованием защитных операторов, шаблонов стратегий, шаблонов состояний и т. д. Ниже приведены примеры защитных операторов:
public void today() {
if (isBusy()) {
System.out.println(“change time.”); return;
}
if (isFree()) {
System.out.println(“go to travel.”);
return;
}
System.out.println(“stay at home to learn Alibaba Java Coding Guidelines.”);
return;
}
Попытаемся разобрать приведенные выше правила на примерах, перед разбором сначала проясним реализацию дефолтных методов equals и hashCode в Java, а при помещении элемента в хеш-набор (HashSet, HashMap и т.д.) хэш Правила решения набора для методов equals и hashCode. Метод equals(Object obj) по умолчанию в объектах Java используется для определения того, являются ли два объекта «одинаковыми», и возвращает true, если они «одинаковые», в противном случае возвращает false. Метод hashCode() возвращает целое число, которое возвращается путем преобразования внутреннего адреса объекта в целое число. При сохранении объекта в хеш-наборе сначала сравните хэш-код. Если хэш-код не равен, поставьте его напрямую. В противном случае продолжайте сравнивать равные. Если равные не равны, поставьте его, а если равные равны , отбросить его напрямую.
понимать
- Какие проблемы могут возникнуть, если я просто переопределю equals без переопределения hashCode?
package com.test;
import java.util.HashSet;
import java.util.Set;
public class OverrideEqualsTest {
public static void main(String[] args) {
Set<Point> set = new HashSet<Point>();
Point p1 = new Point(1, 1);
Point p2 = new Point(1, 1);
System.out.println("p1.equals(p2):" + p1.equals(p2));
set.add(p1);
set.add(p2);
set.add(p1);
System.out.println("set.size():" + set.size());
for (Point p : set) {
System.out.println(p);
}
}
static class Point {
private int x;
private int y;
public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Point other = (Point) obj;
if (x != other.x) {
return false;
}
if (y != other.y) {
return false;
}
return true;
}
@Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
}
}
результат операции: p1.equals(p2): правда установить.размер():2 Точка[х=1,у=1] Точка[х=1,у=1]
Анализ: поскольку метод hashCode не переписывается, целые числа, возвращаемые методами hashCode по умолчанию для объектов p1 и p2, должны быть разными, поэтому в набор можно поместить и p1, и p2, так что это не тот результат, которого мы ожидали.
- Что произойдет, если вы переопределите только hashCode без переопределения equals?
package com.test;
import java.util.HashSet;
import java.util.Set;
public class OverrideHashCodeTest {
public static void main(String[] args) {
Set<Point> set = new HashSet<Point>();
Point p1 = new Point(1, 1);
Point p2 = new Point(1, 1);
System.out.println("p1.equals(p2):" + p1.equals(p2));
set.add(p1);
set.add(p2);
set.add(p1);
System.out.println("set.size():" + set.size());
for (Point p : set) {
System.out.println(p);
}
}
static class Point {
private int x;
private int y;
public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
final int prime = 3L;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
}
}
результат операции: p1.equals(p2): ложь установить.размер():2 Точка[х=1,у=1] Точка[х=1,у=1]
Анализ: поскольку нет переопределения равен методу, по умолчанию P1 и P2 равен методу для сравнения объектов «==», а P1 и P2 - два разных объекта, поэтому P1 и P2 могут быть размещены в наборе, так что это не наше желаемый результат. Таким образом, когда мы также отменяем равную равновесию и методы Hashcode, чтобы получить последовательные результаты в сборе хеш-операции.
- После помещения объекта в набор хэшей значение, влияющее на хеш-код, изменяется.Каковы последствия?
package com.test;
public class Test {
public static void main(String[] args) {
Point p1 = new Point(1, 1);
Point p2 = new Point(2, 2);
set.add(p1);
set.add(p2);
System.out.println("set.size():" + set.size());
p2.setY(3);
set.remove(p1);
set.remove(p2);
System.out.println("set.size():" + set.size());
}
}
результат операции: установить.размер():2 set.size():1
Анализ: во время выполнения значение y объекта p2 изменяется, что приводит к изменению возвращаемого значения hashCode объекта p2, поэтому метод удаления hashset не находит объект, отображаемый новым hashCode, что приводит к утечка памяти.