Думая об Али Руководство по разработке Java (1)

Java

В старые времена Ван Сиетан был перед Яном, Летайте в дома простых людей. Редактор поможет вам проанализировать Руководство по разработке 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, что приводит к утечка памяти.

Публичный аккаунт WeChat:На мечеПожалуйста, обратите внимание на мою личную технологию общедоступного аккаунта WeChat, подпишитесь на дополнительный контент