Writing high-quality code: 151 suggestions for improving Java programs (Chapter 1: common methods and guidelines for JAVA Development ___ recommendation 6 ~ 10), java151

Source: Internet
Author: User

Writing high-quality code: 151 suggestions for improving Java programs (Chapter 1: common methods and guidelines for JAVA Development ___ recommendation 6 ~ 10), java151
Recommendation 6: The override variable length method is also well-behaved.

In JAVA, it is common to override a parent class in a subclass. This can fix bugs or provide extended service function support, it also complies with the Open-Closed Principle ).

Main features of Open-Closed Principle:

1. Open for extension ). This means that the behavior of the module can be expanded. When the application needs to change, we can expand the module to meet the new changes. That is to say, we can change the function of the module.

2. Closed for modification ). You do not need to modify the source code or binary code of the module when extending the module behavior. The binary executable version of the module, whether it is a connectable library, DLL or. EXE file, does not need to be changed.

Next, let's take a look at the conditions that must be met:

See the following code:

1 public class Client6 {2 public static void main (String [] args) {3 // converts 4 Base base = new Sub (); 5 base. fun (100, 50); 6 // No transformation 7 Sub sub = new Sub (); 8 sub. fun (100, 50); 9} 10} 11 12 // Base class 13 class Base {14 void fun (int price, int... discounts) {15 System. out. println ("Base ...... fun "); 16} 17} 18 19 // subclass, override parent class method 20 class Sub extends Base {21 @ Override22 void fun (int price, int [] discounts) {23 System. out. println ("Sub ...... fun "); 24} 25}

In this program, the sub. fun (100, 50) error is reported, prompting that the fun (int, int) method cannot be found. This is strange: The subclass inherits all the attributes and methods of the parent class, whether the render manager is private or public access permission, the same parameter, the same method name, there is no problem with calling through the parent class, but it cannot be compiled through the subclass call. Why? Is it difficult to inherit it? Or does the subclass reduce the preconditions of the parent class method? If so, it should not be overwritten. @ Override should report an error.

In fact, the base Object transforms the subclass object upwards. The parameter list is determined by the parent class. Because it is a variable-length parameter, during compilation, the base. fun (100, 50); the 50 real parameter in will be "guessed" by the compiler and compiled into the "{50}" array, and then executed by the Sub class. Let's take a look at the situation of directly calling subclass. At this time, the compiler will not convert the "50" block type because the array itself is also an object, the compiler is not smart enough to convert between two classes without inheritance relationships. You must know that JAVA requires strict type Matching. If the type does not match, the compiler will naturally reject the execution, and give an error message.

This is a special case. The override method parameter list is actually different from the parent class, which violates the overwrite definition and causes inexplicable errors. Therefore, when you overwrite the variable length parameter, if you want to use a similar method, Please carefully think about whether it is necessary to do so.

Note: The override method parameters are the same as the parent class, not only the type and quantity, but also the display form.

Recommendation 7: guard against auto-increment traps

I remember when I first started learning C language, the teacher said: auto-increment has two forms: I ++ and I, I ++, which indicate that the values are assigned first and then 1, ++ I adds 1 first and then assigns a value. After many years of understanding this, I still have problems. I didn't doubt whether my understanding was wrong until I encountered the following code:

1 public class Client7 {2     public static void main(String[] args) {3         int count=0;4         for(int i=0; i<10;i++){5             count=count++;6         }7         System.out.println("count = "+count);8     }9 }

What is the count output by this program? Is it count auto-increment 10 times? The answer is 10? To be sure, the running result is count = 0. Why?

Count ++ is an expression that returns values. Its return value is the value before count auto-increment. Java processes auto-increment as follows: first, copy the count value (note that it is a value, not a reference) to a temporary variable area, then return the value of the Temporary Variable Area to the count variable + 1. The procedure for the first loop is as follows:

The "count = count ++" statement can be understood in the following code:

1 public static int mockAdd (int count) {2 // first save the initial value 3 int temp = count; 4 // perform the auto-increment operation 5 count = count + 1; 6 // return the original value 7 return temp; 8}

So after the first loop, the count value is 0, and the other 9 cycles are the same. In the end, you will find that the count value remains unchanged and remains in the initial state.

In this example, the author of the Code is expected to increase the count, so it is only possible to assign a value to itself. I did not expect to adjust it to the Java auto-increment trap. The solution is very simple, change "count = count ++" to "count ++. This problem has different implementations in different language Environments: In C ++, "count = count ++" is equivalent to "count ++, PHP maintains the same processing method as JAVA. The auto-increment implementation methods vary in each language.

Recommendation 8: Do not bother you with the old syntax
1 public class Client8 {2 public static void main (String [] args) {3 // data definition initialization 4 int bytes = 200; 5 // Other business processing 6 saveDefault: save (expiration); 7} 8 9 static void saveDefault () {10 System. out. println ("saveDefault .... "); 11} 12 13 static void save (int finished) {14 System. out. println ("save .... "); 15} 16}

This code analyzes the output results and syntax meanings:

Recommendation 9: Use less static Import

The import static syntax (import static) was introduced from Java 5 to reduce the input of characters and improve the readability of the code, so as to better understand the program. Let's take a look at an example without static import, that is, general import:

1 public class Client9 {2 // calculate the circular area 3 public static double claCircleArea (double r) {4 return Math. PI * r; 5} 6 7 // calculate the ball area 8 public static double claBallArea (double r) {9 return 4 * Math. PI * r; 10} 11}

This is a very simple method. java is introduced in the two calculation methods. lang. the PI (circumference rate) constant in the Math class (this class is imported by default) is a little redundant, especially if there are many methods in the Client9 class. If you need to input the Math class every time, it is cumbersome and redundant. Static import can solve this problem. The program after static import is used is as follows:

1 import static java. lang. math. PI; 2 3 public class Client9 {4 // calculate the circular area 5 public static double claCircleArea (double r) {6 return PI * r; 7} 8 9 // calculate the ball area 10 public static double claBallArea (double r) {11 return 4 * PI * r; 12} 13}

The function of static import is to introduce Pi constants in the Math class into this class. This will make the program simpler and easier to read. As long as you see PI, you will know that this is the circumference rate, you don't have to write all the class names every time. However, misuse of static import makes the program more difficult to read and maintain. After static import, the class name does not need to be written in the code, but we know that the class is a description of a class of things ", without class name modification, the representation meaning of static attributes and static methods can be infinitely magnified, which makes it difficult for readers to figure out what their attributes or methods represent, all the attributes (methods) of the rope need to be considered (the IDE friendly prompt function is also mentioned). It is a nightmare to introduce all static import elements of a class. Let's take a look at the following example:

1 import static java. lang. math. *; 2 import static java. lang. double. *; 3 import static java. lang. integer. *; 4 import static java. text. numberFormat. *; 5 6 import java. text. numberFormat; 7 8 public class Client9 {9 10 public static void formatMessage (String s) {11 System. out. println ("Circle Area:" + s); 12} 13 14 public static void main (String [] args) {15 double s = PI * parseDouble (args [0]); 16 NumberFormat nf = getInstance (); 17 nf. setMaximumFractionDigits (parseInt (args [1]); 18 formatMessage (nf. format (s); 19 20} 21}

It is annoying to look at such a program. The constant PI knows the circumference rate. The parseDouble method may be a conversion method of the Double class, which can be guessed by the name. Which class is the getInstance () method next? Is Client9 a local class? No, this method is not available locally. It turns out to be a NumberFormat class method. There is no difference between this method and the local formatMessage method-this code is too hard to read, and someone must swear by me.

Therefore, for static import, we must follow two principles:

What is a tool class with clear representations? Let's look at the example of using static import in Junit:

1 import static org. junit. assert. *; 2 class DaoTest {3 @ Test4 public void testInsert () {5 // assertEquals 6 ("foo", "foo"); 7 assertFalse (Boolean. FALSE); 8} 9}

We can easily determine from the program that the assertEquals method is used to assert whether the two values are equal. The assertFalse method is an assertexpression that is false, which indeed reduces the amount of code, the code readability is also improved, which is also a benefit of using the correct static import.

Recommendation 10: Do not overwrite static import variables and methods in this class.

What will happen if the methods and attributes in a class are the same as those in static import? See the following code.

1 import static java. lang. math. PI; 2 import static java. lang. math. abs; 3 4 public class Client10 {5 // The constant name is the same as that of the static import PI 6 public final static String PI = "zuchongzhi "; 7 // The method name is the same as the static import method. 8 public static int abs (int abs) {9 return 0; 10} 11 12 public static void main (String [] args) {13 System. out. println ("PI =" + PI); 14 System. out. println ("abs (-100) =" + abs (-100); 15} 16}

The code above defines a constant PI of the String type and an abs method, which is the same as static import. First, let's talk about the good news. There is no error in the Code. Next, there is a bad message: we don't know which attribute and method to call. Because the constant name and method name are the same, what method is called? The result is as follows:

PI = "zuchongzhi", abs (-100) = 0;
Obviously, the local method is called. Why not call the attributes and methods in the Math class? That's because the compiler has"Shortest Path" principle: If you can find related variables, constants, and methods in this class, you will not find them in other packages, parent classes, or interfaces, to ensure that the attributes and methods in this class are preferred.

  Therefore, if you want to change a method to be statically imported, the best way is to refactor the method in the original class, rather than overwrite it in the class.

 

Related Article

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.