본문 바로가기
우아한테크코스

프리코스 준비과정 - 자바 컨벤션 코드

by 임동무 2022. 10. 27.

지금까지 공부하면서 사용해왔던 자바는 내가 보기 편한 코드 규칙으로 작성되어 왔다.

우아한테크코스에 지원하고 프리코스를 준비하던 중 자바 컨벤션을 지켜 코드를 작성하라는 문구를 보고 자바 컨벤션 코드에 대해서 접하게 되었다. 

 

1. 자바 컨벤션이란

자바 컨벤션은 자바를 사용하는 프로그래머들의 코딩 컨벤션, 즉 코딩하는데 있어서 규칙을 의미한다.

https://google.github.io/styleguide/javaguide.html

 

Google Java Style Guide

1 Introduction This document serves as the complete definition of Google's coding standards for source code in the Java™ Programming Language. A Java source file is described as being in Google Style if and only if it adheres to the rules herein. Like ot

google.github.io

위 문서는 구글에서 지원하는 문서로 구글이 자바를 사용하는 스타일에 대한 가이드이며 이 문서를 바탕으로 자바 컨벤션을 익혔다.

(번역본을 보면 생각보다 해석이 잘 되어 있지만 애매한 문장이 있어 영어 그대로 읽는 것이 더 이해가 잘 된다.)

이 글은 이 문서를 번역하면서 공부한 자바 컨벤션에 관련된 내용이다.

 

들어가기 전에

1. class 는 class, enum, interface, annotation type 을 모두 포함한다.
2. member 는 nested class, field, method, constructor 를 의미한다.
3. 주석은 구현주석만을 의미한다. 이 문서에서 문서화주석은 다루지 않으며 대신에 "Javadoc" 에서 다룬다.

The term class is used inclusively to mean an "ordinary" class, enum class, interface or annotation type (@interface).

The term member (of a class) is used inclusively to mean a nested class, field, method, or constructor; that is, all top-level contents of a class except initializers and comments.

The term comment always refers to implementation comments. We do not use the phrase "documentation comments", and instead use the common term "Javadoc."

 

 

2 Source file basics

2.1 File name - 파일 명

파일 명은 하나뿐인 최상위 클래스 + .java 확장자로 구성된다.

The source file name consists of the case-sensitive name of the top-level class it contains (of which there is exactly one), plus the .java extension.

 

2.2 File encoding: UTF-8

소스 파일은 UTF -8 로 인코딩 된다.

Source files are encoded in UTF-8.

 

2.3 Special characters

 

2.3.1 Whitespace characters - 공백문자

line 이 끝나는 즉, 개행문자를 제외하고 ASCII 의 공백문자는 (0X20) 이 유일하다. 이것은

1. 모든 문자열과 문자 리터럴에서 공백문자는 이스케이프 된다.

2. 탭 문자는 들여쓰기에서 허용되지 않는다. 

Aside from the line terminator sequence, the ASCII horizontal space character (0x20) is the only whitespace character that appears anywhere in a source file. This implies that:
1. All other whitespace characters in string and character literals are escaped.
2. Tab characters are not used for indentation.

 

2.3.2 Special escape sequences

\b, \t, \n, \f, \r, \", \', \\ 은 이스케이프 되는 특수문자로 octal 나 유니코드 방식보다는 그대로 사용된다.

For any character that has a special escape sequence (\b, \t, \n, \f, \r, \", \' and \\), that sequence is used rather than the corresponding octal (e.g. \012) or Unicode (e.g. \u000a) escape.

 

2.3.3 Non-ASCII characters

ASCII 에 포함되지 않은 문자는 실제 유니코드 문자나 유니코드 이스케이프가 사용된다.

선택은 오직 코드를 읽고 이해하기 쉽게 만드는 데에 달려있으며

일부 프로그램이 ASCII에 포함되지 않은 문자를 적절하게 다루지 못한다는 것 때문에 코드의 가독성을 낮추면 안된다. 

For the remaining non-ASCII characters, either the actual Unicode character (e.g. ∞) or the equivalent Unicode escape (e.g. \u221e) is used. The choice depends only on which makes the code easier to read and understand, although Unicode escapes outside string literals and comments are strongly discouraged.
Tip: In the Unicode escape case, and occasionally even when actual Unicode characters are used, an explanatory comment can be very helpful.
Examples:
ExampleDiscussion
String unitAbbrev = "μs"; Best: perfectly clear even without a comment.
String unitAbbrev = "\u03bcs"; // "μs" Allowed, but there's no reason to do this.
String unitAbbrev = "\u03bcs"; // Greek letter mu, "s" Allowed, but awkward and prone to mistakes.
String unitAbbrev = "\u03bcs"; Poor: the reader has no idea what this is.
return '\ufeff' + content; // byte order mark Good: use escapes for non-printable characters, and comment if necessary.

Tip: Never make your code less readable simply out of fear that some programs might not handle non-ASCII characters properly. If that should happen, those programs are broken and they must be fixed.

3 Source file structure - 소스파일의 구성

아래의 순서로 파일이 구성되어야 하며, 존재하는 각각의 섹션은 개행문자로 구분한다.

1. 존재한다면 License 와 저작권 정보

2. Package 

3. Import

4. 최상위 클래스 이름

A source file consists of, in order:
1. License or copyright information, if present
2. Package statement
3. Import statements
4. Exactly one top-level class

Exactly one blank line separates each section that is present.

 

3.1 License or copyright information, if present

License 와 저작권 정보가 존재한다면 최상단에 적어준다.

If license or copyright information belongs in a file, it belongs here.

3.2 Package statement

패키지 문은 개행하지 않으며, 열 제한이 적용되지 않는다.

The package statement is not line-wrapped. The column limit (Section 4.4, Column limit: 100) does not apply to package statements.

3.3 Import statements - Import 문

3.3.1 No wildcard imports

와일드카드 방식으로 가져오지 않는다. ex) import java.util.*;

와일드카드로 가져온 두개의 import 된 패키지에 동일한 이름의 method 가 선언되어 있는 경우 이를 명시해주지 않으면 컴파일 오류를 일으킨다. 그러니 와일드카드 방식으로 import 문을 사용하지 않는다.  

Wildcard imports, static or otherwise, are not used.

 

3.3.2 No line-wrapping

import 문 역시 개행하지 않는다. 열 제한 역시 적용되지 않는다.

Import statements are not line-wrapped. The column limit (Section 4.4, Column limit: 100) does not apply to import statements.

 

3.3.3 Ordering and spacing

순서와 위치

Import 문들은 아래의 순서를 따른다.

1. 모든 static import가 포함된 하나의 블록

2. 모든 non-static import가 포함된 하나의 블록

 

만약 static 과 non-static 패키지 가 모두 import 되어있는 경우, 한 줄의 개행으로 이 둘을 분리하며 모든 import 문들 사이의 개행문자는 이 한 줄의 개행밖에 존재하지 않는다. 각 블록 내에서 가져온 이름은 ASCII 정렬 순서로 나타낸다. 

( 참고: '.'가 ';'보다 먼저 정렬되기 때문에 이것은 ASCII 정렬 순서에 있는 import 문과 동일하지 않다 .)

Imports are ordered as follows:
1. All static imports in a single block.
2. All non-static imports in a single block.
If there are both static and non-static imports, a single blank line separates the two blocks. There are no other blank lines between import statements.
Within each block the imported names appear in ASCII sort order. (Note: this is not the same as the import statements being in ASCII sort order, since '.' sorts before ';'.)

 

3.3.4 No static import for classes

nested classes를 위해 static import 를 사용하지 않는다. 이들은 최상위 클래스에 위해 import 된다.

Static import is not used for static nested classes. They are imported with normal imports.

 

3.4 Class declaration

3.4.1 Exactly one top-level class declaration

각 최상위 클래스는 자체 소스파일을 가지고 있다.

Each top-level class resides in a source file of its own.

 

3.4.2 Ordering of class contents

클래스 멤버와 생성자에 정해진 순서는 없다. 다만, 이 순서는 어떠한 논리적인 순서를 가지고 있어야 한다.

가령, 새로 추가하는 메소드를 가장 아래다 정의하는 '시간적 순서' 에 의한 배열은 논리적인 순서를 가지고 있지 않는다. 

또한 Overload 된 동일한 이름을 지니는 멤버는 분리되어 있으면 안된다. (ex. 항상 동일한 이름을 같는 여러개의 생성자 )

The order you choose for the members and initializers of your class can have a great effect on learnability. However, there's no single correct recipe for how to do it; different classes may order their contents in different ways.
What is important is that each class uses some logical order, which its maintainer could explain if asked. For example, new methods are not just habitually added to the end of the class, as that would yield "chronological by date added" ordering, which is not a logical ordering.
3.4.2.1 Overloads: never split
Methods of a class that share the same name appear in a single contiguous group with no other members in between. The same applies to multiple constructors (which always have the same name). This rule applies even when modifiers such as static or private differ between the methods.

 

4 Formatting

 

Terminology Note: block-like construct refers to the body of a class, method or constructor. Note that, by Section 4.8.3.1 on array initializers, any array initializer may optionally be treated as if it were a block-like construct.

4.1 Braces

4.1.1 Use of optional braces

if, else, for, do, while 문과 함께 사용되는 중괄호는 바디가 비어있거나 단 하나의 statement 만 포함하는 경우에도 생략되면 안된다.

람다 표현식과 같은 중괄호는 선택 사항이다.

Braces are used with if, else, for, do and while statements, even when the body is empty or contains only a single statement.
Other optional braces, such as those in a lambda expression, remain optional.

 

4.1.2 Nonempty blocks: K & R style

중괄호는 다음과 같은 규칙을 따른다.

1. 하단에 자세하게 설명된 내용 외의 중괄호를 열기 전에는 개행하지 않는다.

2. 중괄호를 열고 난 후에는 개행한다.

3. 중괄호를 닫기 전에는 개행한다.

4. 중괄호를 닫은 후에 구문이 종료되거나, 메소드의 바디, 생성자, 구체화 클리스 등이 종결되는 상황에서만 개행한다. if 이후에 else 문이나오는 경우나 콤마(,)가 나오는 경우에는 중괄호를 닫은 후에 개행하지 않는다.

Braces follow the Kernighan and Ritchie style ("Egyptian brackets") for nonempty blocks and block-like constructs:

  • No line break before the opening brace, except as detailed below.
  • Line break after the opening brace.
  • Line break before the closing brace.
  • Line break after the closing brace, only if that brace terminates a statement or terminates the body of a method, constructor, or named class. For example, there is no line break after the brace if it is followed by else or a comma.

Exception: In places where these rules allow a single statement ending with a semicolon (;), a block of statements can appear, and the opening brace of this block is preceded by a line break. Blocks like these are typically introduced to limit the scope of local variables, for example inside switch statements.

Examples:

return () -> {
  while (condition()) {
    method();
  }
};

return new MyClass() {
  @Override public void method() {
    if (condition()) {
      try {
        something();
      } catch (ProblemException e) {
        recover();
      }
    } else if (otherCondition()) {
      somethingElse();
    } else {
      lastThing();
    }
    {
      int x = foo();
      frob(x);
    }
  }
};

A few exceptions for enum classes are given in Section 4.8.1, Enum classes.

 

4.1.3 Empty blocks: may be concise

빈 블록에서 중괄호는 개행은 선택사항이다. 개행을 해도 되고 하지 않아도 된다. 다만,  try~catch 문이나 if~else 문 같은 멀티블록 상황에서는 개행을 해야만 한다.

An empty block or block-like construct may be in K & R style (as described in Section 4.1.2). Alternatively, it may be closed immediately after it is opened, with no characters or line break in between ({}), unless it is part of a multi-block statement (one that directly contains multiple blocks: if/else or try/catch/finally).

Examples:

  // This is acceptable
  void doNothing() {}

  // This is equally acceptable
  void doNothingElse() {
  }
  // This is not acceptable: No concise empty blocks in a multi-block statement
  try {
    doSomething();
  } catch (Exception e) {}

 

4.2 Block indentation: +2 spaces

매 새로운 블록 혹은 블록 형태의 구조가 열릴 때마다, 두 개의 공백이 추가된다. 블록이 끝나면, 들여쓰기 level 은 이 전의 들여쓰기 level로 변한다. 즉 다시 공백문자 2개가 제거된다. 이 들여쓰기 level 은 코드와 주석에 모두 적용된다. 

Each time a new block or block-like construct is opened, the indent increases by two spaces. When the block ends, the indent returns to the previous indent level. The indent level applies to both code and comments throughout the block. (See the example in Section 4.1.2, Nonempty blocks: K & R Style.)

 

4.3 One statement per line

하나의 줄에는 하나의 구문만 존재한다.

Each statement is followed by a line break.

 

4.4 Column limit: 100

자바의 코드는 한 줄에 100개의 문자 제한을 가진다. 이 "문자" 의 의미는 유니코드 포인트를 의미하며, 하단에 정리된 예외를 제외하는 모든 줄은 줄 바꿈 규칙을 준수해야 한다. 

예외

1. Javadoc의 URL 이나 긴 JSNI 메소드 참조 처럼 열 제한을 지키는 것이 불가능한 경우

2. Package 나 improt 문

3. 주석 내의 쉘에 붙여넣을 수 있는 내용

4. 매우 긴 식별자의 경우 거의 호출되지 않지만, 열 제한을 초과할 수 있다. 이 경우 이를 둘러싼 주변 코드를 위한  wrapping 은 google-java-format 을 참조하자.

Java code has a column limit of 100 characters. A "character" means any Unicode code point. Except as noted below, any line that would exceed this limit must be line-wrapped, as explained in Section 4.5, Line-wrapping.

Each Unicode code point counts as one character, even if its display width is greater or less. For example, if using fullwidth characters, you may choose to wrap the line earlier than where this rule strictly requires.
Exceptions:
1. Lines where obeying the column limit is not possible (for example, a long URL in Javadoc, or a long JSNI method reference).
2. package and import statements (see Sections 3.2 Package statement and 3.3 Import statements).
3. Command lines in a comment that may be copied-and-pasted into a shell.
4. Very long identifiers, on the rare occasions they are called for, are allowed to exceed the column limit. In that case, the valid wrapping for the surrounding code is as produced by google-java-format.

 

4.5 Line-wrapping

한 줄에 포함될 수 있는 규칙을 가진 코드를 여러 줄로 나누는 것을 줄바꿈이라고 표현한다.

모든 경우에서 어떻게 줄바꿈을 해야하는지를 설명하는 포괄적이고 결정적인 공식은 없으며 다양한 방식이 있다.

통상 줄바꿈을 하는 이유는 열 제한을 피하기 위해서, 혹은 열 제한은 만족하지만 코드 작성자의 재량(가독성을 위해)에 의해서 줄바꿈을 할 수 있다. 

Tip : 메소드 호출 혹은 지역변수를 사용하는 것은 줄바꿈을 대신해서 이 문제를 해결할 수 있다.

Terminology Note: When code that might otherwise legally occupy a single line is divided into multiple lines, this activity is called line-wrapping.
There is no comprehensive, deterministic formula showing exactly how to line-wrap in every situation. Very often there are several valid ways to line-wrap the same piece of code.
Note: While the typical reason for line-wrapping is to avoid overflowing the column limit, even code that would in fact fit within the column limit may be line-wrapped at the author's discretion.
Tip: Extracting a method or local variable may solve the problem without the need to line-wrap.

 

4.5.1 Where to break

더 높은 레벨의 구문에서 끊어주는 것을 원칙으로 한다. 

1. non-assignment operator (대입 연산자가 아닌 이외의 연산자) 에서 줄이 끊어질 때, symbols 앞에서 줄을 끊어 줄바꿈을 해준다. 이는 연산자와 같은 symbols 들에게대 동일하게 적용한다.

- Google style 의 다른 언어에서는 동일하게 사용되지 않는다.

 

  • 점 구분기호(.)
  • 메소드 참조(::)
  • 타입 바운드에서 앤드기호(&)
  • catch 블록에서 pipe (|)

2. 대입 연산자에서 줄이 끊어지면 일반적으로 기호 뒤에 줄바꿈이 오지만 어느 쪽이든 상관없다. 이는 향상된 for 문의 콜론에도 적용된다.

3. 메서도 또는 생성자 이름 뒤에 오는 여는 괄호는 붙여준다.

3. 쉼표는 앞에 오는 토큰에 붙여준다.

4. 람다의 본문이 중괄호가 없는 단일 표현식으로 구성된 경우 화살표의 바로 뒤에서 줄이 끊어지는 경우를 제외하고는 람다의 화살표 옆에서 줄바꿈을 하지 않는다.

 

줄 바꿈의 가장 최우선적인 목표는 코드의 가독성이다. 줄이 몇개 없는 코드의 경우 줄바꿈이 크게 필요하지 않다.

 

The prime directive of line-wrapping is: prefer to break at a higher syntactic level. Also:

  1. When a line is broken at a non-assignment operator the break comes before the symbol. (Note that this is not the same practice used in Google style for other languages, such as C++ and JavaScript.)
    • This also applies to the following "operator-like" symbols:
      • the dot separator (.)
      • the two colons of a method reference (::)
      • an ampersand in a type bound (<T extends Foo & Bar>)
      • a pipe in a catch block (catch (FooException | BarException e)).
  2. When a line is broken at an assignment operator the break typically comes after the symbol, but either way is acceptable.
    • This also applies to the "assignment-operator-like" colon in an enhanced for ("foreach") statement.
  3. A method or constructor name stays attached to the open parenthesis (() that follows it.
  4. A comma (,) stays attached to the token that precedes it.
  5. A line is never broken adjacent to the arrow in a lambda,  if the body of the lambda consists of a single unbraced expression. Examples: 
  6. MyLambda<String, Long, Object> lambda = (String label, Long value, Object obj) -> { ... }; Predicate<String> predicate = str -> longExpressionInvolving(str);

Note: The primary goal for line wrapping is to have clear code, not necessarily code that fits in the smallest number of lines.

 

4.5.2 Indent continuation lines at least +4 spaces

줄 바꿈 이후에는 기존의 라인보다 4개 이상의 들여쓰기를 해준다. 연속행이 여러개인 경우 공백을 4개 이상으로 들여쓸 수 있다. 일반적으로 병렬요소인 두 개의 연속행에 대해서는 동일한 수준의 들어쓰기를 사용한다.

When line-wrapping, each line after the first (each continuation line) is indented at least +4 from the original line.
When there are multiple continuation lines, indentation may be varied beyond +4 as desired. In general, two continuation lines use the same indentation level if and only if they begin with syntactically parallel elements.
Section 4.6.3 on Horizontal alignment addresses the discouraged practice of using a variable number of spaces to align certain tokens with previous lines.

 

4.6 Whitespace

4.6.1 Vertical Whitespace

클래스의 연속 멤버 혹은 생성자 사이에, 문서의 다른 섹션에는 하나의 빈 줄이 항상 들어간다.

예외 :

1. 두 개의 연속 field 에 대한 빈 줄은 선택사항이다.

2. enum 상수에 대한 빈 줄은 section 4.8.1 에서 설명한다. 

 

 

A single blank line always appears:
1. Between consecutive members or initializers of a class: fields, constructors, methods, nested classes, static initializers, and instance initializers.

Exception: A blank line between two consecutive fields (having no other code between them) is optional. Such blank lines are used as needed to create logical groupings of fields.

Exception: Blank lines between enum constants are covered in Section 4.8.1.

2. As required by other sections of this document (such as Section 3, Source file structure, and Section 3.3, Import statements).

A single blank line may also appear anywhere it improves readability, for example between statements to organize the code into logical subsections. A blank line before the first member or initializer, or after the last member or initializer of the class, is neither encouraged nor discouraged.
Multiple consecutive blank lines are permitted, but never required (or encouraged)

 

4.6.2 Horizontal whitespace

수평 공백

- 언어, 다른 스타일의 규칙, 리터럴, 주석 및 Javadoc 을 제외한 ASCII 공백은 다음의 위치에만 나타난다.

1. if,for,catch  등의 모든 예약어 의 여는 괄호 사이에 공백

2. else, catch 등의 예약어의 닫는 중괄호 앞의 공백

3. 모든 여는 중괄호 앞에

 

예외 

  • @SomeAnnotation({a, b}) (no space is used)
  • String[][] x = {{"foo"}}; (no space is required between {{, by item 9 below)

 

4. 이항, 3항 연산자, 연산자 앞뒤 + 연산자 같은 symbols 들도 마찬가지

  •  

Beyond where required by the language or other style rules, and apart from literals, comments and Javadoc, a single ASCII space also appears in the following places only.

  1. Separating any reserved word, such as if, for or catch, from an open parenthesis (() that follows it on that line
  2. Separating any reserved word, such as else or catch, from a closing curly brace (}) that precedes it on that line
  3. Before any open curly brace ({), with two exceptions:
    •  
  4. On both sides of any binary or ternary operator. This also applies to the following "operator-like" symbols:
    • the ampersand in a conjunctive type bound: <T extends Foo & Bar>
    • the pipe for a catch block that handles multiple exceptions: catch (FooException | BarException e)
    • the colon (:) in an enhanced for ("foreach") statement
    • the arrow in a lambda expression: (String str) -> str.length()
    but not
    • the two colons (::) of a method reference, which is written like Object::toString
    • the dot separator (.), which is written like object.toString()
  5. After ,:; or the closing parenthesis ()) of a cast
  6. Between any content and a double slash (//) which begins a comment. Multiple spaces are allowed.
  7. Between a double slash (//) which begins a comment and the comment's text. Multiple spaces are allowed.
  8. Between the type and variable of a declaration: List<String> list
  9. Optional just inside both braces of an array initializer
    • new int[] {5, 6} and new int[] { 5, 6 } are both valid
  10. Between a type annotation and [] or ....

This rule is never interpreted as requiring or forbidding additional space at the start or end of a line; it addresses only interior space.

4.6.3 Horizontal alignment: never required

수평 정렬은 코드의 가독성을 좋게 만들기 위해서 몇개의 공백을 추가적으로 넣는 것을 의미한다. 일반적으로 허용되기는 하지만 구글 스타일에서는 절대 사용되지 않는다. 이는 향후 유지관리에 문제가 되기 때문이다. 

Terminology Note: Horizontal alignment is the practice of adding a variable number of additional spaces in your code with the goal of making certain tokens appear directly below certain other tokens on previous lines.

This practice is permitted, but is never required by Google Style. It is not even required to maintain horizontal alignment in places where it was already used.

Here is an example without alignment, then using alignment:

private int x; // this is fine
private Color color; // this too

private int   x;      // permitted, but future edits
private Color color;  // may leave it unaligned

Tip: Alignment can aid readability, but it creates problems for future maintenance. Consider a future change that needs to touch just one line. This change may leave the formerly-pleasing formatting mangled, and that is allowed. More often it prompts the coder (perhaps you) to adjust whitespace on nearby lines as well, possibly triggering a cascading series of reformattings. That one-line change now has a "blast radius." This can at worst result in pointless busywork, but at best it still corrupts version history information, slows down reviewers and exacerbates merge conflicts.

 

4.7 Grouping parentheses: recommended

독자 전체가 JAVA 연산자의 우선순위 관계를 알고 있다고 가정하는 것은 합리적이지 않다. 그래서 선택적으로 그룹화하기 위해 사용되는 괄호는 코드의 작성자나 리뷰어가 코드를 잘못 해석하거나 코드를 읽기 어렵게 만드는 경우를 제외하고 허용된다. 

Optional grouping parentheses are omitted only when author and reviewer agree that there is no reasonable chance the code will be misinterpreted without them, nor would they have made the code easier to read. It is not reasonable to assume that every reader has the entire Java operator precedence table memorized.

4.8 Specific constructs

4.8.1 Enum classes

열거형 상수 다음에 오는 각 쉼표 뒤의 줄바꿈은 선택사항이다. 또한 추가적인 한 줄의 공백도 허용된다. 또한 메소드나 요소에 대한 문서가 없는 열거형 클래스의 경우 배열 이니셜라이저처럼 형식을 지정할 수 있다. 열거형 클래스도 클래스이기 때문에 클래스의 모든 형식 규칙이 적용된다.

After each comma that follows an enum constant, a line break is optional. Additional blank lines (usually just one) are also allowed. This is one possibility:

private enum Answer {
  YES {
    @Override public String toString() {
      return "yes";
    }
  },

  NO,
  MAYBE
}

An enum class with no methods and no documentation on its constants may optionally be formatted as if it were an array initializer (see Section 4.8.3.1 on array initializers).

private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS }

Since enum classes are classes, all other rules for formatting classes apply.

4.8.2 Variable declarations - 변수선언

모든 변수 선언은 하나의 변수만 선언해야한다. int a,b; 와 같은 선언은 사용하지 않는다.

for 반복문의 헤더에서는 예외적으로 여러 변수 선언이 허용된다.

 

지역 변수는 습관적으로 이를 포함하는 블록이나 블록같은 구조의 시작 부분에서 선언되지 않는다. 범위를 최소화하기 위해서 처음 사용되는 지점에 가깝게 선언된다. 지역 변수 선언은 일반적으로 이니셜라이저가 있거나 선언 직후에 초기화 한다. 

4.8.2.1 One variable per declaration
Every variable declaration (field or local) declares only one variable: declarations such as int a, b; are not used.
Exception: Multiple variable declarations are acceptable in the header of a for loop.
4.8.2.2 Declared when needed
Local variables are not habitually declared at the start of their containing block or block-like construct. Instead, local variables are declared close to the point they are first used (within reason), to minimize their scope. Local variable declarations typically have initializers, or are initialized immediately after declaration.

 

4.8.3 Arrays

 

4.8.3.1 Array initializers: can be "block-like"

배열 이니셜라이저는 블록처럼 사용될 수 있다.

모든 배열 이니셜라이저는 블록처럼 선택적으로 형식을 지정할 수 있다. 다음 아래의 모든 예는 유효한 배열 이니셜라이저의 예이다. 

Any array initializer may optionally be formatted as if it were a "block-like construct." For example, the following are all valid (not an exhaustive list):

new int[] {           new int[] {
  0, 1, 2, 3            0,
}                       1,
                        2,
new int[] {             3,
  0, 1,               }
  2, 3
}                     new int[]
                          {0, 1, 2, 3}

 

4.8.3.2 No C-style array declarations

대괄호는 변수가 아니라 자료형에 붙여서 사용한다. String args[] (x) ->  String[] args

The square brackets form a part of the type, not the variable: String[] args, not String args[].

4.8.4 Switch statements

스위치 블록의 들여쓰기는 2개의 추가 공백을 사용한다. 또한 각 case 내의 구문을 쓸때는 들여쓰기를 +2 의 추가 공백을 사용하며 다음 case로 넘어갈 때는 이전의 수준으로 돌아간다. 각 case 에서 break 가 없이 통과하는 경우에는 일반적으로 //fall though 라는 주석을 달아놓는다. case 1 처럼 빈 case 의 경우에는 주석을 사용하지 않아도 된다.switch 문에 default 코드가 없는 경우에도 default 블록을 빈 코드로 추가한다.

Terminology Note: Inside the braces of a switch block are one or more statement groups. Each statement group consists of one or more switch labels (either case FOO: or default:), followed by one or more statements (or, for the last statement group, zero or more statements).

4.8.4.1 Indentation

As with any other block, the contents of a switch block are indented +2.

After a switch label, there is a line break, and the indentation level is increased +2, exactly as if a block were being opened. The following switch label returns to the previous indentation level, as if a block had been closed.

4.8.4.2 Fall-through: commented

Within a switch block, each statement group either terminates abruptly (with a break, continue, return or thrown exception), or is marked with a comment to indicate that execution will or might continue into the next statement group. Any comment that communicates the idea of fall-through is sufficient (typically // fall through). This special comment is not required in the last statement group of the switch block. Example:

switch (input) {
  case 1:
  case 2:
    prepareOneOrTwo();
    // fall through
  case 3:
    handleOneTwoOrThree();
    break;
  default:
    handleLargeNumber(input);
}

Notice that no comment is needed after case 1:, only at the end of the statement group.

4.8.4.3 Presence of the default label

Each switch statement includes a default statement group, even if it contains no code.

Exception: A switch statement for an enum type may omit the default statement group, if it includes explicit cases covering all possible values of that type. This enables IDEs or other static analysis tools to issue a warning if any cases were missed.

 

4.8.5 Annotations

4.8.5.1 Type-use annotations

Type-use 어노테이션은 자료형 이전에 바로 나온다. @Target(ElementType.TYPE_USE) 이 포함된 어노테이션은 type-use 어노테이션이다. 

어노테이션은 각 한줄에 적으며 들여쓰기를 하지 않는다.

파라미터가 없는 하나의 어노테이션의 경우 메소드 시그니쳐와 같이 쓸수 있으며 필드 변수에 붙이는 어노테이션의 경우에도 한 줄에 여러개를 쓸 수 있다. 

Type-use annotations appear immediately before the annotated type. An annotation is a type-use annotation if it is meta-annotated with @Target(ElementType.TYPE_USE). Example:

final @Nullable String name;

public @Nullable Person getPersonByName(String name);

4.8.5.2 Class annotations

Annotations applying to a class appear immediately after the documentation block, and each annotation is listed on a line of its own (that is, one annotation per line). These line breaks do not constitute line-wrapping (Section 4.5, Line-wrapping), so the indentation level is not increased. Example:

@Deprecated
@CheckReturnValue
public final class Frozzler { ... }

4.8.5.3 Method and constructor annotations

The rules for annotations on method and constructor declarations are the same as the previous section. Example:

@Deprecated
@Override
public String getNameIfPresent() { ... }

Exception: A single parameterless annotation may instead appear together with the first line of the signature, for example:

@Override public int hashCode() { ... }

4.8.5.4 Field annotations

Annotations applying to a field also appear immediately after the documentation block, but in this case, multiple annotations (possibly parameterized) may be listed on the same line; for example:

@Partial @Mock DataLoader loader;

4.8.5.5 Parameter and local variable annotations

There are no specific rules for formatting annotations on parameters or local variables (except, of course, when the annotation is a type-use annotation).

 

4.8.6 Comments

이 부분에서는 구현 주석을 다룬다.

 모든 줄바꿈 앞에는 임의의 공백이 오고 그 뒤에 구현주석이 달린다. 이러한 주석은 공백으로 랜더링되지 않는다.

 

블록 주석은 주변 코드와 같은 수준으로 들여쓰기 된다. /* ... */// ... 의 스타일로 작성할 수있으며

여러 행일 경우에는  /* ... */ 의 스타일을 사용한다.  다음 라인은 '*' 와 함께 시작되어야 한다. 

This section addresses implementation comments. Javadoc is addressed separately in Section 7, Javadoc.

Any line break may be preceded by arbitrary whitespace followed by an implementation comment. Such a comment renders the line non-blank.

4.8.6.1 Block comment style

Block comments are indented at the same level as the surrounding code. They may be in /* ... */ style or // ... style. For multi-line /* ... */ comments, subsequent lines must start with * aligned with the * on the previous line.

/*
 * This is          // And so           /* Or you can
 * okay.            // is this.          * even do this. */
 */

Comments are not enclosed in boxes drawn with asterisks or other characters.

Tip: When writing multi-line comments, use the /* ... */ style if you want automatic code formatters to re-wrap the lines when necessary (paragraph-style). Most formatters don't re-wrap lines in // ... style comment blocks.

4.8.7 Modifiers

클래스나 멤버 수정자가 존재하는 경우 Java 언어에서 권장하는 순서로 나타난다.

Class and member modifiers, when present, appear in the order recommended by the Java Language Specification:

public protected private abstract default static final transient volatile synchronized native strictfp

 

4.8.8 Numeric Literals

Long 타입의 정수는 대문자인 L을 사용하며 소문자는 절대 사용하지 않는다. 이는 숫자 1과 혼동될 수 있기 때문이다. 예를 들어 

3000000000l 대신 3000000000L 을 사용해야 한다. 

long-valued integer literals use an uppercase L suffix, never lowercase (to avoid confusion with the digit 1). For example, 3000000000L rather than 3000000000l.

 

5 Naming

5.1 Rules common to all identifiers - 모든 식별자의 공통 규칙

식별자들은 오직 ASCII 문자 혹은 숫자,언더바를 이용한다.

구글 스타일에서는 아래와 같은 예처럼 특수 접두나사 접미사를 붙여서사용하지 않는다. 

Identifiers use only ASCII letters and digits, and, in a small number of cases noted below, underscores. Thus each valid identifier name is matched by the regular expression \w+ .
In Google Style, special prefixes or suffixes are
 
notused. For example, these names are not Google Style:
name_,
mName,
s_name
and kName.

 

5.2 Rules by identifier type

5.2.1 Package names

패키지명은 오직 소문자와 숫자로만 사용한다.

Package names use only lowercase letters and digits (no underscores). Consecutive words are simply concatenated together. For example, com.example.deepspace, not com.example.deepSpace or com.example.deep_space.

5.2.2 Class names

클래스명은 UpperCamelCase 를 사용한다. 클래스명은 일반적으로 명사나 명사 구를 사용하지만 상황에 따라 형용사나 형용사구를 사용하기도 한다.

어노테이션 클래스에 대해서는 클래스명을 위한 특별한 규칙이나 잘 정의된 컨벤션이 존재하지 않는다.

테스트 클래스는 Test 로 끝나는 이름을 같는다. 특정 클래스의 테스트 클래스는 해당 클래스명 +Test 로 테스트 클래스의 이름을 정의한다.

Class names are written in UpperCamelCase.
Class names are typically nouns or noun phrases. For example, Character or ImmutableList. Interface names may also be nouns or noun phrases (for example, List), but may sometimes be adjectives or adjective phrases instead (for example, Readable).
There are no specific rules or even well-established conventions for naming annotation types.
A test class has a name that ends with Test, for example, HashIntegrationTest. If it covers a single class, its name is the name of that class plus Test, for example HashImplTest.

 

5.2.3 Method names

메소드명은 lowerCamelCase 를 사용한다. 

일반적으로 동사를 사용한다.

JUnit 테스트 메소드를 정의하는 데에는 정답은 없지만 언더바를 통해 논리적인 요소를 구분할 수 있다.

Method names are written in lowerCamelCase.
Method names are typically verbs or verb phrases. For example, sendMessage or stop.
Underscores may appear in JUnit test method names to separate logical components of the name, with each component written in lowerCamelCase, for example transferMoney_deductsFromSource. There is no One Correct Way to name test methods.

 

5.2.4 Constant names

상수명은 UPPER_SNAKE_CASE 를 사용한다. 모든 문자를 대문자로 사용하는 것을 말하며 각각의 단어는 언더바를 통해 구분한다.

상수란 아예 변경되지 않으며 메소드의 영향을 받지 않는 정적인 필드이다. 기본형, 문자열, 변경할 수 없는 값,null 등에 대한

모든 예를 보여준다. 어떤 인스턴스이던지 변경될 소지가 있는 경우 그것은 상수가 아니다. 객체를 변경하지 않으려는 의도만으로는 충분하지 않다. 

Constant names use UPPER_SNAKE_CASE: all uppercase letters, with each word separated from the next by a single underscore. But what is a constant, exactly?

Constants are static final fields whose contents are deeply immutable and whose methods have no detectable side effects. Examples include primitives, strings, immutable value classes, and anything set to null. If any of the instance's observable state can change, it is not a constant. Merely intending to never mutate the object is not enough. Examples:

// Constants
static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
static final Map<String, Integer> AGES = ImmutableMap.of("Ed", 35, "Ann", 32);
static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable
static final SomeMutableType[] EMPTY_ARRAY = {};

// Not constants
static String nonFinal = "non-final";
final String nonStatic = "non-static";
static final Set<String> mutableCollection = new HashSet<String>();
static final ImmutableSet<SomeMutableType> mutableElements = ImmutableSet.of(mutable);
static final ImmutableMap<String, SomeMutableType> mutableValues =
    ImmutableMap.of("Ed", mutableInstance, "Ann", mutableInstance2);
static final Logger logger = Logger.getLogger(MyClass.getName());
static final String[] nonEmptyArray = {"these", "can", "change"};

These names are typically nouns or noun phrases.

 

5.2.5 Non-constant field names

상수가 아닌 필드명은 lowerCamleCase 를 사용한다. 이 이름들은 일반적으로 computedValues, index 처럼 명사를 사용한다. 

Non-constant field names (static or otherwise) are written in lowerCamelCase.
These names are typically nouns or noun phrases. For example, computedValues or index.

 

5.2.6 Parameter names

파라미터의 이름은 lowerCamelCase 르 적어지며 public 메소드에서 한글자의 파라미터는 피해야한다.

Parameter names are written in lowerCamelCase.
One-character parameter names in public methods should be avoided.

5.2.7 Local variable names

지역변수는 lowerCamelCase 를 사용한다. 만약 final 이고 변경할 수 없는 경우에도 상수로 취급되지 않으며 상수의 style 을 적용하면 안된다.

Local variable names are written in lowerCamelCase.
Even when final and immutable, local variables are not considered to be constants, and should not be styled as constants.

 

5.2.8 Type variable names

Type 변수의 이름 두가지 스타일이 있다.

1. 하나의 대문자나 혹은 하나의 숫자까지 허용한다.

2. 클래스에 사용되는 형식의 이름에 대문자 T를 붙인다.

Each type variable is named in one of two styles:

  • A single capital letter, optionally followed by a single numeral (such as E, T, X, T2)
  • A name in the form used for classes (see Section 5.2.2, Class names), followed by the capital letter T (examples: RequestT, FooBarT).

 

5.3 Camel case: defined

카멜케이스에 대한 정의이며 구두점을 기준으로 분할하여 각 단어의 가장 첫 문자를 대문자로 지정한다. 

UpperCamelCase 의 경우 첫 번째 나오는 단어 또한 첫 문자는 대문자로 지정하며

lowerCamelCase 의 경우 첫 번째 나오는 단어의 첫 문자는 소문자로 지정한다.

Sometimes there is more than one reasonable way to convert an English phrase into camel case, such as when acronyms or unusual constructs like "IPv6" or "iOS" are present. To improve predictability, Google Style specifies the following (nearly) deterministic scheme.

Beginning with the prose form of the name:

  1. Convert the phrase to plain ASCII and remove any apostrophes. For example, "Müller's algorithm" might become "Muellers algorithm".
  2. Divide this result into words, splitting on spaces and any remaining punctuation (typically hyphens).
    • Recommended: if any word already has a conventional camel-case appearance in common usage, split this into its constituent parts (e.g., "AdWords" becomes "ad words"). Note that a word such as "iOS" is not really in camel case per se; it defies any convention, so this recommendation does not apply.
  3. Now lowercase everything (including acronyms), then uppercase only the first character of:
    • ... each word, to yield upper camel case, or
    • ... each word except the first, to yield lower camel case
  4. Finally, join all the words into a single identifier.

Note that the casing of the original words is almost entirely disregarded. Examples:

Prose formCorrectIncorrect

"XML HTTP request" XmlHttpRequest XMLHTTPRequest
"new customer ID" newCustomerId newCustomerID
"inner stopwatch" innerStopwatch innerStopWatch
"supports IPv6 on iOS?" supportsIpv6OnIos supportsIPv6OnIOS
"YouTube importer" YouTubeImporter
YoutubeImporter*
 

*Acceptable, but not recommended.

Note: Some words are ambiguously hyphenated in the English language: for example "nonempty" and "non-empty" are both correct, so the method names checkNonempty and checkNonEmpty are likewise both correct.

 

6 Programming Practices

6.1 @Override: always used

오버라이드 한 경우 @Override 어노테이션을 꼭 붙여야 한다. 여기에는 상위 클래스의 메소드를 오버라이드한 메소드, 인터페이스를 구현한 메소드, 상위 인터페이스의 메소드를 재지정하는 인터페이스 메소드를 포함한다.

단, 부모의 메소드가 @Deprecated 인 경우, @Override 는 생략할 수 있다.

A method is marked with the @Override annotation whenever it is legal. This includes a class method overriding a superclass method, a class method implementing an interface method, and an interface method respecifying a superinterface method.

Exception: @Override may be omitted when the parent method is @Deprecated.

 

6.2 Caught exceptions: not ignored

아래 표기한 내용을 제외하고 catch 문 내에 아무 내용도 없는 경우 중 대부분은 잘못되어 있는 것이다.

만약 catch  문이 비어있는 것이 정말 올바르게 작성한 것이라면 이를 주석을 통해 비어있는 것이 왜 올바른지에 대해서 설명해야 한다.

지만 예외와 관련된 테스트를 하는 경우 (예시에 표기된 내용) catch 문을 비어놓아도 주석을 따로 달 필요가 없다.

Except as noted below, it is very rarely correct to do nothing in response to a caught exception. (Typical responses are to log it, or if it is considered "impossible", rethrow it as an AssertionError.)

When it truly is appropriate to take no action whatsoever in a catch block, the reason this is justified is explained in a comment.

try {
  int i = Integer.parseInt(response);
  return handleNumericResponse(i);
} catch (NumberFormatException ok) {
  // it's not numeric; that's fine, just continue
}
return handleTextResponse(response);

Exception: In tests, a caught exception may be ignored without comment if its name is or begins with expected. The following is a very common idiom for ensuring that the code under test does throw an exception of the expected type, so a comment is unnecessary here.

try {
  emptyStack.pop();
  fail();
} catch (NoSuchElementException expected) {
}

 

6.3 Static members: qualified using class

static 클래스 멤버를 참조해야 하는 경우, 그 클래스의 참조나 표현식이 아니라 클래스 자체의 이름으로 참조해야 한다.

When a reference to a static class member must be qualified, it is qualified with that class's name, not with a reference or expression of that class's type.

Foo aFoo = ...;
Foo.aStaticMethod(); // good
aFoo.aStaticMethod(); // bad
somethingThatYieldsAFoo().aStaticMethod(); // very bad

 

6.4 Finalizers: not used

finalize 는 일반적으로 거의 재정의 되지 않는다. 

Tip : 하지 마라. 만약 너가 정말 해야겠다면 먼저 Effective Java Item 8의 "Avoid finalizers and cleaners  very carefully"를 읽고 이해한 후에 사용하지 마라.

It is extremely rare to override Object.finalize.

Tip: Don't do it. If you absolutely must, first read and understand Effective Java Item 8, "Avoid finalizers and cleaners" very carefully, and then don't do it.

 

7 Javadoc

7.1 Formatting

7.1.1 General form

Javadoc 블록의 일반적인 형태는 아래와 같다. 일반적인 아래의 형태는 언제나 적용될 수 있다. 또한, 전체의 Javadoc 블록이 한 줄에 들어갈 수 있다면 이는 한줄의 형태로 변경할 수 있다. 다만 이때는 @return 과 같은 태그가 존재하면 안된다.

The basic formatting of Javadoc blocks is as seen in this example:

/**
 * Multiple lines of Javadoc text are written here,
 * wrapped normally...
 */
public int method(String p1) { ... }

한줄의 경우는 다음과 같다.

... or in this single-line example:

/** An especially short bit of Javadoc. */

The basic form is always acceptable. The single-line form may be substituted when the entirety of the Javadoc block (including comment markers) can fit on a single line. Note that this only applies when there are no block tags such as @return.

 

7.1.2 Paragraphs

하나의 빈 줄, 즉 정렬된 (*) 를 포함하는 라인은 문단 사이, 만약 블록 태그 그룹이 있는 경우 그 앞에 나타난다.

One blank line—that is, a line containing only the aligned leading asterisk (*)—appears between paragraphs, and before the group of block tags if present. Each paragraph except the first has <p> immediately before the first word, with no space after it. HTML tags for other block-level elements, such as <ul> or <table>, are not preceded with <p>.

 

7.1.3 Block tags

모든 표준 블록태그는 @param, @return , @throws, @deprecated 순으로 나타나며 이 네가지 유형은 꼭 이에 대한 설명을 덧붙여야한다. 블록 태그가  한 줄에 맞지 않으면 연속되는 줄은 '@' 를 기준으로 4개의 들여쓰기를 해준다.

Any of the standard "block tags" that are used appear in the order @param, @return, @throws, @deprecated, and these four types never appear with an empty description. When a block tag doesn't fit on a single line, continuation lines are indented four (or more) spaces from the position of the @.

 

7.2 The summary fragment

Javadoc 은 간단한 요약 부분으로 시작된다. 이는 굉장히 중요하다. 

이 부분은 명사로 구성되며 완전한 문장이 아니다.

즉, 아래의 예시처럼

This method is~~, This method returns ~~~ , A {code} is~~~ 처럼 작성되지 않는다. 또한 @return 같은 블록태그도 사용하면 안된다.

/** Returns the customer ID. */ 같은 형식으로 완전한 문장이 아니면서 간단한 요약으로 구성해야 한다.

Each Javadoc block begins with a brief summary fragment. This fragment is very important: it is the only part of the text that appears in certain contexts such as class and method indexes.
This is a fragment—a noun phrase or verb phrase, not a complete sentence. It does not begin with A {@code Foo} is a..., or This method returns..., nor does it form a complete imperative sentence like Save the record.. However, the fragment is capitalized and punctuated as if it were a complete sentence.
Tip: A common mistake is to write simple Javadoc in the form /** @return the customer ID */. This is incorrect, and should be changed to /** Returns the customer ID. */.

 

7.3 Where Javadoc is used

아래의 예시를 제외하고 모든 public 클래스, 모든 public 혹은 protected 된 멤버에는 최소한 Javadoc이 존재해야 한다.

At the minimum, Javadoc is present for every public class, and every public or protected member of such a class, with a few exceptions noted below.
Additional Javadoc content may also be present, as explained in Section 7.3.4, Non-required Javadoc.

7.3.1 Exception: self-explanatory members

단순하고 명백한, 즉 메소드명 만으로도 해당 메소드가 어떤 작업을 하는지 정확하게 알 수 있는 경우 Javadoc이 필요하지 않다.

 

하지만 아래의 예시처럼 CanonicalName 을 반환한다는 것은 알 수 있지만 CanonicalName 이 뭔데? 라고 생각할 수도 있는 경우 즉, 용어 자체가 어려워서 모를 수 있는 경우에는 Javadoc 을 생략하면 안된다.

Javadoc is optional for "simple, obvious" members like getFoo(), in cases where there really and truly is nothing else worthwhile to say but "Returns the foo".
Important:
 
it is not appropriate to cite this exception to justify omitting relevant information that a typical reader might need to know. For example, for a method named
 
getCanonicalName
, don't omit its documentation (with the rationale that it would say only
 
/** Returns the canonical name. */) if a typical reader may have no idea what the term "canonical name" means!

 

7.3.2 Exception: overrides

상위 메소드를 override 하는 경우에 Javadoc이 항상 존재하는 것은 아니다.

Javadoc is not always present on a method that overrides a supertype method.

 

7.3.4 Non-required Javadoc

다른 클래스나 멤버는 Javadoc이 필요하거나, 원할 때 사용된다.

구현 주석이 클래스나 멤버의 모든 행동이나 목적을 정의하기 위해 사용된 경우에는 해당 주석은 Javadoc 으로 대신 작성된다.

7.1.1,7.1.2,7.1.3,7.2 에서 언급한 불필요한 주석에 대한 규칙은 권장되기는 하지만 강력하게 요구되는 사항은 아니다.

Other classes and members have Javadoc as needed or desired.

Whenever an implementation comment would be used to define the overall purpose or behavior of a class or member, that comment is written as Javadoc instead (using /**).

Non-required Javadoc is not strictly required to follow the formatting rules of Sections 7.1.1, 7.1.2, 7.1.3, and 7.2, though it is of course recommended.

댓글