Kotlin 🌈

Hero image for Kotlin 🌈

Reference Resources

When it comes to Java most conventions are shared with Kotlin. But when there are differences, specific examples for Java are added. For more generic conventions, we follow:

Formatting

  • Indentation:
    • Only using spaces * never tabs.
    • Use 4 space indents for blocks and 8 space indents for line wraps.
    • It’s also flexible to change the rules too, as there is a recommendation from Google to use 2 space for blocks and 4 space for line wraps too, so, depending on the start of the project, we should always follow the base structure.
  • Line length: it shouldn’t exceed the screen width, ideally should be no longer than 100 characters.

  • Line amount per class: should be no longer than 600 lines per class.

  • Vertical spacing: it’s very important that you should keep alignment on your new codes to be consistent with current code base in order to have good experience when doing the code review.

  • Brace style:
// Bad
public void main()
{
    // Not this
}

// Good
public void main() {
    // Your code goes here
}
  • Conditional statements are always required to be enclosed with braces:
// Bad
if (conditionPassed)
    doSomething();

// Good
if (conditionPassed) {
    doSomething();
}
if (someTest) { doSomethingElse(); }

if (someTest) doSomethingElse(); // Still acceptable
  • Method chain case:

When multiple methods are chained in the same line * for example when using Builders * every call to a method should go in its own line, breaking the line before the .. For example:

SomeClass.Builder.with(context)
        .setAlpha("1")
        .setCancelable(false)
        .setExtras(bundle)
        .build();
  • RxJava chaining style:
public Observable<Location> syncLocations() {
    return mLocationHelper.getAllLocations()
            .concatMap(new Func1<Location, Observable<? extends Location>>() {
                @Override
                 public Observable<? extends Location> call(Location location) {
                     return mLocationService.getLocation(location.id);
                 }
            })
            .retry(new Func2<Integer, Throwable, Boolean>() {
                 @Override
                 public Boolean call(Integer numRetries, Throwable throwable) {
                     return throwable instanceof Error;
                 }
            });
}

Naming

Packages

Package names are all lower-case, multiple words concatenated together, without hypens or underscores:

// Bad
com.nimble.android_demo

// Good
com.nimble.androiddemo

Variables

BAD:

// Bad
private int mTemp;
private boolean mA;

private void check() {
    // Do a bunch of logics here
}

// Good
private int mTemporary;
private boolean mIsValid;

private void checkStyle() {
    // or private void validateStyle() and do your logics here
}

Classes and Interfaces

  • Written in UpperCamelCase.
// Bad
BaseACTIVITY

// Good
BaseActivity

Methods

  • Written in lowerCamelCase.
// Bad
setvalue

// Good
setValue

Fields

  • Normally be written in lowerCamelCase.
  • Non-public, non-static field names start with an m.
  • Static field names start with an s.
// Bad
private int Value //or anything else.
public static Singleton singleTon;

// Good
private int mValue; // Note: in Kotlin it could be different.
public static Singleton sSingleton;
  • Static final fields should be written in uppercase:
// Bad
public static final int extra_value = 42;

// Good
public static final int EXTRA_VALUE = 42;
  • Acronyms should be treated as words:
// Bad
XMLHTTPRequest
String URL
findPostByID

// Good
XmlHttpRequest
String url
findPostById
  • Example:
public class ExampleClass {
    public static final int SOME_CONSTANT = 42;
    public int publicField;
    protected int mProtected;
    private String mUrl;

    private int findRateById() {
        // Your code goes here
    }
}
class ExampleClass {
    val publicFinalField: Int
    var publicField: Int = 0
    protected val protectedField: Int
    private val url: String

    private fun findRateById(): Int {
        // Your code goes here
    }
}

const val SOME_CONSTANT = 42

Declaration

  • Access level modifiers should be explicitly defined for classes, methods and member variables:
// Bad
boolean isValid;
void method() {
    // Nope
}

// Good
private boolean isValid;
public void method() {
    // Your code
}
  • Classes should be one class per source file, although inner classes are still encouraged in some situations.

  • Enum: should be avoided where possible, due to a large memory overhead. Static constants are preferred. See more or here.

Comments

// Bad

// Two line
// comments

/**
  * Block comment but mis-aligned
 */

// Good

// One line comment

/*
 * Block comment
 * that is longer than 2 lines
 */

 /**
  * Class/method description (Javadoc)
  *
  * @param  url  an absolute URL giving the base location of the image
  * @param  name the location of the image, relative to the url argument
  * @return      the image at the specified URL
  * @see         Image
  */