Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Naming Conventions Should follow Sun's guideline of Hungerian notation All final variables should be capitalized The name should not include underscores Method Naming Conventions : Should follow Sun's guideline of Hungerian notation The name should not include underscores. Class Naming Conventions Class names should always begin with an upper case character. Short Variable Name A field, local, or parameter should not have a very short name Long Variable Name A field, formal or local variable should not be declared with a long name Abstract Naming Abstract classes should be named 'AbstractXXX'. Avoid Dollar Signs Avoid using dollar signs in variable/method/class/interface names Method With Same Name As Enclosing Class Non-constructor methods should not have the same name as the enclosing class. Although this is legal, but confusing. Suspicious Hashcode Method Name: The method name and return type should not close to hashCode(), which may mean you are intending to override the hashCode() method. Suspicious Constant Field Name : A field name is all in uppercase characters, which in Sun's Java naming conventions indicate a constant. However, the field is not final. Suspicious Equals Method Name : The method name and parameter number are suspiciously close to equals(Object), which may mean you are intending to override the equals(Object) method. Avoid Field Name Matching Type Name : It is somewhat confusing to have a field name matching the declaring class name. This probably means that type and or field names could be more precise. Avoid Field Name Matching Method Name : It is somewhat confusing to have a field name with the same name as a method. While this is totally legal, having information (field) and actions (method) is not clear naming. No Package : A class or interface should have a package definition. Package Case : A package definition should not contain upper case characters. Misleading Variable Name: A non-field has a name starting with 'm_' usually indicates a field and thus is confusing. Boolean Get Method Name : "Methods having return type "boolean" should have name 'isXXX()' rather than 'getXXX()'." Local Variable Could Be Final : A local variable assigned only once can be declared final. Although few find it verbose, but still "final" is better optimised by JVM. Method Argument Could Be Final : A method argument that is never assigned can be declared final Avoid Instantiating Objects In Loops : Never instantiate a new object is inside a loop Empty If Statement : There should not be 'if' statements where a condition is checked but nothing is done about it. Empty While Statement: Avoid empty 'while' statements. If it is a timing loop, then you should use Thread.sleep() for it; if it's a while loop that does a lot in the exit expression, rewrite it to make it clearer. Empty Switch Statements : Avoid empty switch statements. Empty Synchronized Block : Avoid empty synchronized blocks - they're useless. Empty Static Initializer : An empty static initializer was found. Empty Statement Not In Loop : An empty statement (aka a semicolon by itself) that is not used as the sole body of a for loop or while loop is probably a bug. It could also be a double semicolon, which is useless and should be removed. Empty Initializer : An empty initializer should be avoided. Jumbled Incrementer : Avoid jumbled loop incrementers - it's usually a mistake, and it's confusing even if it's what's intended. For Loop Should Be While Loop : Some for loops can be simplified to while loops - this makes them more concise. Unnecessary Conversion Temporary : Avoid unnecessary temporaries when converting primitives to Strings Override Both Equals And Hashcode : Override both public boolean Object.equals(Object other), and public int Object.hashCode(), or override neither. Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly delegating to your superclass Return From Finally Block : Avoid returning from a finally block - this can discard exceptions. Unnecessary Return: Avoid unnecessary return statements Unconditional If Statement : "Do not use "if" statements that are always true or always false Boolean Instantiation : Avoid instantiating Boolean objects; you can reference Boolean.TRUE, Boolean.FALSE, or call Boolean.valueOf() instead. BigInteger Instantiation: Don't create instances of already existing BigInteger (BigInteger.ZERO, BigInteger.ONE) and for Java 1.5 on, BigInteger.TEN and BigDecimal (BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN) Wrapper Classes : Byte Instantiation: In JDK 1.5, calling new Byte() causes memory allocation. Byte.valueOf() is more memory friendly. Short Instantiation : In JDK 1.5, calling new Short() causes memory allocation. Short.valueOf() is more memory friendly. Long Instantiation: In JDK 1.5, calling new Long() causes memory allocation. Long.valueOf() is more memory friendly. Integer Instantiation: In JDK 1.5, calling new Integer() causes memory allocation. Integer.valueOf() is more memory friendly. String Instantiation: Avoid instantiating String objects; this is usually unnecessary Avoid Decimal Literals In BigDecimal Constructor: "One might assume that ""new BigDecimal(.1)"" is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances notwithstanding. The (String) constructor, on the other hand, is perfectly predictable: 'new BigDecimal("".1"")' is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one." Unnecessary Final Modifier : When a class has the final modifier, all the methods are automatically final. So, decide properly before making a class final. Collapsible If Statements : Sometimes two 'if' statements can be consolidated by separating their conditions with a boolean short-circuit operator. Useless Overriding Method : The overriding method merely calls the same method defined in a superclass Class Cast Exception With ToArray : if you need to get an array of a class from your Collection, you should pass an array of the desidered class as the parameter of the toArray method. Otherwise you will get a ClassCastException. Useless Operation On Immutable: An operation on an Immutable object (String, BigDecimal or BigInteger) won't change the object itself. The result of the operation is a new object. Therefore, ignoring the operation result is an error. Misplaced Null Check : "The null check here is misplaced. if the variable is null you'll get a NullPointerException. Either the check is useless (the variable will never be ""null"") or it's incorrect." Unused Null Check In Equals : After checking an object reference for null, you should invoke equals() on that object rather than passing it to another object's equals() method. Avoid Thread Group: Avoid using ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread safe. Broken Null Check: The null check is broken since it will throw a NullPointerException itself. It is likely that you used Avoid Using Octal Values : Integer literals should not start with zero. Zero means that the rest of literal will be interpreted as an octal value. Avoid Using Hard Coded IP: An application with hard coded IP may become impossible to deploy in some case. It never hurts to externalize IP adresses. Check Result Set : Always check the return of one of the navigation method (next,previous,first,last) of a ResultSet. Indeed, if the value return is 'false', the developer should deal with it ! Avoid Multiple Unary Operators: Using multiple unary operators may be a bug, and/or is confusing. Check the usage is not a bug, or consider simplifying the expression. If Statements Must Use Braces: Avoid using if statements without using curly braces. If Else Statements Must Use Braces: Avoid using if..else statements without using curly braces. While Loops Must Use Braces: Avoid using 'while' statements without using curly braces For Loops Must Use Braces : Avoid using 'for' statements without using curly braces. Proper Clone Implementation: Object clone() should be implemented with super.clone(). Clone Throws CloneNotSupportedException: The method clone() should throw a CloneNotSupportedException. Clone Method Must Implement Cloneable: The method clone() should only be implemented if the class implements the Cloneable interface with the exception of a final method that only throws CloneNotSupportedException. Bean Members Should Serialize : If a class is a bean, or is referenced by a bean directly or indirectly it needs to be serializable. Member variables need to be marked as transient, static, or have accessor methods in the class. Marking variables as transient is the safest and easiest modification. Accessor methods should follow the Java naming conventions, i.e.if you have a variable foo, you should provide getFoo and setFoo methods. Use Correct Exception Logging : To make sure the full stacktrace is printed out, use the logging statement with 2 arguments: a String and a Throwable. Proper Logger: A logger should normally be defined private static final and have the correct class. Private final Log log; is also allowed for rare cases where loggers need to be passed around. More Than One Logger: Normally only one logger is used in each class. System Out Println : Should not use this Avoid Print Stack Trace : Avoid printStackTrace(); use a logger call instead. Use Array List Instead Of Vector: Consider replacing Vector usages with the newer java.util.ArrayList if expensive threadsafe operation is not required. Replace Hashtable With Map: Consider replacing Hashtable with the newer java.util.Map Replace Enumeration With Iterator: Consider replacing Enumeration with the java.util.Iterator Simplify Starts With : Since it passes in a literal of length 1, this call to String.startsWith can be rewritten using String.charAt(0) to save some time. Use String Buffer For String Appends: Avoid usages of += for appending strings. Use Arrays As List: The class java.util.Arrays has a "asList" method that should be use when you want to create a new List from an array of objects. It is faster than executing a loop to copy all the elements of the array one by one. Avoid Array Loops: Instead of copying data between two arrays, use System.arrayCopy method Add Empty String: Finds empty string literals which are being added. This is an inefficient way to convert any type to a String. Avoid Catching Throwable: This is dangerous because it casts too wide a net; it can catch things like OutOfMemoryError. Signature Declare Throws Exception: It is unclear which exceptions that can be thrown from the methods. It might be difficult to document and understand the vague interfaces. Use either a class derived from RuntimeException or a checked exception. Exception As Flow Control: Using Exceptions as flow control leads to GOTOish code and obscures true exceptions when debugging. Avoid Throwing NullPointerException: Avoid throwing a NullPointerException - it's confusing because most people will assume that the virtual machine threw it. Consider using an IllegalArgumentException instead; this will be clearly seen as a programmer-initiated exception. Avoid Catching NPE: Code should never throw NPE under normal circumstances. A catch block may hide the original error, causing other more subtle errors in its wake. Avoid Throwing Raw Exception Types: Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable, Exception, or Error, use a subclassed exception or error instead. Avoid Rethrowing Exception: Catch blocks that merely rethrow a caught exception only add to code size and runtime complexity. Do Not Extend java.lang.Error: Errors are system exceptions. Do not extend them. Do Not Throw Exception In Finally: Throwing exception in a finally block is confusing. It may mask exception or a defect of the code, it also render code cleanup uninstable. Avoid Duplicate Literals: Code containing duplicate String literals can usually be improved by declaring the String as a constant field. String toString: Avoid calling toString() on String objects; this is unnecessary. Inefficient String Buffering : Avoid concatenating non literals in a StringBuffer constructor or append(). Unnecessary Case Change: Using equalsIgnoreCase() is faster than using toUpperCase/toLowerCase().equals() Use StringBuffer Length: "Use StringBuffer.length() to determine StringBuffer length rather than using StringBuffer.toString().equals("""") or StringBuffer.toString().length() ==." Append Character With Char: Avoid concatenating characters as strings in StringBuffer.append. Use indexOf Char: Use String.indexOf(char) when checking for the index of a single character; it executes faster. Inefficient Empty String Check : String.trim().length() is an inefficient way to check if a String is really empty, as it creates a new String object just to check its size. Consider creating a static function that loops through a string, checking Character.isWhitespace() on each character and returning false if a non-whitespace character is found. Insufficient StringBuffer Declaration: "Failing to pre-size a StringBuffer properly could cause it to re-size many times during runtime. This rule checks the characters that are actually passed into StringBuffer.append(), but represents a best guess ""worst case"" scenario. An empty StringBuffer constructor initializes the object to 16 characters. This default is assumed if the length of the constructor can not be determined." Useless String ValueOf: No need to call String.valueOf to append to a string; just use the valueOf() argument directly. StringBuffer Instantiation With Char : StringBuffer sb = new StringBuffer('c'); The char will be converted into int to intialize StringBuffer size. Use Equals To Compare Strings: sing '==' or '!=' to compare strings only works if intern version is used on both sides Avoid StringBuffer Field: StringBuffers can grow quite a lot, and so may become a source of memory leak (if the owning class has a long life time Unused Imports: Avoid unused import statements. This rule will find unused on demand imports, i.e. import com.foo.*. Duplicate Imports: Avoid duplicate import statements. Don’t Import Java Lang: Avoid importing anything from the package 'java.lang'. These classes are automatically imported (JLS 7.5.3). Import From Same Package : No need to import a type that lives in the same package. Too Many Static Imports : If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Readers of your code (including you, a few months after you wrote it) will not know which class a static member comes from (Sun 1.5 Language Guide). Unused Private Field: Remove a private field if it is declared and/or assigned a value, but not used. Unused Local Variable: Remove a local variable if it is declared and/or assigned, but not used. Unused Private Method: Remove a private method if it is declared but is unused Unused Formal Parameter: Avoid passing parameters to methods or constructors and then not using those parameters. Empty Finalizer : If the finalize() method is empty, then it does not need to exist. Finalize Only Calls Super Finalize: If the finalize() is implemented, it should do something besides just calling super.finalize(). Finalize Overloaded: Methods named finalize() should not have parameters. It is confusing and probably a bug to overload finalize(). It will not be called by the VM. Finalize Does Not Call Super Finalize: If the finalize() is implemented, its last action should be to call super.finalize. Finalize Should Be Protected: If you override finalize(), make it protected. If you make it public, other classes may call it. Avoid Calling Finalize: Object.finalize() is called by the garbage collector on an object when garbage collection determines that there are no more references to the object. Variable names: The name of a variable, function, or class, should answer all the big questions. It should tell you why it exists, what it does, and how it is used. If a name requires a com- ment, then the name does not reveal its intent. int d; // elapsed time in days The name d reveals nothing. It does not evoke a sense of elapsed time, nor of days. We should choose a name that specifies what is being measured and the unit of that measure- ment: int elapsedTimeInDays; int daysSinceCreation; int daysSinceModification; int fileAgeInDays; New developers had to have the variables explained to them, and then they spoke about it in silly made-up words instead of using proper English terms. Compare class DtaRcrd102 { private Date genymdhms; private Date modymdhms; private final String pszqint = "102"; /* ... */ }; to }; Intelligent conversation is now possible: “Hey, Mikey, take a look at this record! The gen- eration timestamp is set to tomorrow’s date! How can that be?” Use Searchable Names Single-letter names and numeric constants have a particular problem in that they are not easy to locate across a body of text. One might easily grep for MAX_CLASSES_PER_STUDENT, but the number 7 could be more troublesome. Searches may turn up the digit as part of file names, other constant defini- tions, and in various expressions where the value is used with different intent. It is even worse when a constant is a long number and someone might have transposed digits, thereby creating a bug while simultaneously evading the programmer’s search. Likewise, the name e is a poor choice for any variable for which a programmer might need to search. It is the most common letter in the English language and likely to show up in every passage of text in every program. In this regard, longer names trump shorter names, and any searchable name trumps a constant in code. If a variable or constant might be seen or used in multiple places in a body of code, it is imperative to give it a search-friendly name. Once again compare for (int j=0; j<34; j++) { s += (t[j]*4)/5; } } Note that sum, above, is not a particularly useful name but at least is searchable. The intentionally named code makes for a longer function, but consider how much easier it will be to find WORK_DAYS_PER_WEEK than to find all the places where 5 was used and filter the list down to just the instances with the intended meaning. Avoid Encodings We have enough encodings to deal with without adding more to our burden. Encoding type or scope information into names simply adds an extra burden of deciphering. It hardly seems reasonable to require each new employee to learn yet another encoding “lan- guage” in addition to learning the (usually considerable) body of code that they’ll be work- ing in. It is an unnecessary mental burden when trying to solve a problem. Encoded names are seldom pronounceable and are easy to mis-type. Hungarian Notation In days of old, when we worked in name-length-challenged languages, we violated this rule out of necessity, and with regret. Fortran forced encodings by making the first letter a code for the type. Early versions of BASIC allowed only a letter plus one digit. Hungarian Notation (HN) took this to a whole new level. HN was considered to be pretty important back in the Windows C API, when every- thing was an integer handle or a long pointer or a void pointer, or one of several implemen- tations of “string” (with different uses and attributes). The compiler did not check types in those days, so the programmers needed a crutch to help them remember the types. In modern languages we have much richer type systems, and the compilers remember and enforce the types. What’s more, there is a trend toward smaller classes and shorter functions so that people can usually see the point of declaration of each variable they’re using. int realDaysPerIdealDay = 4; const int WORK_DAYS_PER_WEEK = 5; int sum = 0; for (int j=0; j < NUMBER_OF_TASKS; j++) { int realTaskDays = taskEstimate[j] * realDaysPerIdealDay; int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK); sum += realTaskWeeks; Class Names Classes and objects should have noun or noun phrase names like Customer, WikiPage, Account, and AddressParser. Avoid words like Manager, Processor, Data, or Info in the name of a class. A class name should not be a verb. Method Names Methods should have verb or verb phrase names like postPayment, deletePage, or save. Accessors, mutators, and predicates should be named for their value and prefixed with get, set, and is according to the javabean standard.4 string name = employee.getName(); customer.setName("mike"); if (paycheck.isPosted())... When constructors are overloaded, use static factory methods with names that describe the arguments. For example, Complex fulcrumPoint = Complex.FromRealNumber(23.0); is generally better than Complex fulcrumPoint = new Complex(23.0); Switch Statements public Money calculatePay(Employee e) throws InvalidEmployeeType { switch (e.type) { case COMMISSIONED: return calculateCommissionedPay(e); case HOURLY: return calculateHourlyPay(e); case SALARIED: return calculateSalariedPay(e); default: throw new InvalidEmployeeType(e.type); } } public abstract class ContainerBase implements Container, Lifecycle, Pipeline, MBeanRegistration, Serializable { /** * The processor delay for this component. */ protected int backgroundProcessorDelay = -1; /** * The lifecycle event support for this component. */ protected LifecycleSupport lifecycle = new LifecycleSupport(this); /** * The container event listeners for this Container. */ protected ArrayList listeners = new ArrayList(); /** * The Loader implementation with which this Container is * associated. */ protected Loader loader = null; /** * The Logger implementation with which this Container is * associated. */ protected Log logger = null; /** * Associated logger name. */ protected String logName = null; Listing 4-2 ContainerBase.java (Tomcat) 62 Chapter 4: Comments Listing 4-2 (continued) ContainerBase.java (Tomcat) /** * The Manager implementation with which this Container is * associated. * protected Manager manager = null; /** * The cluster with which this Container is associated. */ protected Cluster cluster = null; /** * The human-readable name of this Container. */ protected String name = null; /** * The parent Container to which this Container is a child. */ protected Container parent = null; /** * The parent class loader to be configured when we install a * Loader. */ protected ClassLoader parentClassLoader = null; /** * The Pipeline object with which this Container is * associated. */ protected Pipeline pipeline = new StandardPipeline(this); /** * The Realm with which this Container is associated. */ protected Realm realm = null; /** * The resources DirContext object with which this Container * is associated. */ protected DirContext resources = null; /** * * @param title The title of the CD * @param author The author of the CD * @param tracks The number of tracks on the CD * @param durationInMinutes The duration of the CD in minutes */ public void addCD(String title, String author, int tracks, int durationInMinutes) { CD cd = new CD(); cd.title = title; cd.author = author; cd.tracks = tracks; cd.duration = duration; cdList.add(cd); } Package Names : Object Creation : Avoid creating unnecessary objects and always prefer to do Lazy Initialization Object creation in Java is one of the most expensive operation in terms of memory utilization and performance impact. It is thus advisable to create or initialize an object only when it is required in the code. public class Countries { private List countries; public List getCountries() { //initialize only when required if(null == countries) { countries = new ArrayList(); } return countries; } } Quote 2: Never make an instance fields of class public Making a class field public can cause lot of issues in a program. For instance you may have a class called MyCalender. This class contains an array of String weekdays. You may have assume that this array will always contain 7 names of weekdays. But as this array is public, it may be accessed by anyone. Someone by mistake also may change the value and insert a bug! public class MyCalender { public String[] weekdays = {"Sun", "Mon", "Tue", "Thu", "Fri", "Sat", "Sun"}; //some code } Best approach as many of you already know is to always make the field private and add a getter method to access the elements. private String[] weekdays = {"Sun", "Mon", "Tue", "Thu", "Fri", "Sat", "Sun"}; public String[] getWeekdays() { return weekdays; } But writing getter method does not exactly solve our problem. The array is still accessible. Best way to make it unmodifiable is to return a clone of array instead of array itself. Thus the getter method will be changed to. public String[] getWeekdays() { return weekdays.clone(); }