Method
38th: Check the validity of the parameters
Check the parameters at the beginning of the method body, and for public methods, use the @throws tab of Javadoc to describe the exception that is thrown when the parameter value limit is violated in the document
/**
* @throws arithmeticexception if M is less than or equal to 0
/public
BigInteger mod (BigInteger m) {
I F (m.signum () <= 0) {
throw new ArithmeticException ("modulus <= 0:" + m);
}
Non-public methods should usually use assertions to check their arguments
Private helper function for a recursive sort
private static void sort (long a[], int offset, int length) {
Asse RT a!= null;
Assert offset >= 0 && offset <= a.length;
}
Assertions will throw assertionerror once they fail
For some parameters, the method itself is not used, but is saved for later use, to test the validity of such parameters is particularly important (such as the constructor parameters of the test)
Before a method performs its computational task, it should examine its parameters, with the exception of the rule, an important exception being that, in some cases, the validity check is very expensive or impractical at all, and the validity check has been implicitly performed in the calculation, such as Collections.sort (List), where one of the comparison operations is thrown classcastexception
Sometimes, some calculations implicitly perform the necessary validation checks, but if the check is unsuccessful, the wrong exception is thrown, in which case the exception thrown in the calculation should be converted to the correct exception (the exception indicated in the document) 39th: Protective copies when necessary
While it is not possible for another class to modify the internal state of an object without the help of an object, it is easy for an object to provide this help unconsciously, as in the following class
Public final class Period {
private final Date start;
Private final Date end;
Public Period (date start, date end) {
if (Start.compareto) > 0)
throw new IllegalArgumentException (
Start + "after" + end);
This.start = start;
This.end = end;
}
This class seems immutable, however, because the date class itself is mutable
Date start = new Date ();
Date end = new Date ();
Period p = new Period (start, end);
End.setyear (78); Modifies internals of p!
In order to protect the internal information of the period instance from this attack, a protective copy of each variable parameter of the constructor is necessary
Public Period (date start, date end) {
This.start = new Date (Start.gettime ());
This.end = new Date (End.gettime ());
if (This.start.compareTo (this.end) > 0)
throw new IllegalArgumentException (start + "after" + End);
}
A protective copy is done before checking the validity of the parameter, and the validity check is for the object after the copy, not for the original object 40th: Careful design method signature carefully chooses the name of the method. Naming conventions do not overly pursue the means of providing convenience. Each method should do its best, and too many methods can make it difficult to learn, use, document, test, and maintain a parameter list that is too long to avoid. The target is four parameters, or less, you can use the Builder mode to allow the client to make multiple "setter" calls to 41st: careful with overloading
public class Collectionclassifier {public
static String classify (set<?> s) {return
' Set ';
}
public static String classify (list<?> s) {return
"List";
}
public static String classify (collection<?> s) {return
"Unknown Collection";
}
public static void Main (string[] args) {
collection<?>[] collections = {
new hashset<string> (), C12/>new arraylist<biginteger> (),
new hashmap<string, string> (). VALUES ()
};
for (collection<?> c:collections) {
System.out.println (classify (c));}}}
The above example expects the program to print "Set", "List" and "Unknown Collection", but actually print "Unknown Collection" three times
The reason is that the classify method is overloaded, and which overloaded method to call is made at compile time, and for (collection<?> c:collections) in the example above causes each call to be classify (Collection <?>) This overloaded method
The overridden method (override) is selected based on the Run-time type of the object to which the method is invoked
For overloading, a safe and conservative strategy is to never export two overloaded methods with the same number of arguments 42nd: Cautious with variable parameters
The variable parameter method accepts 0 or more parameters of the specified type, and the variable parameter mechanism creates an array first, the size of the array is the number of arguments passed at the call position, and then passes the parameter values to the array, and finally the array is passed to the method
Suppose you determine that a call to a method 95% will have 3 or fewer parameters, declare 5 overloads of the method, each with 0 to 3 normal parameters, and a variable parameter method when the number of arguments exceeds 3
public void Foo () {} public
void foo (int a1) {} public
void foo (int a1, int a2) {} public
void foo (int a1, int A2, int a3) {} public
void foo (int a1, int a2, int a3, int ... rest) {}
43rd: Returns an array or collection of 0 lengths, rather than null
For a method that returns null instead of a 0-length array or collection, almost every time the method is used, additional code is needed to handle the null return value 44th: Write documentation comments for all exported API elements
In order to properly write API documents, you must add a document comment before each exported class, interface, constructor, method, and domain declaration
A document annotation of a method should succinctly describe the contract between it and the client. Explains what this method does, each parameter should have a @param label, and a @return label (unless the return type is void) and every exception that is thrown for the method, whether it is examined or not , there is a @throws tag, and if the method starts a background thread, it should also be stated in the document General programming 45th: Minimize the scope of local variables
Minimizing the scope of local variables can enhance the readability and maintainability of your code and reduce the likelihood of errors
The best way to minimize the scope of a local variable is to declare 46th at the place where it was first used : The For-each loop takes precedence over the traditional for loop
The For-each loop avoids the possibility of confusion and error by completely hiding an iterator or index variable, and there is no performance penalty
There are three common scenarios where you cannot use the For-each loop: 1. Filtering-if you need to traverse the collection and delete the selected elements, you need to use an explicit iterator so that you can call its Remove Method 2. Conversion--If you need to traverse a list or array and replace some or all of its element values, You need a list iterator or an array index, to set the value of the element 3. Parallel iterations-If you need to traverse multiple sets in parallel, you need to explicitly control iterators or index variables so that all iterators or index variables can be synchronized forward 47th: Understanding and Using class libraries
By using standard class libraries, you can take advantage of the knowledge of these experts who write standard class libraries, as well as the experience of others
Programmers should spend their time on applications, not on the bottom of the details 48th: If you need precise answers, avoid using float and double
The float and double types are designed primarily for scientific calculations and engineering calculations, and they perform binary floating-point operations designed to provide more accurate, fast approximation calculations on a wide range of numerical ranges. Therefore, they do not provide exact results, so they should not be used in situations where precise results are required.
Such as
System.out.println (1.00-0.42);
The result is: 0.5800000000000001
The correct way to solve this problem is to use BigDecimal, int, or long
BigDecimal a = new BigDecimal (1.00);
BigDecimal B = new BigDecimal (0.42);
System.out.println (A.subtract (b));
Output is 0.58
There are two disadvantages to using BigDecimal: This is inconvenient and very slow compared to using the basic operation type
In addition to using BigDecimal, there is also a way to use int or long, and to record decimal points themselves, if the range of values does not exceed 9 decimal digits, you can use the int, if not more than 18 digits, you can use long, if the number may be more than 18 digits, You must use BigDecimal 49th: The base type takes precedence over the boxed base type
There are three main differences between the base type (int, double, Boolean) and the boxed base type (Integer, double, Boolean) first, the base type has only a value, and the boxed base type has a different identity than their value. The base type has only a full-featured value, and each boxed base type also has a non-functional value: null third, the base type usually saves time and space more than the boxed base type
When the base type and the boxed base type are mixed in an operation, the boxed base type is automatically disassembled
The case of boxed base types should be used: as elements, keys, and values in a collection list<integer> 50th: If other types are more appropriate, avoid using string strings as a substitute for other value types, such as int, Boolean String does not fit in place of enum type
String does not fit in lieu of a clustered type
String Compoundkey = className + "#" + I.next ();
This approach has many drawbacks, such as having to parse the string in order to access a separate domain. A better practice is to simply write a class that describes the dataset, usually a private static member class
Strings are also not suitable for the ability table (strings are used to authorize access to a feature) 51st: Beware the performance of string concatenation
The string concatenation operator (+) is a convenient way to combine multiple strings into one string, but it is not suitable for use in large-scale scenarios. To use the string concatenation operator repeatedly for connecting n strings, you need the time of the square level of N. This is because two strings are concatenated together and their contents are copied
It is recommended that you use StringBuilder instead of string 52nd: Referencing an object through an interface
If a suitable interface type exists, then for parameters, return values, variables, and fields, you should declare them using the interface type
If the base type of the object is a class, not an interface, you should refer to the object with the relevant base class (often an abstract class) instead of its implementation class 53rd: The interface takes precedence over the reflection mechanism
The core reflection mechanism, Java.lang.reflect, provides the ability to access information about loaded classes through a program. Given a class instance, you can get constructor, method, and field instances
The reflection mechanism (reflection) allows a class to use another class, even if the current person is compiled without the latter. However, this ability also comes at a price: loss of the benefits of compile-time type checking, including the very clumsy and lengthy performance penalty required for exception checking for reflection access, and a much slower reflection method invocation than normal method calls
Typically, a normal application should not be able to access objects in a reflective manner at run time
For some programs, they must use classes that cannot be acquired at compile time, but there is an appropriate interface or superclass at compile time, through which they can refer to the class. In this case, you can create instances in reflection, and then access these instances in the normal way through their interfaces or superclass, as in the following example
public static void Main (string[] args) {
//Translate the class name into a class object
class<?> cl = null;
try {
cl = Class.forName (Args[0]);
} catch (ClassNotFoundException e) {
System.err.println ("Class not Found. ");
System.exit (1);
}
Instantiate the class
set<string> s = null;
try {
s = (set<string>) cl.newinstance ();
} catch (Illegalaccessexception e) {
System.err.println ("Class not accessible.");
System.exit (1);
} catch (Instantiationexception e) {
System.err.println ("Class not instantiable.");
System.exit (1);
}
Exercise the Set
s.addall (Arrays.aslist (args). sublist (1, args.length));
System.out.println (s);
}
The above program creates a set<string> instance whose class is specified by the first command-line argument that inserts the remaining command-line arguments into the collection
This program can easily become a generic collection tester that validates a specified set implementation by hacking through one or more collection instances and checking to see if the set interface's conventions are adhered to. In the vast majority of cases, it is this approach that is needed to use the reflection mechanism
Reflection mechanism is a powerful mechanism, it is necessary for a particular complex system programming task, if possible, to instantiate an object using only the reflection mechanism, while accessing an object using an interface known at compile time or a superclass 54th: Use local methods with care
The practice of using local methods to improve performance is not worth advocating
There are some serious drawbacks to using the local method because the local language is not secure, so applications that use local methods are no longer immune to memory corruption errors, and the associated fixed cost is required when entering and exiting local code 55th: Careful optimization
To try to write good programs rather than fast programs, good programs embody the principle of information hiding: whenever possible, they centralize design decisions in a single module
Efforts to avoid design decisions that limit performance, interactions between modules, and components that interact with the outside world may have serious limitations on what the system should achieve
Consider the performance consequences of API design decisions, such as making public types variable, which can lead to a large number of unwanted protected copies
The Profiling Tools help you decide where you should focus your optimization, such tools can provide you with run-time information, such as how much time each method spends, how many times it is invoked, and even whether you need to change the algorithm 56th: adherence to universally accepted naming conventions
identifier type |
example |
package |
C Om.google.inject |
class or interface |
timer,futuretask |
method or domain |
REMOVE,ISDIGIT,GETCRC |
constant field |
min_value |
Local Change Amount |
i,xref |
type parameter |
t,e,k,v |