Java (Android) Code Formatting Standards
##Variables
- Local variable and public field names should be written in lower camel case:
int camelCase;
- Names should be formed from the 26 upper and lower case letters (A...Z, a...z), the 10 digits (0...9). Avoid use of international characters because they may not read well or be understood everywhere.
- Do not use type prefixes/Hungarian notation
private String someClassString;
- Constants should be all caps and underscored
- Constants should be static final
public static final String SOME_CONSTANT_STRING = "hello, world";
- Any variable with explicitly local scope that is not a method parameter should not have any prefix
- Public class members are acceptable in the case of data-modeling. Generally getter/setters are encouraged. The lowercase 'm' prefix can be omitted from non-public fields when they need to match the data for JSON parsing or for database storage purposes.
- For reference: Android Code Style
##Classes
- Class names should be uppercase on every word in the name
SomeClass, SocialLoginActivity
- Opening braces for a class definition should be on the same line as the class name:
public class SocialLoginActivity extends Activity {
...
}
- Static inner classes and interfaces should be defined at the bottom of the enclosing class' declaration. In the case of a single listener interface, it can be defined at the top of the enclosing class' declaration:
public class NetworkAlertFragment extends Fragment {
public interface NetworkAlertFragmentListener {
void alertDismissed();
}
[ALL YOUR OTHER CODE]
public static class Type {
public static final int SUCCESS = 0;
public static final int FAILURE = 1;
}
}
##Methods
- If one method calls another, they should be vertically close, and the caller should be above the callee, if at all possible. This gives the program a natural flow. If the convention is followed reliably, readers will be able to trust that method definitions will follow shortly after their use.
- Opening brackets are on the same line as the method declaration
- There is a space before the opening bracket
- There is a space between parameters
- All methods should have nullability annotations directly. Package level annotations are ok if enforced by CI
- All non-generic parameters should have nullability annotations
@NonNull
public String someFunction(@Nullable param1, @NonNull param2) {
...
return someString;
}
- Resource annotations must be used when passing an expected res type as a parameter
public abstract void setTitle(@StringRes int resId) { … }
- Parameter types which are eligible for lambda conversion should be ordered last to allow for Kotlin's trailing lambda syntax
- For example, RxJava 2’s Flowable.create() method signature is defined as:
public static <T> Flowable<T> create(
FlowableOnSubscribe<T> source,
BackpressureStrategy mode) { /* … */ }
- Because FlowableOnSubscribe is eligible for SAM conversion, function calls of this method from Kotlin look like this:
Flowable.create({ /* … */ }, BackpressureStrategy.LATEST)
- If the parameters were reversed in the method signature, though, function calls could use the trailing-lambda syntax:
Flowable.create(BackpressureStrategy.LATEST) { /* … */ }
- If a parameter list exceeds the 120 character wrap margin the list should be broken to a new line. The parameters can be grouped logically for clarity. Wrapped parameters should align under the first parameter. The bracket should still be on the same line as the last parameter.
public void someHypotheticallyLongQueryFunction(Context context, Uri contentUri,
String query, String[] queryArgs) {
...
}
- Event handlers or callback methods should begin with the word “on”:
onOptionSelect() {}
onClickSubmit() {}
onSubmitSuccess() {}
- Never use the
android:onClick
XML attribute, if you refactor the code, the XML attribute could be invalidated. Always set listeners in Java using Butterknife if possible orsetOnClickListener
and related if necessary.
##General optimization rules
- Avoid creating objects that are unnecessary. Being careless with your object creation will invoke the garbage collector and inhibit performance.
- Prefer static over virtual. If you don't need access to an objects fields the invocation will execute quicker.
- Use static final for native datatype constants. This writes the value of the constant into static field initializers in the DEX file, making a value lookup less expensive.
- When looping over a collection that uses an Iterable interface for it's iterator, use the following syntax:
Collection<Type> myCollection = ...
for (Type current : myCollection) {
...
}
- The only exception to rule #4 is a hand-written counted loop will often times be faster (you should avoid for each loops inside performance critical code, such as drawing code, as an iterator is created which causes excess garbage collection).
- Use package scope for inner classes:
public class Foo {
private int value;
...
class Inner {
public void someFunction() {
Foo.this.doSomething(Foo.this.mValue);
}
}
}
- Use multi-catch syntax where catch bodies are the same:
try {
// some file operation
} catch (IOException | FileNotFoundException ex) {
ex.printStackTrace();
}