N suggestions for improving Java programs

Recommendation 22: handle currency with integer type

I thought about this a long time ago. At that time, I saw that the currencies returned by many e-commerce interfaces were in the unit of "points". So I thought that taking "Yuan" as the unit was more reasonable and more in line with people's thinking logic? Let's look at the following case.

Xiao Ming went to the supermarket to buy a bottle of 4.6 yuan drink with a 5 yuan note. The salesperson should give you 0.4 yuan, but the result printed out by the following program was unsatisfactory and output 0.40000000000036.

public class Proposal_22 {
	public static void main(String[] args) {
		System.out.println(5.00 - 4.60);
	}
}

In fact, the reason is that in the computer world, floating-point numbers are not necessarily accurate. The decimal system of 0.4 is converted into binary decimals using the "multiply 2, round and arrange in order" method. Finally, it is found that 0.4 cannot be accurately expressed in binary. In the binary world, it is an infinite circular decimal.

All right, so I'll fix it for him soon?

public class Proposal_22 {
	public static void main(String[] args) {
		NumberFormat f = new DecimalFormat("#.##");
		System.out.println(f.format(5.00 - 4.60));
	}
}

0.4 is printed at this time. Yes, it seems to solve the problem, but there will be a big gap in the results in mass calculation. For example, the bank accounting system requires accuracy and must not allow such errors. The solutions here also include:
1. Use BIgDecimal: specially designed to make up for the defect that floating-point numbers cannot be calculated accurately;
2. Use integer: expand the value of parameters and operations by 100 times. It is generally used in retail industry and has simple operation.

  Scan VX for Java data, front-end, test, python and so on

Recommendation 24: boundary, boundary, or boundary

Recently, Huawei has produced a very popular folding screen mobile phone MetaX. Assuming that the mobile phone needs to be booked one month in advance, and it specifies the maximum number of products that a channel can purchase, the background logic is as follows:

public class Proposal_24 {
	// The maximum quantity a channel can buy
	public final static int LIMIT = 2000;

	public static void main(String[] args) {
		// Number of mobile phones owned by current channel providers
		int cur = 1000;
		Scanner scanner = new Scanner(System.in);
		System.out.println("Please enter the quantity to be booked:");
		while (scanner.hasNextInt()) {
			int order = scanner.nextInt();
			// Sum of currently owned and ready to order products
			if (order > 0 && order + cur <= LIMIT) {
				System.out.println("You have successfully booked" + order + "Products");
			} else {
				System.out.println("Exceeding the limit, reservation failed");
			}
		}
	}
}

The logic seems to be very simple. I don't interpret it one by one. I tried several tests. The results are as follows:

The first two test results are normal, one is not out of limit, the other is out of limit, but the last result is a little strange. It is reasonable to say that it must be out of limit. Is the number 2147483647 familiar? Yes, it is the maximum value of int in Java. The current order is this value, plus 1000, and the result is - 2147482649. This result must be less than the positive number 2000. This kind of problem is that the number exceeds the boundary, which invalidates the verification conditions. In WEB development, both the front end and the back end must verify the data submitted by the user.

Recommendation 33: do not override static methods

When you see this suggestion, you may be puzzled. Java override itself is for non static methods, not static methods. Although it cannot be overridden, it can be hidden:

public class Proposal_33 {
	public static void main(String[] args) {
		Base base = new Sub();
		// Call non static method
		base.doAnything();
		// Call static method
		base.doSomething();
	}
}

class Base {
	public static void doSomething() {
		System.out.println("I am the static method of the parent class");
	}

	public void doAnything() {
		System.out.println("I am a non static method of the parent class");
	}
}

class Sub extends Base {
	public static void doSomething() {
		System.out.println("I am a static method of a subclass");
	}

	@Override
	public void doAnything() {
		System.out.println("I am a non static method of a subclass");
	}
}

It's no problem to see that the doAnything() method of the subclass of the program overrides the method of the parent class. What about doSomething()? It has the same name as the parent method, the same input and output, and is also overridden by reason. What is the fact?

The result is confusing. What is the reason for calling subclass methods, one executing subclass methods and the other executing parent methods?

We know that the instance object has two types: surface type and actual type. The surface type is the type at the time of declaration and the actual type is the type at the time of generation. In this example, the surface type of base is base and the actual type is Sub. For non static methods, it is executed according to the actual type of the object; For static methods, it is special. It is accessed through the class name, followed by the object. If it is a static method called through the object, the JVM will find the entry of the static method through the surface type of the object. It is not surprising that the above program prints "I am the static method of the parent class".

It can also be seen from this example that the practice of overriding static methods is recommended to be abandoned.

  Scan VX for Java data, front-end, test, python and so on

Tags: Java Back-end

Posted on Mon, 06 Dec 2021 15:11:09 -0500 by killsite