Java 코드 검토 가이드

Java 개발자는 코드의 힌트를 빠르게 보기 시작합니다.

다른 두 눈으로 코드를 스캔하는 것은 항상 유용하다. 생산을 중단하기 전에 오류를 발견하는 데 도움을 줄 수 있다.너는 전문가가 될 필요가 없이 다른 사람의 코드를 검사할 수 있다.프로그래밍 언어의 경험과 회고 목록이 시작에 도움이 될 것이다.Java 코드를 볼 때 기억해야 할 사항을 나열했습니다.읽어라!

1. Java 코드 규칙 따르기


언어 관례를 따르는 것은 코드를 빠르게 훑어보고 이해하는 데 도움이 되어 가독성을 높일 수 있다.예를 들어 자바의 모든 가방 이름은 소문자로 쓰이고, 상수는 대문자로 쓰며, 변수명은 CamelCase로 쓴다. here이 약정한 전체 목록을 찾아라.
어떤 팀은 자신의 약속을 정하기 때문에 이런 상황에서 유연해야 한다!

2. 명령식 코드를 lambda와streams로 바꾸기


자바 8+를 사용한다면, 순환과 지루함을 streams와 Lambda로 바꾸는 방법은 코드를 더욱 깨끗하게 보일 것입니다.Lambdasstreams에서는 Java를 사용하여 함수 코드를 작성할 수 있습니다.다음 코드 세그먼트는 일반적인 명령 방식으로 홀수를 필터합니다.
List **<** Integer **>** oddNumbers **=**  **new** ArrayList**<>();**
 **for** **(**Integer number **:** Arrays **.** asList**(**1 **,** 2 **,** 3 **,** 4 **,** 5 **,** 6**))**  **{**
    **if** **(**number **%** 2 **!=** 0**)**  **{**
      oddNumbers **.** add**(**number**);**
  **}**
 **}**
filtering odd numbers의 기능은 다음과 같습니다.
List **<** Integer **>** oddNumbers **=** Stream **.** of**(**1 **,** 2 **,** 3 **,** 4 **,** 5 **,** 6**)**
  **.** filter**(**number **->** number **%** 2 **!=** 0**)**
  **.** collect**(**Collectors **.** toList**());**

3. NullPointer Exception 조심


새 방법을 작성할 때, 가능한 한 null로 돌아가는 것을 피하십시오.이로 인해 104만5천679만1천510명이 사망할 수 있다.다음 코드 세그먼트에서 목록에 정수가 없으면 가장 높은 방법은null로 되돌아옵니다.
**class**  **Items**  **{**
    **private**  **final** List **<** Integer **>** items **;**
    **public** **Items(**List **<** Integer **>** items**)**  **{**
            **this.** items **=** items **;**
    **}**
    **public** Integer **highest()**  **{**
      **if** **(**items **.** isEmpty**())**  **return**  **null;**
      Integer highest **=**  **null;**
      **for** **(**Integer item **:** items**)**  **{**
          **if** **(**items **.** indexOf**(**item**)**  **==** 0**)** highest **=** item **;**
          **else** highest **=** highest **>** item **?** highest **:** item **;**
      **}**
      **return** highest **;**
    **}**
 **}**
대상을 직접 호출하는 방법에 앞서 저는 null pointer exceptions을 검사할 것을 건의합니다. 아래와 같습니다.
Items items **=**  **new** Items**(**Collections **.** emptyList**());**
Integer item **=** items **.** highest**();**
 **boolean** isEven **=** item **%** 2 **==** 0 **;** _// throws NullPointerException ❌_  
**boolean** isEven **=** item **!=**  **null**  **&&** item **%** 2 **==** 0 _// ✅_
그러나 코드 곳곳에 빈 검사가 있으면 매우 번거로울 수 있다.Java 8+를 사용하는 경우 유효한 상태가 없을 수 있는 값을 나타내는 옵션 클래스를 사용하는 것이 좋습니다.대체 동작을 쉽게 정의할 수 있고 링크 방법에 매우 유용합니다.
다음 코드 세션에서, 우리는 nulls을 사용하여 선택할 수 있는 값을 되돌려 주는 방법을 통해 가장 큰 숫자를 찾습니다.우리가 사용하는 것은 흐름이라는 것을 주의하세요.reduce, 선택할 수 있는 값을 되돌려줍니다.
**public** Optional **<** Integer **>** **highest()**  **{**
    **return** items
            **.** stream**()**
            **.** reduce**((**integer **,** integer2**)**  **->** 
                            integer **>** integer2 **?** integer **:** integer2**);**
 **}**
Items items **=**  **new** Items**(**Collections **.** emptyList**());**
items **.** highest**().**ifPresent**(**integer **->**  **{** _// ✅_  
    **boolean** isEven **=** integer **%** 2 **==** 0 **;**
**});**
또는 @Nullable 또는 @NonNull 등의 주석을 사용할 수도 있습니다. 코드를 구축할 때 빈 충돌이 발생하면 경고가 발생합니다.예를 들어, @Nullable 매개변수를 @NonNull 매개변수를 적용하는 방법에 전달합니다.

Java 스트림 API 4. 고객 코드의 인용을 필드에 직접 분배


필드가 최종 필드라도 클라이언트 코드에 노출된 인용을 조작할 수 있다.우리는 하나의 예를 통해 이 점을 더욱 잘 이해합시다.
**private**  **final** List **<** Integer **>** items **;**
 **public** **Items(**List **<** Integer **>** items**)**  **{**
        **this.** items **=** items **;**
 **}**
위의 코드 세션에서, 우리는 클라이언트 코드의 인용을 필드에 직접 분배합니다.클라이언트는 목록의 내용을 쉽게 바꾸고 우리의 코드를 조작할 수 있다. 아래와 같다.
List **<** Integer **>** numbers **=**  **new** ArrayList**<>();**
Items items **=**  **new** Items**(**numbers**);**
numbers **.** add**(**1**);** _// This will change how items behaves as well_
대신 을 고려하거나 새 참조를 만들어 필드에 할당하십시오.
**private**  **final** List **<** Integer **>** items **;**
 **public** **Items(**List **<** Integer **>** items**)**  **{**
    **this.** items **=**  **new** ArrayList**<>(**items**);**
 **}**
인용을 되돌릴 때 같은 규칙도 적용된다.너는 내부의 가변 상태가 드러나지 않도록 조심해야 한다.

클론 참조 5.예외적인 상황을 조심스럽게 처리한다


이상을 포획할 때, 여러 개의catch 블록이 있다면,catch 블록의 순서가 가장 적게 정해져 있는지 확인하십시오.다음 코드 세그먼트에서 exception류는 모든 이상 어머니이기 때문에 두 번째 블록에서 이상을 포착하지 않습니다.
**try**  **{**
    stack **.** pop**();**
 **}**  **catch** **(**Exception exception**)**  **{**
    _// handle exception_  
**}**  **catch** **(**StackEmptyException exception**)**  **{**
    _// handle exception_  
**}**
만약 상황이 복구 가능하고 클라이언트(라이브러리 또는 코드 사용자)가 처리할 수 있다면 을 사용하는 것이 가장 좋다.e, g.IOException은 선택한 이상으로 클라이언트가 이 장면을 처리하도록 강요한다. 만약에 클라이언트가 이 이상을 다시 던지기를 선택한다면 의식적으로 그것을 호출해서 이 이상을 무시해야 한다.

이상 검사 6. 데이터 구조의 선택에 대해 생각한다


자바 집합은ArrayList,LinkedList,Vector,Stack,HashSet,HashMap,Hashtable을 제공합니다.정확한 환경에서 사용할 수 있도록 각 방법의 장단점을 이해하는 것이 중요하다.다음 프롬프트를 사용하여 올바른 선택을 할 수 있습니다.
  • 맵: 키, 값이 형식에 대한 무질서한 항목이 있고 효율적인 검색, 삽입, 삭제 작업이 필요하다면 이 맵은 매우 유용합니다. ,Hashtable,LinkedHashMap은 모두Map 인터페이스의 실현이다.
  • 목록: 프로젝트를 만드는 데 매우 자주 사용되는 서열표입니다.이 목록에는 중복 항목이 포함될 수 있습니다.ArrayList는 List 인터페이스의 구현입니다.집합을 사용하면 목록을 안전하게 만들 수 있습니다.synchronizedList 는 Vector 를 사용하지 않아도 됩니다.HashMap은 벡터에 대해 기본적으로 유행이 지난 정보를 더 많이 제공했다.
  • 세트: 목록과 유사하지만 중복은 허용되지 않습니다.HashSet은 Set 인터페이스를 실현합니다.
  • 여기 있다 7. 노출 전 심사숙고 후 행동


    Java에는 선택할 수 있는 액세스 수정자가 많습니다. — 공공의, 보호의, 개인의.클라이언트 코드에 방법을 공개하기를 원하지 않으면, 기본적으로 모든 내용의 사유성을 유지하기를 원할 수도 있습니다.일단 네가 API를 공개한다면 다시는 돌아갈 길이 없을 것이다.
    예를 들어, 다음과 같은 이름으로 도서를 체크 아웃하는 방법이 있는 라이브러리가 있습니다.
    **public** **checkout(**String bookName**)**  **{**
        Book book **=** searchByTitle**(**availableBooks **,** bookName**);**
      availableBooks **.** remove**(**book**);**
      checkedOutBooks **.** add**(**book**);**
     **}**
    
    **private** **searchByTitle(**List **<** Book **>** availableBooks **,** String bookName**)**  **{**
     **...**
     **}**
    
    기본적으로 검색 ByTitle 방법을 사유화하지 않고 최종적으로 공개되면 다른 클래스가 그것을 사용하기 시작하고 논리를 구축할 수 있습니다. Library 클래스의 일부가 되기를 원할 수도 있습니다.그것은 라이브러리 종류의 봉인을 파괴하거나 다른 사람의 코드를 파괴하지 않은 상태에서 나중에 복구/수정할 수 없습니다.의식적으로 폭로!

    8. 코드-인터페이스


    특정 인터페이스(예를 들어 Array List 또는 Linked List)의 구체적인 구현이 있고 코드에서 직접 사용하면 고도의 결합을 초래할 수 있습니다.목록 인터페이스를 꾸준히 사용하면 코드를 중단하지 않고 언제든지 전환할 수 있습니다.
    **public** **Bill(**Printer printer**)**  **{**
        **this.** printer **=** printer **;**
     **}**
    
    **new** Bill**(new** ConsolePrinter**());**
     **new** Bill**(new** HTMLPrinter**());**
    
    위의 코드 세션에서 프린터 인터페이스를 사용하면 개발자가 다른 구체적인 클래스인 HTMLPrinter로 이동할 수 있습니다.

    9. 인터페이스를 강제로 설치하지 마라


    다음 화면을 보십시오.
    **interface**  **BookService**  **{**
            List **<** Book **>** **fetchBooks();**
        **void** **saveBooks(**List **<** Book **>** books**);**
        **void** **order(**OrderDetails orderDetails**)**  **throws** BookNotFoundException **,** BookUnavailableException **;**    
    **}**
    
    **class**  **BookServiceImpl**  **implements** BookService **{**
     **...**
    
    이런 인터페이스를 만들면 어떤 좋은 점이 있습니까?이 인터페이스는 다른 종류로 이루어집니까?이 인터페이스는 다른 종류에 의해 충분히 통용될 수 있습니까?만약 모든 이 문제들의 답안이 부정적이라면, 나는 틀림없이 당신에게 이 불필요한 인터페이스를 사용하지 말라고 건의할 것입니다. 당신은 장래에 반드시 이 인터페이스를 유지해야 합니다.마틴 포러는 에서 이 점을 잘 설명했다.
    그렇다면 인터페이스의 좋은 용례는 무엇입니까?만약 우리가 하나의 직사각형과 하나의 원형을 가지고 있다면, 그것들은 둘레를 계산하는 행위를 한다.요컨대, 만약 요구가 있다면, 모든 형태의 둘레는 — 다태적인 용례를 가지고 인터페이스를 가지면 더욱 의미가 있을 것이다. 아래와 같다.
    **interface**  **Shape**  **{**
            Double **perimeter();**
     **}**
    
    **class**  **Rectangle**  **implements** Shape **{**
    _//data members and constructors_  
        @Override
        **public** Double **perimeter()**  **{**
            **return** 2 **\*** **(this.**length **+**  **this.** breadth**);**
        **}**
     **}**
    
    **class**  **Circle**  **implements** Shape **{**
    _//data members and constructors_  
        @Override
        **public** Double **perimeter()**  **{**
            **return** 2 **\*** Math **.** PI **\*** **(this.**radius**);**
        **}**
     **}**
    
    **public**  **double** **totalPerimeter(**List **<** Shape **>** shapes**)**  **{**
        **return** shapes **.** stream**()**
                   **.** map**(**Shape **::** perimeter**)**
                   **.** reduce**((**a **,** b**)**  **->** Double **.** sum**(**a **,** b**))**
                   **.** orElseGet**(()**  **->** **(double)** 0**);**
     **}**
    

    블로거 10. 다시 쓰는 것은 해시 코드를 다시 쓰는 것과 같다


    그 값에 따라 같은 대상을 이라고 한다.e. 돈, 시간.값이 같으면, 이 클래스는true를 되돌려 주기 위해 equals 방법을 다시 써야 합니다.기타 라이브러리는 보통 value objects 방법으로 비교와 상등성 검사를 한다.따라서 평등을 압도할 필요가 있다.각 Java 객체에는 다른 객체와 구분되는 해시 코드 값이 있습니다.
    **class**  **Coin**  **{**
        **private**  **final**  **int** value **;**
    
        Coin**(int** value**)**  **{**
            **this.** value **=** value **;**
        **}**
    
        @Override
        **public**  **boolean** **equals(**Object o**)**  **{**
            **if** **(this**  **==** o**)**  **return**  **true;**
            **if** **(**o **==**  **null**  **||** getClass**()**  **!=** o **.** getClass**())**  **return**  **false;**
            Coin coin **=** **(**Coin**)** o **;**
            **return** value **==** coin **.** value **;**
        **}**
     **}**
    
    위의 예에서는 Object의 equals 방법만 덮어썼습니다.
    HashMap **<** Coin **,** Integer **>** coinCount **=**  **new** HashMap **<** Coin **,** Integer**>()**  **{{**
      put**(new** Coin**(**1**),** 5**);**
      put**(new** Coin**(**5**),** 2**);**
     **}};**
    
    _//update count for 1 rupee coin_  
    coinCount **.** put**(new** Coin**(**1**),** 7**);**
    
    coinCount **.** size**();** _// 3 🤯 why?_
    
    우리는 코인카운트가 1루피 동전의 수량을 7로 갱신하기를 희망한다. 왜냐하면 우리는 같은 것을 소홀히 했기 때문이다.그러나 equals은 내부에서 두 대상의 해시 코드가 동일한지 확인한 후에야 equals 방법을 통해 계속 동일성을 테스트했다.두 개의 서로 다른 대상은 같은 해시 코드를 가지거나 가지지 않을 수 있지만, 두 개의 같은 대상은 항상 같은 해시 코드를 가져야 한다. 예를 들어 해시 코드 방법의 계약에 의해 정의된 바와 같다.따라서 우선 해시 코드를 검사하는 것이 조기 퇴출 조건이다.이것은 equals와hashCode 방법을 다시 써서 똑같이 표시해야 한다는 것을 의미한다.
    자바 코드를 작성하거나 볼 때, DeepSource는 HashMap을 처리하고 많은 시간을 절약할 수 있습니다.하나만 추가하면deepsource.toml 파일은 저장소의 루트 디렉토리에 있으며 DeepSource는 즉시 해당 파일을 추출하여 검색합니다.스캔을 하면 코드의 개선 범위를 발견하고, 유용한 설명을 통해 이 문제들을 복구할 수 있습니다.
    automating the code reviews, 직접 보세요!
    최초로 Sign up에 발표되었다.

    좋은 웹페이지 즐겨찾기