Reprint----Write high-quality code: 151 recommendations for improving Java programs (1th: Common methods and guidelines in Java Development ___ recommended)

Source: Internet
Author: User
Tags random seed

Read Catalogue

    • Recommendation 1: Do not appear in constants and variables easily confusing letters
    • Recommendation 2: Never let a constant degenerate into a variable
    • Recommendation 3: The types of ternary operators must be consistent
    • Recommendation 4: Avoid method overloads with variable-length parameters
    • Recommendation 5: Do not allow null values and null values to threaten the variable length method

The reasonable man adapts himself and the world; The unreasonable one persists in trying to adapt the world himself.

A sensible man adapts himself to the world; an unknown man wants the world to adapt to himself.

-------Bernard Shaw

 This department article is used to document reading notes from the book "151 recommendations for writing high-quality code to improve Java programs." Easy to view, but also convenient for everyone to check, thanks to the original book author Qin Xiaobo Java's unique insights to help Java enthusiasts grow. As a result of the space I will take the reading notes in batches of memory to share, the book a total of 12 chapters, a total of 151 suggestions, including the first chapter of the Java grammar itself proposed 51 recommendations; the 4th to 9th chapter focuses on the use of the JDK API to put forward 80 recommendations; Section 10~ Chapter 12 provides 20 suggestions for program performance, open source tools and frameworks, coding styles, and programming ideas. According to the directory structure of the book, I read this book gradually, special record here.

I first read this book is 1.5 ago, at that time not careful, just understand some of the problems, at that time feel that this book can also, now 1 years later will he turned out, start looking again, feel understanding or the first time to see the charm of different places, so suggest that you must carefully understand reading, not to seek speed,   To taste carefully, because read how many books, not to go out to blow a good, I have read which books, with a short time outside the ..... Books are read to themselves, to promote themselves, so be careful to understand, think first, and apply. Technical books are similar, the principle is unchanged, so carefully read a technical book, later read other books on this kind of technology, your understanding will be more profound, compared to the rapid reading of a number of books on the one hand technology, the last is smattering, only know it, do not know why.

The world of Java rich and colorful, but also full of economic traps, everyone accidentally may fall into the abyss of darkness, only after understanding its rules can be their own in the technology of the sea to fly, wanton gallop. A journey to the ground, this chapter focuses on issues related to the Java Language Foundation and the considerations for the proposed solutions and variables, how to secure serialization, how to assert how to use it, etc.

Back to top recommendation 1: Do not appear in constants and variables prone to confusing letters

The package name is all lowercase, the class name is all uppercase, the constants are all capitalized and separated by underscores, the variables are named after the camel case, and these are the most basic Java coding specifications, the rules that each javaer should be familiar with, but be careful not to introduce easily confusing letters in the declaration of variables. Try reading the following code to think about how I is printing the result:

1 public class demo{2 public     static void Main (string[] args) {3         test01 (); 4     } 5      6 public     static void Test01 () {7         long i=1l; 8         System.out.println (twice Times of "I": "+ (I+i)); 9     }10}

Some people will say: This simple example can be wrong? The running result is definitely 22! Practice is the only standard to test truth, run it for a look, perhaps you will be very strange, the result is 2, not 22. Is there a problem with the compiler and a "2" missing?

Because the value assigned to the variable i is the number "1", only the long integer variable is appended with the letter "L". Don't say I dug a hole to make you jump. If a similar program appears in the project, this scenario may occur when you try to read the code to understand the author's ideas. So in order to make your program easier to understand, the letter "L" (including the capital letter "O") Try not to mix with the numbers, so as not to confuse the reader's understanding with the procedural intent. If the letters and numbers are mixed, the letter "L" must be capitalized, and the letter "O" will add comments.

Note: Be sure to capitalize the letter "L" as a long-integer flag .

Back to top recommendation 2: Never let a constant degenerate into a variable

Constant metamorphosis into a variable? How can you change the constants that add final and static? It is impossible to assign a value to this. Is it really impossible? Look at the following code:

1 Import java.util.Random; 2  3 public class Demo01 {4 publicly     static void main (string[] args) {5         test02 (); 6     } 7  8 public     St atic void test02 () {9         System.out.println ("Constant will change OH:" + constant.rand_const);}11}12-Interface Constant     {14
   public static final int rand_const = new Random (). Nextint (); 15}

Is Rand_const a constant? will its value change? Will definitely change! The definition of this constant is absolutely undesirable, the constant is a constant, at compile time must determine its value, should not be changed at run time, otherwise the program readability is very poor, even the author himself can not determine what happened during the run time what magical things.

Don't think about using the constant variable function to implement the sequence number algorithm, random seed generation, unless this is really the only project in the program, otherwise give up, constant or when the constant is used.

Note: Be sure to keep the value of the constant at run time.

Back to top recommendation 3: The type of ternary operator must be consistent

The ternary operator is a simplified notation for if-else, where it is used in a wide variety of areas, and is very useful, but easy to use and simple does not mean that it can be used arbitrarily, see the following code:

1 public static void test03 () {2         int i = 80;3         String str = string.valueof (i < 90:100); 4         String str1 = String.valueof (i < 90:100.0); 5         System.out.println ("whether the two are equal:" + str.equals (str1)); 6     }

Analyze this procedure, I is 80, less than 100, the return value of both must be 90, and then turn to string type, its value is absolutely equal, no doubt. Well, the analysis is a bit of a point, but the second operand of the ternary operator in the variable str is 100, and the second operand in str1 is 100.0, does the wood have an effect? It's impossible to have an effect, the conditions of the ternary operator are true, only the first value is returned, and the second value has a yarn relationship, seemingly justified.

After running, the result is: "Are they equal: false", not equal, why?

The problem is on the 100 and 100.0 of the two numbers, in the variable str, the first operand of the ternary operator 90 and the second operand 100 are of type int, the same type, the result returned is the type of int 90, and the variable str1 the first operand (90) is an int type, The second operand 100.0 is a floating-point number, that is, the type of two operands is inconsistent, the ternary operator must return a data, and the type to determine, it is not possible to return the int type when the condition is true, the conditions are false when the float type, the compiler is not allowed to do so, it will convert the type int to float 90 .0, that is, the return value of the ternary operator is a floating-point number 90.0, then of course, and the integer 90 is not equal. Why is the integer type converted to floating point instead of floating-point type? This involves the conversion rules for the ternary operator type:

    1. If two operands are not convertible, no conversion is made and the return value is object type;
    2. If the two operand is a definite type of expression (such as a variable), then the normal binary number conversion, int to Long,long to float, etc.
    3. If one of the two operands is a number s, the other is an expression, and its type is the flag bit T, then if the number S is in the range of T, then the T is converted to the type "s", if S is beyond the range of T
    4. If the two operands are direct numbers, the return value type range is larger.

  Know what the reason, the corresponding solution is also: to ensure that the ternary operator of the two operands of the same type, to avoid this error.

Back to top tip 4: Avoid method overloads with variable-length parameters

In the project and system development, in order to improve the flexibility and reusability of the method, we often have to pass an indeterminate number of parameters into the method, the common design technique before JAVA5 is to define the formal parameter as the collection type or its subclass type, or the array type. The disadvantage of this approach is that null parameters need to be judged and filtered, compared to null values and collection or arrays of length 0. and JAVA5 introduced the variable-length parameter (varags) is in order to better the reusability of the method, so that the method of the caller can be "arbitrary" to pass the number of arguments, of course, the variable length parameter is also to follow certain rules, such as the variable length parameter must be the last parameter in the method , a method cannot define multiple variable length parameters, and so on, these basic rules need to be kept in mind, but even if you remember these rules, there is still the possibility of errors, see the following code:

1 public class Client {2 public     static void Main (string[] args) {3         Client client = new Client (); 4         //499 Yuan of goods 75 percent 5         client.calprice (499), 6     } 7  8     //Simple discount calculation 9 public     void Calprice (int price, int discount) { Ten         Float knockdownprice = Price * discount/100.0f;11         System.out.println ("After a simple discount is:" + formatcurrency ( Knockdownprice));     }13     //complex multi-discount calculation of the public     void Calprice (int price, int ... discounts) {         float Knockdownprice = price;17 for         (int discount:discounts) {             knockdownprice = Knockdownprice * Discount/ 100;19         }20         System.out.println ("The price after the complex discount is:" + formatcurrency (knockdownprice));     }22     String FormatCurrency (float price) {         numberformat.getcurrencyinstance-return (). Format (price);     }26}

This is a simulation of the product discount, with two parameters of the Calprice method (the business logic of the method is: to provide the original price and discount rate of goods, you can get the discount price of the commodity) is a simple discount calculation method, which is often used in the actual project, this is a single discount method. The Calprice method with variable-length parameters is called the more complex discount calculation mode, multiple discount stacking operations (simulation class is a relatively simple implementation) are often seen in practice, such as during the sale of VIP members once again discounted; or the day is your birthday, and give you a 90 percent, That is the folding of the slang.

Business logic clear, let's take a closer look at these two methods, are they overloaded? Of course, the definition of overloading is: "The method name is the same, the parameter type or the number is different", it is obvious that these two methods are overloaded. But this overload is a bit special, and the parameter category of Calprice (int price, int ... discounts) covers the parameter category of Calprice (int price,int discount). The question comes out: for Calprice (499,75), which method should be called to deal with?

We know the Java compiler is very clever, it will be compiled based on the method signature to determine the method called, such as: Calprice (499,75,95) This call, it is obvious that 75 and 95 will be converted to a two element array, and passed to Calprice (int Price,int ... Discounts), because only this method conforms to this argument type, which is easy to understand. But now we are dealing with Calprice (499,75) Call, this 75 can be compiled into an int type of 75, can also be compiled into an int array {75}, which contains only an array of one element. So which method should I call? The result is: "The price after the simple discount is: 374.25". It appears that the first method was called, why would the first method be called instead of the second variable-length method? Because Java at compile time, first of all according to the number and type of arguments (here 2 arguments, all of the int type, note does not turn into an int array) for processing, that is, to find Calprice (int price,int discount) method, and confirm if he meets the method signature criteria. The question now is why the compiler would first find the method based on an argument of the two int type instead of an int type, an int array type argument?

Because int is a native data type, and the array itself is an object, the compiler wants to "lazy", so it will start from the simplest "guess", as long as the compilation criteria can be passed, so this problem occurs.

The problem is clear, in order to let our program can be "human" to understand, or careful consideration of variable length parameters of the method overload it, or let people bother not to say, maybe one day into this kind of small traps.

Back to top recommendation 5: Do not let null values and Null values threaten the variable length method

The previous recommendation explains the overloading of variable-length parameters, and this recommendation will continue to discuss the overloading of variable-length parameters, the previous recommendation is that the range of variable-length parameters covers the range of non-variable length parameters, and this discussion is about two methods of variable-length parameters, the code is as follows:

1 public class Client5 {2  3 public     void MethodA (String str, Integer ... is) {4  5     } 6 7 public     Voi d MethodA (String str, string ... strs) {8  9}10 public     static void Main (string[] args) {         CLIENT5 cl IENT5 = new Client5 (),         Client5.methoda ("China", 0), and         Client5.methoda ("China", "people");         Client5.methoda ("China"):         Client5.methoda ("China", null);     }18}

Two MethodA are overloaded, and now the problem is: the above Client5.methoda ("China"), Client5.methoda ("China", NULL), compilation does not pass, prompt the same: The method is ambiguous, The compiler does not know which method to call, but the flavor of the two code reactions is different.

For the MethodA ("China") method, according to the argument "China" (string type), two methods conform to the formal parameter format, the compiler does not know to call that method, then error. Let's think about this: CLIENT5 This class is a complex business logic that provides two overloaded methods, called from other modules (local calls to system or remote system calls from outside the system), and the number of parameters passed in variable-length parameters can be N (n>= 0), of course, it can be written Client5.methoda ("China") method Ah! Fully conform to the specification, but this makes the compiler and caller depressed, the program conforms to the rules but can not run, so the question, who's responsibility? Is the designer of the Client5 class, he violated the kiss principle (Keep It smile,stupid, that is, lazy principle), according to this design method should be a call, but now follow the specification but compile does not pass, which for designers and developers should be banned.

For Client5.methoda ("China", null), the direct amount of NULL is no yo type, although the two MethodA methods meet the call requirements, but do not know which one to call, so the error. After careful analysis, there is a very bad coding habit, except that it does not conform to the lazy principle above, that is, the caller hides the argument type, which is very dangerous, not only the caller needs to "guess the call that method", and the callee may also produce internal logic chaos. For this example, this should be modified:

1 public static void main (string[] args) {2         Client5 client5 = new Client5 (); 3         String strs[] = null;4         client5.m Ethoda ("China", STRs); 5     }

That is, let the compiler know that this null value is a string type, the compilation can pass smoothly, also reduce the occurrence of errors.

Reprint----Write high-quality code: 151 recommendations for improving Java programs (1th: Common methods and guidelines in Java Development ___ recommended)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.