Android에서 Java 코딩 스타일 SW


Android 코딩 스타일을 실무에 적용하면서 가이드와 실제 개발자 사이에 이견이 있는 부분들이 있습니다.

  1. 글자폭 100 적용
    글자 폭을 100자 적용을 못하는 이유는 그 자체보다도 method의 이름이 잘못되어서 지나치게 길던지, 아니면 String Constant를 위한 Class 정의 시 Class가 아니라 Interface를 사용해서 발생하는 경우가 많습니다. 글자폭은 언어에서 지원하는 정도와 관련이 많은데, Java라면 Coding Idion을 잘 지킨다면 100자가 충분합니다.

    이 부분은 Effective Java의 Item 17 (또는 Item 19)의 Use interfaces only to define types 에 나와 있는 것처럼 String constant를 정의하는 경우에 interface 대신에 private 생성자로 되어 있는 String Class를 이용하고, 사용 할 때에 static import를 이용하면 Java에서 Namespace/Interface명 지정 때문에 글자폭이 길어지는 문제를 방지 할 수 있습니다. Constant를 정의 할 떄에는 Interface가 조금 더 편한 경우가 많은데, 사용하는 경우 static import를 이용해서 Class 이름을 생략 할 수 있기 때문에 코드가 더 단축됩니다.

  2. Exception을 무시하지 마라
  3. Sonarqube의 기본 Rule에서 특이했던 점으로, Exception을 다시 throw하거나 Log를 남기지 않으면 Major 이슈로 검출됩니다. 이 부분에 대해서 많은 가이드와 anti-pattern에 대한 article 들이 있는데, Top 20 Java Exception Handling Best Practices 를 추천합니다. 다음은 이 중에서 꼭 적용해야 한다고 팀원들에게 이야기 하는 사항입니다.

    5) Always correctly wrap the exceptions in custom exceptions so that stack trace is not lost

    throw 할 떄에는 반드시 exception chaining을 하고, log를 남길 때에는 e.getMessage()를 사용하지 말고 exception을 별도로 argument로 전달 받는 log 함수 (예를 들어 Android라면 https://developer.android.com/reference/android/util/Log.html#e(String, String, Throwable))를 사용해서 명시적으로
    Exception을 Argument로 전달해서 Static Tool에서 Log 처리 여부를 구분 할 수 있게 합니다.

    6) Either log the exception or throw it but never do the both

    Log를 남기는 위치에 대한 내용인데, catch 내부에서 Log를 남기던지, 아니면 throw하던지 하고 둘 다 하는 것은 의미 없습니다. 앞의 5)번 가이드에 의해서 Log를 최종 catch 하는 부분에서 Log가 남게 되어 있고, 중간에 Exception 처리하는 Logic에서는 Exception이 발생한 위치가 Chaining 되어서 남게 됩니다.

    7) Never throw any exception from finally block

    이 부분은 정합성에 대한 내용으로, Java의 JVM spec에 의하면 control이 바뀌는 명령(throw, break, continue 등)이 finally 안에서 실행된다면 Main 구문의 예외가 덮어 써 질수 있습니다. 이런 문제가 발생하면 5), 6)의 Idom으로 보전된 Callstack 정보를 잃어버릴 수 있습니다.