Java 코딩 우수 사례에 대한 간단한 요약

Oracle, Google, Twitter 및 Spring Framework의 코딩 표준 기반

이 기사의 목적은 Oracle, Google, Twitter 및 Spring Framework와 같은 기술 거인의 코딩 표준을 기반으로 선호하는 것과하지 말아야 할 것의 빠른 요약을 제공하는 것입니다.

여기에 제시된 모범 사례 중 일부에 동의 할 수도 있고 동의하지 않을 수도 있으며, 일부 코딩 표준이있는 한 절대적으로 좋습니다.

코딩 표준이 처음 인 이유는 무엇입니까? Google을 사용하면 많은 이유가 있으며 다음 그림을 남겨 드리겠습니다.

코딩 표준 문서는 길고 지루할 수 있습니다. 이 기사 cherry는 Google, Oracle, Twitter 및 Spring의 코딩 규칙에서 비트와 조각을 선택하며, 코드를 쉽게 읽고 유지 관리 할 수 ​​있도록 따라하기 쉽고 지루하지 않은 관행을 제공하는 것을 목표로합니다.

거의 항상 기존 소프트웨어로 작업하는 팀에 합류 할 것이며 대부분의 저자가 다른 프로젝트로 떠나거나 다른 프로젝트로 전환했을 가능성이 매우 높습니다.

다양한 코딩 표준의 모범 사례를 살펴 보겠습니다.

자바 소스 파일

다음은 Java 소스 파일과 관련하여 모범 사례로 간주됩니다.

  • 소스 파일 길이가 2,000 줄 미만의 코드
  • 소스 파일은 아래와 같이 문서 주석, 패키지 선언, 클래스 주석, 그룹화 (정적 마지막), 클래스 / 인터페이스 서명 등으로 구성됩니다.
패키지 com.example.model;
/ **
 개발자가 읽을 수있는 구현이 필요없는 관점
 * 반드시 소스 코드를 가지고 있지 않은 사람
 *
 * @ 저자 x, y, z
 * @데이트
 * @ 버전
 * @저작권
 *
 * /
import com.example.util.FileUtil;
/ *
 * 선택적 수업 별 설명
 *
 * /
공개 클래스 SomeClass {
  // 가시성 순서의 정적 변수
  공개 정적 최종 정수 PUBLIC_COUNT = 1;
  정적 최종 정수 PROTECTED_COUNT = 1;
  개인 정적 최종 정수 PRIVATE_COUNT = 1;
  // 가시성 순서에 따른 인스턴스 변수
  공개 문자열 이름;
  문자열 우편 번호;
  개인 문자열 주소;
  // 생성자 및 순서대로 오버로드
  공개 SomeClass () {}
  공개 SomeClass (문자열 이름) {
    this.name = 이름;
  }
  // 메소드
  공개 문자열 doSomethingUseful () {
    "유용한 것"을 반환;
  }
  // 끝에 getter, setter, equals, hashCode 및 toString
}

명명

클래스 및 인터페이스 이름은 CamelCase이며 전체 단어를 사용하고 약어 / 약어를 사용하지 않는 것이 좋습니다. 예를 들어 클래스 Raster 또는 클래스 ImageSprite

  • 패키지 — com.deepspace 또는 com.deep_space에서 com.deepspace로 이름을 지정합니다.
  • 파일 — 이름은 CamelCase이며 클래스 이름과 일치하는 .java로 끝납니다. 파일에 각 최상위 클래스가있는 파일 당 하나의 공개 클래스가 있습니다.
  • 메서드 — 이름은 대문자로 된 각 내부 단어와 함께 대소 문자가 혼합 된 동사 여야합니다 (예 : run ()). 또는 runFast ();
  • 상수 — 각 단어를 구분하는 "_"가있는 대문자 여야합니다 (예 : int MIN_WIDTH = 44). int MAX_WIDTH = 99;
  • 변수 — 프로그램의 독자에게 변수가 무엇을 나타내는 지 알려주는 이름입니다 (예 : 테스트 등급을 저장하는 경우 등급 대 var1 선택). 메타 데이터를 포함하지 않도록 변수 이름을 짧게 유지하십시오.
// 선호 ()-변수 이름이 짧고 저장 내용을 설명
int schoolId;
int [] filteredSchoolIds;
int [] uniqueSchooldIds;
맵 <정수, 사용자> usersById;
문자열 값;
// Avoid (x)-너무 상세한 변수 명명
int schoolIdentificationNumber;
int [] userProvidedSchoolIds;
int [] schoolIdsAfterRemovingDuplicates;
맵 <정수, 사용자> idToUserMap;
문자열 값 문자열;

기억하십시오 — 변수 이름은 짧아야하며 독자에게 그것이 나타내는 값을 쉽게 알려 주어야합니다. 당신의 판단을 사용하십시오.

선호 및 회피

형식화 및 들여 쓰기는 코드를 쉽게 읽을 수 있도록 구성하는 것입니다. 간격, 줄 길이, 줄 바꿈 및 나누기 등이 포함됩니다.

  • 들여 쓰기 — 2 ~ 4 개의 공백을 사용하고 일관성을 유지합니다
  • 줄 길이 — 가독성에 따라 최대 70 ~ 120 자입니다. 쉼표와 연산자 뒤에 가로 스크롤 및 줄 바꿈이 필요하지 않아야합니다.

방법 — 모범 사례 목록은 다음과 같습니다.

// 선호 () 줄 바꿈은 임의적이며 쉼표 뒤에 나옵니다.
인터넷 (인터넷 인터넷, 튜브 튜브,
    Blogosphere 블로그, Amount  bandwidth) {
  tubes.download (인터넷);
}
// (x) 메서드 인수를 메서드 본문에 다른 방식으로 비교하기 어려움
인터넷 (인터넷 인터넷, 튜브 튜브,
    Blogosphere 블로그, Amount  bandwidth) {
    tubes.download (인터넷);
}
// 선호 들여 쓰기를 위해 () 8 (2 또는 2의 2 배) 간격을 추가하십시오
개인 정적 동기화 horkingLongMethodName (int anArg,
        anotherArg, String yetAnotherArg 객체,
        객체 및 기타) {
  ...
}
// 간편한 스캔 및 추가 열 공간을 선호합니다 ().
공개 문자열 다운로드
    인터넷 인터넷,
    튜브 튜브,
    Blogosphere 블로그,
    <길이, 데이터> 대역폭) {
  tubes.download (인터넷);
  ...
}
단위 테스트는 을 잡았을 것입니다.

If-checks — 올바른 형식의 코드를 작성하는 IMO를 사용하면 작성자와 코드 검토 자에게 오타 및 오류를 쉽게 발견 할 수 있습니다 (아래 참조).

// 피하십시오 (x) {} 생략하지 마십시오
만약에 (조건)
  성명서;
// 피하십시오 (x)
(x <0)이면 음 (x);
// 피하십시오 (x)
if (a == b && c == d) {
...
}
// 선호 ()
if ((a == b) && (c == d)) {
...
}
// 선호 ()
if (조건) {
  진술;
} else if (조건) {
  진술;
} else if (조건) {
  진술;
}
// 피하십시오 (x)
if ((조건 1 && 조건 2)
    || (조건 3 및 조건 4)
    ||! (condition5 && condition6)) {// BAD 랩
    어떻게 좀 해 봐(); //이 라인을 쉽게 만들 수 있습니다.
}
// 선호 ()
if ((조건 1 && 조건 2)
        || (조건 3 및 조건 4)
        ||! (조건 5 && 6)) {
    어떻게 좀 해 봐();
}

삼항 연산자 — 아래는 권장 사례입니다

알파 = (aLongBooleanExpression)? 베타 : 감마;
알파 = (aLongBooleanExpression)? 베타
        : 감마;
알파 = (aLongBooleanExpression)
        ? 베타
        : 감마;

전환 — 전환 할 때는 다음을 수행하는 것이 가장 좋습니다.

  • 코드가 없어도 항상 기본 사례가 있습니다.
  • / *를 사용하여 * /를 통해 제어가 다음 경우에 해당함을 나타냅니다.
스위치 (조건) {
  사례 ABC :
    진술;
  / *는 * /를 통과합니다.
  사건 방어 :
    진술;
    단절;
  기본:
    진술;
     단절;
}

예외 메시지 — 예외를 던질 때 들여 쓰기가 잘된 메시지의 샘플이 있습니다.

// 피하기 (x)-읽기 쉽지 않음
새로운 IllegalStateException 발생 ( "요청을 처리하지 못했습니다"+ request.getId ()
    + "사용자의 경우"+ user.getId () + "query : '"+ query.getText ()
    + " '");
// 선호 ()-읽기 쉬운 편
새로운 IllegalStateException 발생 ( "처리 실패")
    + "request"+ request.getId ()
    + "사용자의 경우"+ user.getId ()
    + "쿼리 : '"+ query.getText () + "'");

반복자와 스트림 — 스트림이 점점 보편화되고 때로는 매우 복잡 할 수 있으므로 읽기 쉽게 들여 쓰기하는 것이 중요합니다.

// 피하기 (x)-읽기 쉽지 않음
Iterable  modules = ImmutableList.  builder (). add (new LifecycleModule ())
    .add (new AppLauncherModule ()). addAll (application.getModules ()). build ();
// 선호 ()-읽기 쉬운 편
Iterable  모듈 = ImmutableList.  builder ()
    .add (new LifecycleModule ())
    .add (new AppLauncherModule ())
    .addAll (application.getModules ())
    .짓다();
코딩 표준을 따르십시오.

선언과 과제 — 한 줄에 하나씩 선언하는 것이 좋으며, 아래 그림과 같이 주석이 권장됩니다.

// 선호 ()
int 레벨; // 들여 쓰기 수준
int sizeMeter; // 테이블 크기
// 위의 (x)를 피하십시오
int 레벨, sizeMeter;
// 선호 ()-변수 이름 또는 유형에 단위 포함
긴 pollIntervalMs;
int fileSizeGb;
양 <정수, 데이터> fileSize;
// (x) 혼합 유형을 피하십시오
int foo, fooarray [];
// 피하십시오 (x)-쉼표로 구분하지 마십시오
Format.print (System.out,“error”), exit (1);
// (x) 다중 할당 방지
fooBar.fChar = barFoo.lchar = 'c';
// 성능을 높이거나 줄을 저장하려는 경우 (x) 내장 된 할당을 피하십시오. 나는 이것을 저지른 죄이다.
d = (a = b + c) + r;
// 위의 () 선호
a = b + c;
d = a + r;
// 선호 ()
문자열 [] 인수
// 피하십시오 (x)
문자열 인수 []
// 1과 혼동을 피하기 위해 "l"대신 "L"을 오래 사용하십시오 ().
긴 타임 아웃 = 3000000000L;
// 피하기 (x)-마지막 글자는 l이 아니라 1
긴 타임 아웃 = 3000000000l;

블록의 시작 부분에만 선언을하십시오 (블록은 중괄호 {와}로 묶인 코드입니다). 변수를 처음 사용할 때까지 선언하지 마십시오. 범위 내에서 경고하지 않은 프로그래머와 혼동 코드 이식성을 혼동시킬 수 있습니다.

// 블록의 시작 부분에 () 선언을 선호하십시오.
공공 무효 doSomething () {
  무엇을 나타내는가; // 메소드 블록의 시작
  if (조건) {
    int someFlag; //“if”블록의 시작
    …
  }
}

또한 상위 수준의 선언을 숨기는 로컬 선언을 피하고 아래에 표시된대로 혼동을 피하는 것이 중요합니다

정수 카운트;
...
공공 무효 doSomething () {
  if (조건) {
    정수 카운트; // 피하십시오!
    ...
  }
  ...
}

간격 및 줄 바꿈 — 가독성을 희생하면서 1-2 줄의 코드를 저장하려는 유혹을 피하십시오. 간격과 빈 줄에 관한 모든 모범 사례는 다음과 같습니다 (공백은 차이를 만듭니다).

  • 메소드와 Spring 개발자 사이의 빈 줄 하나는 생성자, 정적 블록, 필드 및 내부 클래스 다음에 빈 줄 두 개를 권장합니다.
  • 스페이스 패드 연산자, 즉 int foo = a + b + 1; int foo = a + b + 1 이상;
  • 공백을 사용하여 피연산자와“.”을 제외한 모든 이진 연산자를 분리하십시오.
  • 여는 중괄호 "{"는 선언문 또는 메소드와 동일한 행 끝에 표시되며 닫는 중괄호 "}"은 들여 쓰기로 행을 시작합니다.
// 선호 ()- "while"다음과 "("앞의 공백
while (true) {
  ...
}
// 피하세요 (x)-위와 달리 공백이 없습니다
while (true) {
  ...
}
// 선호 ()- "doSomething"과 "("사이에 공백이 없음
공공 무효 doSomething () {
  ...
}
// 피하세요 (x)-위의 공간과 달리
공공 무효 doSomething () {
  ...
}
// 선호 ()-인수 뒤에 공백을 추가합니다
공공 무효 doSomething (int a, int b) {
  ...
}
// 선호 ()-피연산자와 연산자 사이의 간격 (예 : +, =)
a + = c + d;
a = (a + b) / (c * d);
while (d ++ = s ++) {
  n ++;
}

설명서 및 의견

거의 모든 코드가 수명 기간 동안 변경되며, 명확하게 기술되지 않는 한 복잡한 코드 블록, 메서드 또는 클래스의 의도를 파악하려고 할 때가있을 수 있습니다. 현실은 거의 항상 다음과 같습니다

복잡한 코드, 메소드, 클래스에 대한 주석이 가치를 추가하거나 그 목적을 달성하지 못하는 경우가 있습니다. 이것은 일반적으로 그것을 위해 논평 할 때 발생합니다.

주석은 코드 개요를 제공하고 코드 자체에서 쉽게 사용할 수없는 추가 정보를 제공하는 데 사용해야합니다. 시작하자. 주석에는 두 가지 유형이 있습니다

구현 설명 — 코드를 주석 처리하거나 특정 코드 구현에 대해 설명합니다.

문서 주석 — 구현할 필요가없는 관점에서 코드를 지정하여 소스 코드를 가지고 있지 않아도되는 개발자가 읽을 수 있습니다.

주석의 빈도는 때때로 품질이 좋지 않은 코드를 반영합니다. 주석을 추가해야한다고 생각되면 코드를 다시 작성하여 명확하게 만드십시오.

구현 의견 유형

다음과 같이 네 가지 유형의 구현 설명이 있습니다.

  • 주석 차단 — 아래 예 참조
  • 한 줄 주석 — 주석이 줄보다 길지 않은 경우
  • 후행 주석 — 매우 짧은 주석이 오른쪽 끝으로 이동
  • 줄 끝 주석 — 줄 바꿈으로 계속되는 주석을 시작합니다. 완전한 라인 또는 부분 라인 만 주석 처리 할 수 ​​있습니다. 텍스트 주석을 위해 연속 여러 줄에 사용해서는 안됩니다. 그러나 코드 섹션을 주석 처리하기 위해 여러 줄로 연속해서 사용할 수 있습니다.
// 댓글 차단
/ *
 * 사용법 : 파일, 메소드, 데이터 구조에 대한 설명 제공
 * 및 알고리즘. 각 파일의 시작 부분에서 사용할 수 있으며
 * 각 방법 전에. 맞지 않는 긴 주석에 사용
 * 하나의 선. 1 빈 줄은 블록 주석 다음에 진행합니다.
 * /
// 한 줄 주석
if (조건) {
 / * 조건을 처리하십시오. * /
  ...
}
// 후행 주석
if (a == 2) {
 TRUE를 반환; /* 특별한 경우 */
} else {
 return isPrime (a); / *는 홀수에 대해서만 작동합니다 * /
}
// 줄 끝 주석
if (foo> 1) {
  // 더블 플립을합니다.
  ...
} else {
  거짓을 반환; // 여기에 이유를 설명하십시오.
}
// if (바> 1) {
//
// // 트리플 플립을합니다.
// ...
//}
//그밖에
// false를 반환합니다.

설명서 의견 (예 : Javadoc)

Javadoc은 / **로 시작하고 * /로 끝나는 주석을 사용하여 Java 코드에서 HTML 문서를 생성하는 도구입니다. Javadoc의 작동 방식 또는 읽기 방식에 대한 자세한 내용은 Wikipedia를 참조하십시오.

다음은 Javadoc의 예입니다

/ **
 * 화면에 칠할 수있는 Image 객체를 반환합니다.
 * url 인수는 절대 {@link URL}을 지정해야합니다. 이름
 * argument는 url 인수와 관련된 지정자입니다.
 * 

 *이 메소드는 항상  * 이미지가 존재합니다. 이 애플릿이 이미지를 그리려고 할 때  * 화면에 데이터가로드됩니다. 그래픽 프리미티브  * 이미지를 그리는 화면에 점차적으로 페인트됩니다.  *  * @param url은 이미지의 기본 위치를 제공하는 절대 URL입니다.  * @param name url 인수를 기준으로 이미지의 위치  * @ 지정된 URL에서 이미지를 반환  * @ 이미지 참조  * /  공개 이미지 getImage (URL URL, 문자열 이름) {         {             get getImage (새 URL (url, 이름));         } catch (MalformedURLException e) {             null을 돌려줍니다.         }  }

그리고 위의 코드에 대해 javadoc이 실행될 때 위와 같이 HTML이 생성됩니다.

자세한 내용은 여기를 참조하십시오

생성 된 Java 문서의 품질을 향상시키는 데 사용할 수있는 주요 태그는 다음과 같습니다.

@author => @ 저자 Raf
@code => {@code A  C}
@deprecated => @deprecated 지원 중단 메시지
@exception => @exception IOException 발생시
@link => {@link package.class # member 레이블}
@param => @param 매개 변수 이름 설명
@return => 메소드가 리턴하는 것
@see => @ "문자열"참조 또는 @   참조
@since => 공개적으로 접근 가능한 메소드가 추가 될 때 버전을 표시

전체 목록과 자세한 설명은 여기를 참조하십시오

트위터의 코딩 표준은 @author 태그 사용을 금지합니다

코드는 수명주기 동안 여러 번 손을 바꿀 수 있으며 소스 파일의 원래 작성자는 여러 번 반복 한 후 관련이 없습니다. 커밋 히스토리와 OWNERS 파일을 신뢰하여 코드의 소유권을 결정하는 것이 좋습니다.

다음은 Twitter의 코딩 표준에 설명 된대로 통찰력있는 문서 주석을 작성하는 방법에 대한 예입니다.

// 나쁘다.
//-문서는 메소드 선언이하지 않았다고 아무 것도 말하지 않습니다.
//-이것은 '필러 문서'입니다. 스타일 검사를 통과하지만
아무도 도와주지 않습니다.
/ **
 * 문자열을 나눕니다.
 *
 * @param s 문자열.
 * @return 문자열 목록.
 * /
List  split (String s);
// 더 낫다.
//-우리는 그 방법이 어떻게 분리되는지 알고있다
//-여전히 정의되지 않은 동작입니다.
/ **
 * 공백에서 문자열을 분할합니다.
 *
 * @param s 분할 할 문자열입니다. {@code null} 문자열은 빈 문자열로 취급됩니다.
 * @return 입력으로 공백으로 구분 된 부분의 목록입니다.
 * /
List  split (String s);
// 좋아.
//-또 다른 엣지 케이스를 다룹니다.
/ **
 * 공백에서 문자열을 분할합니다. 반복되는 공백 문자
 * 축소됩니다.
 *
 * @param s 분할 할 문자열입니다. {@code null} 문자열은 빈 문자열로 취급됩니다.
 * @return 입력으로 공백으로 구분 된 부분의 목록입니다.
 * /
List  split (String s);

의견을 쓸 때 전문가가되는 것이 중요합니다

// 피하십시오 (x)
// xml / soap가 너무 싫어서 왜 그렇게 할 수 없습니까!?
{
  userId = Integer.parseInt (xml.getField ( "id"));
} catch (NumberFormatException e) {
  ...
}
// 선호 ()
// TODO (Jim) : 라이브러리에서 필드 유효성 검사를 제거합니다.
{
  userId = Integer.parseInt (xml.getField ( "id"));
} catch (NumberFormatException e) {
  ...
}

그리고 구현이 변경되지 않는 한 재정의 된 메소드를 문서화하지 않도록 명심해야합니다.

명심해야 할 몇 가지 사항이 있습니다.

  • 트위터의 코딩 표준에 설명 된대로 와일드 카드 가져 오기를 피하십시오. 클래스의 소스가 덜 명확 해집니다. Eclipse와 IntelliJ 사용자가 혼합 된 팀에서 일하고 Eclipse가 와일드 카드 가져 오기를 제거하고 IntelliJ가 소개한다는 것을 알았습니다. 이 기능을 끄는 옵션이있을 수 있습니다. 둘의 기본값을 지정하고 싶을뿐입니다.
  • 재정의 할 때는 항상 @Override 주석을 사용하십시오.
  • 필드 또는 메서드가 null을 반환 할 때 @Nullable을 사용하도록 권장
  • 미래의 작업에 특별한 설명을 사용하고 다른 사람들이 자신의 Y 질문을 추측, 제거 또는 자식 비난을 확인하는 대신 누가 자신의 Y 질문을해야하는지 아는 것을 잊지 마십시오. Eclipse 및 IntelliJ와 같은 일부 IDE는 알림과 함께 쉽게 액세스 할 수 있도록 목록을 표시하는 데 도움이됩니다.
// FIXME (Raf) : 수행 가능한 메시지를 설명하는 실행 가능한 메시지
// TODO (Raf) : 수행 할 수있는 작업을 설명하는 실행 가능한 메시지

최종 게임은 미래의 저자와 관리자의 삶을 쉽게 만드는 코드를 작성하는 것입니다.

최종 게임

기타 관련 자료

깨끗하고 체계적이며 읽기 쉽고 유지 보수가 쉬운 코드 작성과 관련된 관련 기사 목록. 자세한 내용을 읽으려면 다음을 확실히 권장하십시오.

깨끗한 코드 작성을위한 유용한 팁 목록