In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article is to share with you about the 10 common problems that are most easily ignored in Java programming. I think it is very practical, so I share it with you. I hope you can get something after reading this article. Let's take a look at it.
In Java coding, we are easy to make some mistakes and neglect some problems, so the author summarizes some classic situations encountered in daily coding and discusses them together.
1. A tangled homonym
Phenomenon
Many classes have the same names (for example, common in exceptions, constants, logs, etc.), resulting in sometimes getting the wrong object in import, which is sometimes hidden. Because classes with the same name often have similar functions, IDE does not prompt warn.
Solve
When you finish writing the code, scan the import section to see if there is anything you are not familiar with. After replacing it with the correct import, you should pay attention to whether the comments are modified accordingly.
Revelation
Try to avoid duplicate names, especially to avoid duplicates with classes in JDK, otherwise it is easy to misimport, and there are a large number of renamed classes, so you need more time to identify them when looking for them.
two。 Of course, API.
Phenomenon
Sometimes when you call API, you take it for granted and call it confidently by name, resulting in some surprising errors:
Example 1: flag is true?
Boolean flag = Boolean.getBoolean ("true")
Maybe it's always false.
Example 2: is this the present day of last year (this year is 2012, regardless of leap years)? The result is still 2012:
Calendar calendar = GregorianCalendar.getInstance ()
Calendar.roll (Calendar.DAY_OF_YEAR,-365)
Here's what happened last year:
Calendar.add (Calendar.DAY_OF_YEAR,-365)
Solution.
Ask yourself a few questions. Am I familiar with this method? Is there a similar API? What's the difference? As far as example 1 is concerned, the differences are as follows:
Boolean.valueOf (b) VS Boolean.parseBoolean (b) VS Boolean.getBoolean (b)
Revelation
Name in more detail, comment more clearly, don't take some API for granted without understanding and testing, and if time is limited, use the API you are most familiar with.
3. Sometimes it's not difficult to overflow.
Phenomenon
Sometimes overflows are not difficult, although they are not often repeated:
Example 1:
Long x=Integer.MAX_VALUE+1
System.out.println (x)
How much is x? Unexpectedly, it is-2147483648, which is still the range of long after adding 1. Similar ones often appear in time calculations:
Number 1 × number 2 × number 3...
Example 2:
In the parameter check to check whether it is a positive number, to avoid overloading, the parameter number is selected, so the result of the following code is less than 0, which is also caused by overflow:
Number i=Long.MAX_VALUE
System.out.println (i.intValue () > 0)
Solve
Let * Operand be long, for example, add L or l (lowercase l is not recommended because it is too similar to the number 1)
When you're not sure, use overloading, that is, using doubleValue (), which won't solve the problem when the argument is a BigDecimal parameter.
Revelation
Be sensitive to the use of numbers: when it comes to numerical computation, consider spillover; when it comes to division, consider the divisor 0; there is really no room for it. Consider things like BigDecimal.
4. Where's the journal?
Phenomenon
Sometimes I think log has been called, why can't I find it?
Example 1: no stack trace!
} catch (Exception ex) {
Log.error (ex)
}
Example 2: log not found!
} catch (ConfigurationException e) {
E.printStackTrace ()
}
Solve
Replace with log.error (ex.getMessage (), ex)
Switch to a normal log4j instead of System.out.
Revelation
The definition of API should avoid making mistakes. If you add an overloaded log.error (Exception), there will be no errors.
In the product code, some methods are used to consider whether they are effective or not, and use e.printStackTrace () to figure out where the Console is.
5. Forgotten Volatile
Phenomenon
In DCL mode, you always forget to add a Volatile.
Private static CacheImpl instance; / / lose volatile
Public static CacheImpl getInstance () {
If (instance = = null) {
Synchronized (CacheImpl.class) {
If (instance = = null) {
Instance = new CacheImpl ()
}
}
}
Return instance
}
Solve
There is no doubt that, with one addition, synchronized locks a piece of code (the whole method or a block of code), ensuring the visibility and atomicity of the "block" code, but instance = = null*** is no longer within the scope of secondary judgment. So it is possible to read out the expired null.
Revelation
We always feel that some low-probability events are difficult to occur, such as the possibility of concurrency at a certain time and the possibility of throwing an exception, so we don't control it, but if we can, we should write code according to the previous "practice". At least you don't have to explain too much about why you take a different approach.
6. Don't affect each other.
Phenomenon
IOException is thrown when multiple IO resources are released, so it is possible to write this to save trouble:
Public static void inputToOutput (InputStream is, OutputStream os
Boolean isClose) throws IOException {
BufferedInputStream bis = new BufferedInputStream (is, 1024)
BufferedOutputStream bos = new BufferedOutputStream (os, 1024)
... .
If (isClose) {
Bos.close ()
Bis.close ()
}
}
Assuming that bos shutdown fails, can bis still shut down? Of course not!
Solution.
Although the same exception is thrown, it is better to catch each one. Otherwise, if you fail, the latter side will have no chance to release resources.
Revelation
There may be dependencies between code / modules, and the dependencies on each other should be fully identified.
7. Replace parameter checking with assertions
Phenomenon
As mentioned in the question, as a common way of defensive programming: assertion, writing in product code for parameter verification, etc. For example:
Private void send (List
< Event>EventList) {
Assert eventList! = null
}
Solve
Replace it with a normal unified parameter calibration method. Because the assertion is off by default, it all depends on the configuration. If you use the default configuration, the result of eventList! = null has not worked, and it is futile.
Revelation
Sometimes, the code doesn't work, not only in the use case, but also in the configuration, such as whether the assertion is enabled, log level, etc., to do useful coding in conjunction with the real world.
8. The cognitive burden of users is sometimes heavy.
Phenomenon
Let's first compare three groups of examples to see which ones look smoother.
Example 1:
Public void caller (int a, String b, float c, String d) {
MethodOne (d, z, b)
MethodTwo (b, c, d)
}
Public void methodOne (String d, float z, String b)
Public void methodTwo (String b, float c, String d)
Example 2:
Public boolean remove (String key, long timeout) {
Future
< Boolean>Future = memcachedClient.delete (key)
Public boolean delete (String key, long timeout) {
Future
< Boolean>Future = memcachedClient.delete (key)
Example 3:
Public static String getDigest (String filePath, DigestAlgorithm algorithm)
Public static String getDigest (String filePath, DigestAlgorithm digestAlgorithm)
Solve
Maintain the order of parameter transfer
Remove becomes delete, which is a little abrupt, and it is better to express it in a unified way.
Keep it expressive and it will look fluent with fewer abbreviations.
Revelation
In the coding process, whether the order or naming of the parameters are unified as far as possible, so that the cognitive burden of the user will be very small, so that the user is not easy to make mistakes or confusion. For example, use enumerations instead of string so that users don't wonder what string to pass, and so on.
9. Ignore the timing and level of logging
Phenomenon
There are two examples:
Example 1: should I keep a log?
Catch (SocketException e)
{
LOG.error ("server error", e)
Throw new ConnectionException (e.getMessage (), e)
}
Example 2: what level of log is recorded?
In the user login system, each failed login:
LOG.warn ("Failed to login by" + username+ ")
Solve
Remove logging: when an exception that requires re-throw is encountered, if everyone handles it first and then throw, too many logs will be logged for an error, so it is not recommended to do so. However, if the exception that goes out of re-throw does not have a complete trace (that is, cause), then * * record it.
If you log in maliciously, there will be too much WARN inside the system, which will make the administrator think it is a code error. You can report back to the user with errors, but do not record the user's wrong behavior unless you want to achieve the purpose of control.
Revelation
Do you want to change the log? What's the score? How do you remember? These are all problems, which must be considered in the light of the specific circumstances:
Is it a user behavior error or a code error?
Whether the recorded log can provide useful information to others without causing too much interference to quickly locate the problem.
10. Forget to set the initial capacity
Phenomenon
In JAVA, we often use Map in Collection as Cache, but we often forget to set the initial capacity.
Cache = new LRULinkedHashMap
< K, V>(maxCapacity)
Solve
What is the impact of initial capacity? Take LinkedHashMap, for example, if the initial capacity is not set to 16 by default, if it exceeds 16 × LOAD_FACTOR, it will resize (2 * table.length), which will be expanded twofold: using Entry [] newTable = new Entry [newCapacity]; transfer (newTable), that is, the entire array Copy. Then for a CACHE that needs to do large capacity, it will change from 16 to a large number of times, and you can imagine how many times you need to do group replication. If the initial capacity setting is large, it will naturally reduce resize, but you may worry that when the initial capacity setting is very large, no Cache content will still take up too much volume. In fact, you can refer to the following table for simple calculation, initially there is no cache content, each object is only a 4-byte reference.
Memory for reference fields (4 bytes each)
Memory for primitive fields
Java type
Bytes required
Boolean
one
Byte
Char
two
Short
Int
four
Float
Long
eight
Double
Revelation
Not only map, but also stringBuffer, etc., all have the process of capacity resize. If the amount of data is large, you can not ignore the initial capacity. Consider setting it, otherwise not only frequent resize but also easy to waste capacity.
In Java programming, in addition to some of the problems enumerated above that are easy to ignore, there are many problems in daily practice.
These are the top 10 common problems that are most easily overlooked in Java programming. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.