Recommendations to the style code

The rules of the Java language

We follow standard conventions for the design of code in Java. We have added to them some of the rules:
  1. Exceptions: never steal and do not ignore them without explanation.
  2. Exceptions: Do not use generic exceptions, but the code in the libraries at the root of the stack.
  3. Finalizers do not use them.
  4. Imports: fully qualify the imports.

Rules for Java libraries


There is agreement about the use of Java libraries and tools for Android. In some cases, the agreement may be modified, for example, such as using the old code that may be using unapproved pattern or a library.

Rules of Java Style


Program is much easier to maintain when all files have a consistent style. We follow the standard style of programming in Java, particular in their Sun Code Conventions for the Java Programming Language , with a few exceptions and additions. This style guide is a detailed and comprehensive and widely used Java community.

In addition, we will be obliged to use these rules to the code:
  1. Comments / Javadoc: write them, use a standard style.
  2. Short methods: do not write huge methods.
  3. Margins should be at the top of the file, or directly in front of a method that uses them.
  4. Local variables: limit the scope.
  5. Imports: android; third party (in alphabetical order); java (x)
  6. Padding: 4 spaces, not tabs.
  7. The string length: 100 characters.
  8. Field names: not public, and non-static fields begin with «m».
  9. Braces: opening braces are not in a separate line.
  10. Abstracts: Use standard annotations.
  11. Abbreviations: abbreviate words as names, for example, XmlHttpRequest, getUrl (), etc.
  12. Style TODO: «TODO: write a description here."
  13. Consistency: see what's around you.

The rules of the Java language


Do not ignore exceptions

You may want to write code that ignores exceptions, such as:
void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { } }

Do not ever do it. While you think your code will never run into such a condition, or that it does not matter to handle this condition, ignoring exceptions creates hidden problems. You basically have to handle each exception.The specifics of each case depends on the situation.
Acceptable alternatives:
  • Shift your exceptions to the caller.
    void setServerPort(String value) throws NumberFormatException { serverPort = Integer.parseInt(value); }
  • Throw an exception, 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 block catch {}
    /** Set port. If value is not a valid number, 80 is substituted. */ void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { serverPort = 80; // default port for server } }
  • Catch the error and throw RuntimeException. It is dangerous to do so only if you still happen if the issue is.
    /** Set port. If value is not a valid number, die. */ void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { throw new RuntimeException("port " + value " is invalid, ", e); } }
    Note that the original exception is passed to the RuntimeException. If you use a compiler to Java 1.3, then lower the exception. 
  • If you believe that ignoring an exception in this case occurs, then at least comment on why you think so.
    /** If value is not a valid number, original port number is used. */ void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { // Method is documented to just ignore invalid user input. // serverPort will just be unchanged. } }

Do not catch generic exceptions

Sometimes it's tempting to be lazy with exception handling and write something like this:
try { someComplicatedIOFunction(); // may throw IOException someComplicatedParsingFunction(); // may throw ParsingException someComplicatedSecurityFunction(); // may throw SecurityException // phew, made it all the way } catch (Exception e) { // I'll just catch all exceptions handleError(); // with one generic handler! }

You should not do so. The bottom line is that you may receive an exception, which you did not expect and, eventually, will catch the error at the application level. That is, if someone adds a new exception type, the compiler will not be able to help you understand that this is another error.

There are rare exceptions to this rule: certain test code, or code top level where you want to capture all types of errors (in order to prevent their display in the user interface, or to pursue some kind of batch jobs).

Alternatives to the generalized exclusions:
  • Intercepts each exception separately in the block catch, after a single try. Maybe it's inconvenient, but it is still the preferred way to catch all exceptions.
  • Change your code to a more granular error handling with several blocks try. Separate IO of parsing, error handling on a case.
  • Perebroste exception. In many cases you do not need to handle all exceptions to the current level, just let the method throw them.

Remember: the exception - your friends! Do not get angry when the compiler points to the fact that you do not catches.

Finalizers

What it is: Finalizers - a way to run code before the object is going to the garbage collector.
Pros: can be useful in treatment, particularly external resources.
Cons: there is no guarantee when a finalizer will be invoked and, in general, whether it is called.

Solution: We do not use finalizers. In most cases, all that you need from a finalizer, you can do with exception handling. If you really need a finalizer, then declare the close () and document when it is sure to be invoked.

Imports

The wildcard character in the import

What it is: When you wish to use Class Bar of package foo, there are two ways to do this:
  1. import foo.*;
  2. import foo.Bar;

For # 1: Potentially reduces the number of possible import statements.
For # 2: Make it clear which class is actually used. Makes the code more readable for those who support it.

Solution: Use the style # 2 for the import of any Android code. An explicit exception is made for the standard libraries (java.util .*, java.io. *, etc) and code for unit testing (junit.framework .*).

Comments / Javadoc


Each file must have the copyright notice at the beginning. Next come the announcement of the operators package and import, with each block separated by blank lines. They are followed by announcements of a class or interface. Describe what makes the class Javadoc-comments.
/* * Copyright © 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.foo; import android.os.Blah; import android.view.Yada; import java.sql.ResultSet; import java.sql.SQLException; /** * Does X and Y and provides an abstraction for Z. */ public class Foo { ... }

Each class is trivial and a public method must contain Javadoc, with at least one sentence that describes what it does. The phrase should begin with a descriptive verb third person. Examples:
/** Returns the correctly rounded positive square root of a double value. */ static double sqrt(double a) { } /** * Constructs a new String by converting the specified array of * bytes using the platform's default character encoding. */ public String(byte[] bytes) { }

You do not need to describe the Javadoc for trivial get and set methods, such as setFoo (), if your Javadoc says only «sets Foo». If a method does something more complex (eg, compliance with certain restrictions, or if his actions have an important effect outside of himself), then it must be documented. And if it is not simply an explanation of what it means to Foo, then you should also document it.

In general, any method that you write can benefit from Javadoc, no matter public or not. Public methods are part of the API, so they require a description of the Javadoc.

To write Javadoc'ov you should follow the Sun Javadoc conventions .

Short methods


Methods should be short and to solve specific problems as much as possible. However, it is clear that some great methods are feasible, so there is no strict limit to the length of the method. If the method is more than 40 rows, then you may want to consider whether we can break it into pieces, without breaking 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 code, as well as reduce the likelihood of errors. Each variable must be declared in the deepest unit, which surrounds all the possible locations of the variable.

Local variables must be declared at the place where for the first time to use it. Nearly every local variable needs initializer. If you do not know exactly how to initialize a variable, then you should postpone its announcement until you do not know.

There is one exception, on the block try-catch. If the variable is initialized with the return statement of the method that throws a checked exception, it must be initialized in the block try. If the variable should be used outside the block try, then it is declared in front of him, no matter whether you know exactly how it needs to be initialized:
// Instantiate class cl, which represents some sort of Set Set s = null; try { s = (Set) cl.newInstance(); } catch(IllegalAccessException e) { throw new IllegalArgumentException(cl + " not accessible"); } catch(InstantiationException e) { throw new IllegalArgumentException(cl + " not instantiable"); } // Exercise the set s.addAll(Arrays.asList(args));

But even this case can be avoided by encapsulating try-catch block in the method.
Set createSet(Class cl) { // Instantiate class cl, which represents some sort of Set try { return (Set) cl.newInstance(); } catch(IllegalAccessException e) { throw new IllegalArgumentException(cl + " not accessible"); } catch(InstantiationException e) { throw new IllegalArgumentException(cl + " not instantiable"); } } ... // Exercise the set Set s = createSet(cl); s.addAll(Arrays.asList(args));

The variables in loops to be declared within the operator, unless there are compelling reasons not to do so.
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 as follows:
  1. Android imports.
  2. From imports (com, junit, net, org).
  3. java and javax.

To fully comply setting IDE, imports should be the following:
  • Sorted alphabetically within each group.
  • Capital letters should be in front of lower case letters (for example, Z in front of a).
  • The main groups should be separated by a blank line.

Why?
Order such that:
  • Imports, which people want to see in the first place, are at the top (android).
  • Imports, which people want to see as a last resort, located 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 wrapping, including function calls and assignments, such as correctly as follows:
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);

and so true:
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);

Field names


  • Not static, not public names begin c «m».
  • static fields begin with «s».
  • Other fields begin with a lowercase letter.
  • Fields public static final (constant) is written entirely in upper case with 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 the opening curly brackets are not allocated a separate line, they are in the same line as the code in front of them:
class MyClass { int func() { if (something) { // ... } else if (somethingElse) { // ... } else { // ... } } }

We require braces to the operator environment. The exception is when the condition statement and his body was placed in one line. That is, you can write like this:
if (condition) { body(); // ok } if (condition) body(); // ok

But you can not do:
if (condition) body(); // bad

The string length


Each line of text in the code should be no longer than 100 characters.
Exception: If the comment contains an example of command or URL (it is more convenient to use copy / paste).
Exception: import string may be longer than 100 characters, because people rarely look at them. Also, it simplifies the writing tools.

Abbreviations in names


Think of acronyms and abbreviations as words. The names of the more readable:
WellPoorly
XmlHttpRequestXMLHTTPRequest
getCustomerIdgetCustomerID

This style is also used when the acronyms and abbreviations - it's full name:
WellPoorly
class Htmlclass HTML
String url;String URL;
long id;long ID;


Style TODO


Use TODO comments to the code, which is a temporary, short-term, or good, but not perfect. Comments should include «TODO:», for example:
// TODO: Remove this code after the UrlTable2 has been checked in. // TODO: Change this to use a flag instead of a constant.

If your comment is given "In the future, do something," then make sure it includes a specific date (January 1, 2011), or a particular event "Delete after the release of version 2.1".

Consistency


If you change the code, take a moment out to look at the code around you, and to define his style. If it uses the gaps, then you should use them. If the comments contain a small set of stars, then you should use them.

The whole point of the recommendations to the style of code to create a common vocabulary so that people focused on what they say rather than how they speak. We present a global style rules to let people know this language. But the local style is also important. If the code that you add to the file looks dramatically different from what was then the future is to throw the reader out of his rhythm, and will prevent him understand the structure. Try to avoid this.