1.61k likes | 2.89k Views
Java Coding Standards. Common Standards. Order of modifiers Public, protected, private, abstract, static, final, transient, synchronized . Place your class in the appropriate package, don’t use default package Classes with only private constructors must be final .
E N D
Common Standards • Order of modifiers • Public, protected, private, abstract, static, final, transient, synchronized. • Place your class in the appropriate package, don’t use default package • Classes with only private constructors must be final. • Classes that have only static methods (Utility classes) must not have any public constructors. • Avoid usage of "synch" or "synchronized".
Common Standards • Do not check for null when using instanceof • Do not explicitly initialize instance variables with their default values, java automatically initializes. • Eg: null for object references, 0 for numeric and character types, false for boolean. • Nested try/catch/finally blocks should be avoided • Avoid nested code blocks
Common Standards • Use Collection.isEmpty instead of size() to check for empty. • Use Calendar, Collection, Set, SortedSet, Map, List, etc in place of below concrete classes GregorianCalendar, Hashtable, HashSet, HashMap, ArrayList, LinkedList, LinkedHashMap, LinkedHashSet, TreeSet, TreeMap, Vector in variable declarations, return values, or method parameters.
Common Standards • Use parentheses only where it is necessary to clarify a statement or expression. • Long constants should be defined with an upper ell • Always override the hashCode method when the equals method is overridden • Ensure local variables and method arguments does not have same names as instance variables.
Imports • Remove unused or redundant import statements. • Do not import from java.lang package. • Do not import class from the same package. • Generic imports should be avoided • Correct: import java.awt.Frame; import java.awt.Graphics; import java.awt.event.WindowAdapter; • Incorrect: import java.awt.*; import java.awt.event.*; import java.applet.*;
Imports • Static imports • If you overuse the static import feature, it can make your program unreadable and unmaintainable, • import static Lennon; • import static Ringo; • import static George; • import static Paul; • import static Yoko; // Too much !
Naming Convention • Naming classes/interfaces • Use nouns when naming classes. • Use nouns or adjectives when naming interfaces. • Keep the names simple and descriptive. • Use whole words; avoid acronyms and abbreviations. • Pluralize names of classes that group related attributes, static services or constants. • Capitalize the first letter of each word that appears in a class or interface name. • Examples: MaintainGeneralAction.java GetCoveragesMapper.java
Naming Convention.. • Naming variables • Use nouns when naming variables • Use lowercase for the first word and camel case for subsequent words. eg: primaryOwner • Variable names should convey as much information as possible about what the object is. • One-character variable names are not allowed except for iterators. • Plural form should be used on names representing a collection of objects. • Do not use names that differ only in case within classes. • Constant variables should be all uppercase Example: SCREENNAME_CONTACTDETAILS
Naming Convention.. • Naming variables • Generic variables should have the same name as their type. • void setTopic(Topic topic) • // NOT: void setTopic(Topic value) • // NOT: void setTopic(Topic aTopic) • // NOT: void setTopic(Topic t) • void connect(Database database) • // NOT: void connect(Database db) • // NOT: void connect(Database oracleDB) • Negated boolean variable names must be avoided. • booleanisError; // NOT: isNoError • booleanisFound; // NOT: isNotFound
Naming Convention.. • Naming variables • is prefix should be used for boolean variables and methods. • isSet, isVisible, isFinished, isFound, • There are a few alternatives to the is prefix that fits better in some situations. These are has, can and should prefixes: • booleanhasLicense(); • booleancanEvaluate(); • booleanshouldAbort = false; • Plural form should be used on names representing a collection of objects. • Collection<Point> points; int[] values; • n prefix should be used for variables representing a number of objects. • nPoints, nLines • No suffix should be used for variables representing an entity number. • tableNo, employeeNo
Naming Convention.. • Naming variables • Associated constants (final variables) should be prefixed by a common type name. • final int COLOR_RED = 1; final int COLOR_GREEN = 2; final int COLOR_BLUE = 3;
Naming Convention • Naming Methods • Use verbs when naming methods. • Methods should have descriptive names so that their purpose is easily understood. eg: retrievePolicyData(), addPolicyToClaim(), buildHTMLFrameTitle(), checkForThirdPartyClaimant() • Name of the object is implicit and should be avoided in a method name. line.getLength() instead of line.getLineLength() • Abbreviations and acronyms should not be uppercase when used as name. exportHtmlSource(); // NOT: exportHTMLSource(); getPsdData(); // NOT: getPSDData();
Naming Convention • Naming Methods • The term compute can be used in methods where something is computed. • valueSet.computeAverage(); matrix.computeInverse(); • The term find can be used in methods where something is looked up. • vertex.findNearestVertex(); matrix.findSmallestElement(); node.findShortestPath(Node destinationNode); • The term initialize can be used where an object or a concept is established. • printer.initializeFontSet(); • Abbreviations in names should be avoided. • computeAverage(); // NOT: compAvg(); ActionEvent event; // NOT: ActionEvent e; catch (Exception exception) { // NOT: catch (Exception e) {
Arrays • UseArrayList instead of a Vector • Use Arrays.AsList()method to create Lists from Arrays • Use System.arrayCopy()instead of looping through an array to copy elements • Use Java style array type "String[] args" not "String args[]"
Variable Assignments • Assignments must occur in their own top-level declaration statement. With the exception of iterators, all assignments must occur in their own top-level statement to increase readability. Correct i = 2; String s = Integer.toString(i); Incorrect String s = Integer.toString(i = 2);
Method Params • Method parameter count must not exceed 7 • Method parameters must not be assigned to any value within the method
Switch Statement • Use break statement at the end of every case. • Include default case after all the cases are handled. Example: switch (n) { case 1: //code to handle case 1 break; case 2: //code to handle case 2 break; default: //code to handle default case }
Interface and Constants • Do not declare constants within an interface • Bad Practice - Example public interface IAppConstants { static final String ERROR_SUBJ = "errors.subject"; static final String MSG_DUPLICATE = "msg.duplicateItem"; static final String KEY_VALUE_SEPARATOR = "="; static final String ITEM_SEPARATOR = "\r\n"; } • Best Practice - Example //always define constants within a class public final class AppConstants { public static final String ERROR_SUBJ = "errors.subject"; public static final String MSG_DUPLICATE = "msg.duplicateItem"; public static final String KEY_VALUE_SEPARATOR = "="; public static final String ITEM_SEPARATOR = "\r\n"; }
Use Common Functions • Use functions available in org.apache.commons package instead of re-inventing. (StringUtils,ObjectUtils,BooleanUtils etc classes) • Example Methods in StringUtils: isNotBlank, isEmpty, isBlank isNumeric,isAlphaNumeric,isAlpha lowerCase,upperCase leftPad,rightPad subString Contains indexOf
String Operations • Use StringUtils or ".equals“, “.equalsIgnoreCase etc methods to compare Strings and do not use “==“ • When comparing a String variable with a String literal, always invoke the equals method on the String literal instead of the String variable. This will prevent null pointer exceptions. • Correct if ("something".equals(str)) { ... } • Incorrect if (str == "something") { ... } • Use length() or methods in StringUtils to check for empty strings rather than using StringBuilder/StringBuffer/String.toString().equals(""). • Example // This is bad if(sb.toString().equals("")) {} // This is good if(sb.length() == 0) {}
String Operations.. • Avoid Using String.valueOf() If unnecessary • There is no need to call String.valueOf() to append to a string; just use the valueOf() argument directly. • Bad Practice public String convert(int i) { String s; s = "a" + String.valueOf(i); //Bad return s; } • Best Practice public String convert(int i) { String s; s = "a" + i; // Better return s; }
String Buffer • Use StringBuilder/StringBuffer for string appends • For better performance, instead of using String concatenations (using +), use StringBuilder from Java 5+ or use StringBuffer for Java 1.4 or less. • String objects are immutable. • Each time you append something via '+' (String.concat()) a new String is created, the old stuff is copied, the new stuff is appended, and the old String is thrown away. • The bigger the String gets the longer it takes - there is more to copy and more garbage is produced.
String Buffer.. • Avoid Insufficient StringBuilder/StringBuffer Initialization • The default constructor initializes the object to exactly 16 characters. • Use best guess value in the constructor to prevent resizing multiple times. “best guess”, value is better to be too high than too low. • Bad Practice StringBuffer sb = new StringBuffer(); // Object sb will be resized to fit this string sb.append("This phrase is more than 16 characters"); // 38 characters • Best Practice StringBuffer sb = new StringBuffer(40); // Object sb has enough room to fit this string sb.append("This phrase is more than 16 characters"); // 38 characters
String Buffer.. • Avoid inefficient string buffering • Avoid concatenating non-literals in a StringBuffer constructor or append(). • Avoid consecutively calling StringBuffer.append() with String literals. • Bad Practice public class Foo { void bar() { // Avoid this StringBuffer sb = new StringBuffer("tmp = "+ System.getProperty("java.io.tmpdir")); sb.append("Hello").append(" ").append("World"); //bad } } • Best Practice public class Foo { void bar() { // Use something like this instead StringBuffer sb = new StringBuffer("tmp = "); sb.append(System.getProperty("java.io.tmpdir")); sb.append("Hello World"); } }
Final Field • Final field could be static • If a final field is assigned to a compile-time constant, it could be made static, thus saving overhead in each object at runtime. • Bad Practice public class Foo { // Since we only need one instance of this field // it could be made static to conserve memory public final int bar = 42; } • Best Practice public class Foo { // Now there is only one instance of this field // instance among all the instances of this class public static final int BAR = 42; }
Singular Field • A field that is only used by one method could be replaced by a local variable. Refactoring the field into a local variable prevents the instance from reserving memory that is only needed during the method invocation. • Bad Practice public class Foo { private int x; private int z; public void foo(int y) { // This is the only method where x and y are used x = bar(y); z = bar2(x); return z; } } • Best Practice public class Foo { public void foo(int y) { int x = bar(y); return bar2(x); } }
enum • Define widely used constants as an enum construct public enum Suit { CLUBS("clubs"), DIAMONDS("diamonds"), HEARTS("hearts"), SPADES("spades"); private final String name; private Suit(String name) { this.name = name; } }
Boolean returns • Simplify boolean returns • Avoid unnecessary if..then..else statements when returning a boolean. • Bad Practice public class Foo { private int bar = 2; public boolean isBarEqualsTo(int x) { if (bar == x) { return true; } else { return false; } } } • Best Practice public class Foo { private int bar =2; public boolean isBarEqualsTo(int x) { return bar == x; } }
Lazy Initialization • Consider using lazy initialization in specific conditions • Lazy instantiation allows objects to be created when needed, instead of being defined at the beginning of a class. This allows memory to be allocated only when needed. • Bad Practice //In this example, the list variable ’states’ does not need to be constructed every time public class StatesTest { final List states; public List getStates() { // retrieve states from an expensive DB operation ……… '''return''' states; } } • Best Practice public class StatesTest { final List states; public List getStates() { if(states == null) { // retrieve states from an expensive DB operation ……… } return states; } }
Short-circuiting • Use short-circuited operators to increase efficiency in expressions. • Bad Practice boolean b1 = returnSomeExpensiveBoolean(); boolean b2 = returnSomeMostlyStaticBoolean(); if (b1 || b2) { // logic goes here } • Best Practice if (returnSomeMostlyStaticBoolean() || returnSomeExpensiveBoolean()) { // logic goes here }
Unused code • Avoid creating a field, variable, or method that is declared and/or assigned a value but not used. • Avoid passing parameters to methods and then letting those parameters go unused. • Avoid initializing a variable by creating a new instance that is never used. • Remove Empty Statements Eg: ;; • Remove unused private methods.
Unused System Resources • Ensure that resources (i.e., Connection, Statement, and ResultSet objects) are always closed after use. If not, they may leak memory and adversely affect performance. • Bad Practice public class Bar { public void foo() { Connection c = pool.getConnection(); try { // Code } catch (SQLE xception ex) { // Handle exception } finally { // Additional code } } } • Best Practice public class Bar { public void foo() { Connection c = pool.getConnection(); try { // Code } catch (SQLException ex) { // Handle exception } finally { c.close(); } } }
Unnecessary local Variables • Avoid creating local variables unnecessarily when converting primaries to Strings and before return. • Bad Practice public String convert(int x) { // This wastes an object to convert x to a String String foo = new Integer(x).toString(); return foo; } • Best Practice public String convert(int x) { // This is better return Integer.toString(x); }
Unnecessary Wrapper Object • Avoid unnecessary wrapper object creation • Any parsing methods used should be called directly, instead of obtaining a value through the valueOf() method. • Bad Practice public int convert(String s) { int i; i = Integer.valueOf(s).intValue(); // This wastes an object } • Best Practice public int convert(String s) { int i; i = Integer.parseInt(s); }
Don’t’s • Do not use System.out, System.err or .printStackTrace • Do not use IBMSession • Do not use Thread.sleep() • Do not use System.exit. • Do not use Runtime.getRuntime() • Do not use keywords: volatile, native, strictfp • Do not import vendor/platform-specific packages • Example: (sun.\* , ibm.\*,…)
Java Coding Standards Exceptions
Exceptions • Avoid catching java.lang.Exception or java.lang.RuntimeException • Define and use an application specific runtime exception • Avoid throwing multiple exceptions from a method • Avoid declaring a method to throw too many differently rooted exceptions
Exception Suppression • Do not suppress exceptions • Incorrect public void catchAndSupressExceptions() { try { // Application code that may throw an exception } catch (Exception ex) { // Do nothing } }
Exception Suppression… • Details of an exception may be lost if the try-catch blocks are ordered improperly or if they try to handle exceptions too generically • Incorrect public void catchAndSupressExceptions() { try { // Application code that may throw several types of exceptions } catch (Exception ex) { // Handles the exception, including SpecificException & RuntimeException } catch (SpecificExceptionspEx) { // This exception will never be handled specifically } catch (SubSpecificExceptionsubSpEx) { // This exception will never be handled specifically } } • Correct public void doNotCatchOrSupressExceptions() { try { // Application code that may throw several types of exceptions } catch (SubSpecificExceptionsubSpEx) { // This exception will be handled specifically } catch (SpecificExceptionspEx) { // This exception will be handled specifically } }
Java Coding Standards Code Complexity & Maintainability
Javadoc • Javadoc is required at class level and for each method • Use @param, @return, @throws, @see where ever applicable. /** * <Method description> * * @param parameter-name description * @return return-description * @throws exception-name exception-description */
Javadoc.. • @see tag should be used whenever a method overrides or implements /** * @see abc.application.pageprocessors.PageProcessor# * retrieveData(java.lang.String) */
Class Structure Consistency • Class Structure Consistency • Only one top-level class must be defined per file. • Each class must be less than 1,000 lines (including javadoc, comments, and blank lines). • Each method must be less than 50 lines (including javadoc, comments, and blank lines).
Code Complexity • If the number of classes any given class relies on is greater than 20then the code is considered complex and should be refactored. • Ensure that no method has more than 30 executable statements. • Use private methods to reduce the block size. • Multiple if…then..else statements should be avoided • Consider creating additional objects to avoid multiple if then else.
Data Abstraction Coupling • Data abstraction coupling (DAC) must have a value of less than seven 7, more than this is considered complex • DAC occurs when a local variable is assigned a concrete class instance. • This metric measures the instantiation of other classes within a given class.
Cyclomatic complexity • Cyclomatic complexity must be less than 10. • McCabe cyclomatic complexity measures the number of unique execution paths through a software function. Cyclomaticcomplexity gives the exact number of tests needed to test every decision point in a program for each outcome. • Cyclomatic complexity of 8 are candidates for refactoring , greater than 10 must be refactored.
NPath • NPATH value should be less than 200. • Complexity is also a function of the number of possible execution paths (or NPATH) through a function, taking into account the nesting of conditional statements and multi-part boolean expressions (for example, A && B, C \|\| D, etc.).