Java language rules
We follow standard Java code design conventions. We added some rules to them:
- Exceptions: never intercept or ignore them without explanation.
- Exceptions: do not use generalized exceptions, except for code in libraries, at the root of the stack.
- Finalizers: do not use them.
- Imports: specify imports completely.
Java Library Rules
There are agreements on the use of Java libraries and tools for Android. In some cases, conventions may be modified, for example, in such as using old code that may use a non-approved pattern or library.
Java style rules
Programs are much easier to maintain when all files have a consistent style. We follow the standard Java programming style defined by Sun in their
Code Conventions for the Java Programming Language , with a few exceptions and additions. This style guide is detailed and comprehensive, and is also widely used by the Java community.
In addition, we require the use of the following code rules:
- Comments / Javadoc: write them; use standard style.
- Short methods: do not write giant methods.
- Fields: must be at the top of the file, or right before the method that uses them.
- Local Variables: Limit scope.
- Imports: android; third-party (in alphabetical order); java (x)
- Indents: 4 spaces, without tabs.
- Line Length: 100 characters.
- Field names: non-public and non-static fields start with "m".
- Curly brackets: opening curly brackets are not in a separate line.
- Annotations: use standard annotations.
- Abbreviations: use abbreviations as words in names, for example, XmlHttpRequest, getUrl (), etc.
- TODO style: "TODO: write a description here."
- Consistency: see what is around you.
Java language rules
Do not ignore exceptions.
You may want to write code that ignores exceptions, for example:
void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { } }
Never do that. While you think that your code will never encounter such a condition, or that it is unimportant to handle this condition, ignoring exceptions creates hidden problems. You basically have to handle every exception. Specificity in each case depends on the situation.
Acceptable Alternatives:
- Throw exceptions to the caller.
void setServerPort(String value) throws NumberFormatException { serverPort = Integer.parseInt(value); }
- Throw out exceptions according to your level of abstraction.
void setServerPort(String value) throws ConfigurationException { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { throw new ConfigurationException("Port " + value + " is not valid."); } }
- Catch the error and replace the corresponding value in the catch {} block
void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { serverPort = 80;
- Catch the error and throw a RuntimeException. This is dangerous: do it only if you don't care if this error happens.
void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { throw new RuntimeException("port " + value " is invalid, ", e); } }
Notice that the initial exception is thrown to the RuntimeException constructor. If you are using a Java 1.3 compiler, omit the exception.
- If you are sure that ignoring the exception in this case takes place, then at least comment on why you decided so.
void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) {
Do not catch generalized exceptions.
Sometimes it is tempting to be lazy with exception handling and write something like this:
try { someComplicatedIOFunction();
You shouldn't do that. The bottom line is that there may be an exception that you did not expect and, as a result, the error will be caught at the application level. That is, if someone adds a new type of exception, the compiler will not be able to help you understand that this is another error.
')
There are rare exceptions to this rule: a specific test code, or a top-level code where you want to intercept all types of errors (in order to prevent them from being displayed in the user interface, or to continue any batch task).
Alternatives to generic exceptions:
- Catch each exception separately in a catch block, after a single try. Perhaps this is inconvenient, but still it is the preferred way to catch all exceptions.
- Modify your code for more granular error handling with several try blocks. Separate IO from parsing, handle errors separately in each case.
- Throw an exception. In many cases, you do not need to handle all the exceptions at the current level, just let the method throw them.
Remember: exceptions are your friends! Do not be angry when the compiler indicates that you do not catch them.
Finalizers
What it is : Finalizers are a way to run the program code before the object is collected by the garbage collector.
Pros : may be useful in cleaning, especially external resources.
Against : there is no guarantee of when the finalizer will be called, and, in general, whether it will be called.
Solution : We do not use finalizers. In most cases, everything that you need from the finalizer can be done with exception handling. If you really need a finalizer, declare the close () method and document when it will be called for sure.
Imports
Wildcard in imports
What it is : When you want to use the Bar class from the foo package, then there are two ways to do this:
import foo.*;
import foo.Bar;
Per # 1 : Potentially reduces the number of possible import statements.
Pro # 2 : Makes clear what class is actually used. Makes code more readable for those who support it.
Solution : Use style # 2 to import any Android code. An explicit exception is made for standard libraries (java.util. *, Java.io. *, etc.) and for unit test code (junit.framework. *).
Comments / Javadoc
Each file must have a copyright notice at the very beginning. Next come the declarations of the package and import statements, with each block separated by an empty line. They are followed by class or interface declarations. Describe what the class does in Javadoc comments.
package com.android.internal.foo; import android.os.Blah; import android.view.Yada; import java.sql.ResultSet; import java.sql.SQLException; public class Foo { ... }
Each class and non-trivial public method must contain a javadoc, with at least one phrase describing what it does. The phrase should begin with the descriptive verb of the 3rd person. Examples:
static double sqrt(double a) { } public String(byte[] bytes) { }
You do not need to describe Javadoc for trivial get and set methods, such as setFoo (), if your Javadoc says only “sets Foo”. If a method does something more complicated (for example, the observance of certain restrictions, or if its actions have an important effect outside of it), then it definitely needs to be documented. And if this is not just an explanation of what Foo means, then you should also document it.
In general, any method you write benefits from Javadoc, whether it is public or not. Public methods are part of the API, and therefore they require descriptions in Javadoc.
To write Javadocs, you should follow
Sun Javadoc conventions .
Short methods
Methods should be as small and decisive as possible. However, it is clear that sometimes large methods are appropriate, so there is no strict limit on the length of the method. If the method exceeds 40 lines, then you may need to think about whether it can be divided into parts without violating the structure of the program.
Local variables
The scope of local variables should be kept to a minimum. By doing this, you improve the readability and maintainability of the code, as well as reduce the likelihood of errors. Each variable must be declared in the deepest block that surrounds all possible places of use of the variable.
Local variables should be declared in the place where it is first necessary to use it. Almost every local variable needs an initializer. If you still do not know how to accurately initialize a variable, then you should postpone its declaration until you know it.
There is one exception regarding the try-catch block. If a variable is initialized using the return statement of a method that throws a checked exception, it should be initialized in a try block. If the variable should be used outside the try block, then it is declared before it, no matter if you know how to precisely initialize it:
But even this case can be circumvented by encapsulating a try-catch block in a method.
Set createSet(Class cl) {
Variables in cycles must be declared within the operator itself, unless there is an irresistible reason for not doing this.
for (int i = 0; i <= n; i++) { doSomething(i); } for (Iterator i = c.iterator(); i.hasNext(); ) { doSomethingElse(i.next()); }
Imports
The order of import statements is as follows:
- Android imports.
- Third-party imports (com, junit, net, org).
- java and javax.
To fully comply with the IDE settings, the imports should look like this:
- Sorted alphabetically within each group.
- Capital letters must be in front of lower case letters (for example, Z before a).
- Main groups must be separated by an empty line.
Why?The order is such that:
- Imports that people want to see first are at the top (android).
- The imports that people want to see last are at the bottom (java).
- People can easily use this style.
- IDE can follow this style.
Indentation
we use 4 spaces for blocks. We never use tabs. We use 8 spaces for line breaks, including function calls and assignments, for example, correctly like this:
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
and so wrong:
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
Field names
- Non-static and non-public names begin with c "m".
- static fields start with "s".
- Other fields begin with a lowercase letter.
- Public static final fields (constants) are written entirely in upper case, using underscores (ALL_CAPS_WITH_UNDERSCORES)
For example:
public class MyClass { public static final int SOME_CONSTANT = 42; public int publicField; private static MyClass sSingleton; int mPackagePrivate; private int mPrivate; protected int mProtected; }
Braces
For opening braces, a separate line is not allocated, they are in the same line as the code in front of them:
class MyClass { int func() { if (something) {
We require braces for the condition statement. An exception is when the condition statement and its body are placed on one line. That is, you can write like this:
if (condition) { body();
But so it is impossible:
if (condition) body();
Line length
Each line of text in the code must be no longer than 100 characters.
Exception: if the comment contains an example of commands, or a URL (it is more convenient to use copy / paste).
Exception: import lines can be longer than 100 characters, as people rarely look at them. It also makes writing tools easier.
Abbreviations in names
Consider abbreviations and abbreviations as words. Names are more readable:
Good | poorly |
XmlhttpRequest | XMLHTTPRequest |
getCustomerId | getCustomerID |
This style also applies when abbreviation and abbreviation is the full name:
Good | poorly |
class Html | class HTML |
String url; | String URL; |
long id; | long ID; |
TODO style
Use TODO comments for code that is temporary, short-term, or good, but not perfect. The comment should include “TODO:”, for example:
If your comment has the form “To do something in the future”, then make sure that it includes a specific date (January 1, 2011), or a specific “Delete after version 2.1 release” event.
Consistency
If you change the code, then take a minute to look at the code around you and determine its style. If it uses spaces, then you should use them. If comments contain a small set of asterisks, then you should use them.
The whole point of the recommendations for the style of the code is to create a common vocabulary, so that people concentrate on what they say, instead of what they say. We present the global rules of style so that people know this vocabulary. But local style is also important. If the code that you add to the file looks very different from what it was, it will throw the future reader out of his rhythm and prevent him from understanding the structure. Try to avoid this.