10 practical but paranoid Java programming technologies

Source: Internet
Author: User

10 practical but paranoid Java programming technologies

 

After being immersed in coding for a period of time, for example, I have invested about 20 years in the program.) You will gradually become accustomed to these things. Because, you know ......

Anything may go wrong. That's right, indeed.

This is why we need to adopt defensive programming, that is, some reasons for paranoid habits. The following are the 10 most useful but paranoid Java programming technologies I personally think. Let's take a look:

1. Place the String at the beginning

To prevent occasionalNullPointerExceptionException. We usually place the String on the left side of the equals () function to perform String comparison. The following code:

 
  1. // Bad 
  2. If (variable. equals ("literal ")){...}
  3. // Good
  4. If ("literal". equals (variable )){...}

This is something you can do with your mind. From the code of the Bad version to the code of the Good version, nothing will be lost. Welcome to different ideas...

2. Do not trust the early JDK API

In the early days of Java, programming was a very painful thing. The APIs are still immature. You may have encountered the following code blocks:

 
  1. String[] files = file.list(); 
  2. // Watch out
  3. If (files! = Null ){
  4. For (int I = 0; I <files. length; I ++ ){
  5. ...
  6. }
  7. }

Seems paranoid? Maybe, but see Javadoc:

If this virtual path does not represent a folder directory, this method returns null. Otherwise, a string array is returned. Each string represents a file or folder in the directory.

Yes, that's right. We can add some validation:

 
  1. if (file.isDirectory()) { 
  2. String [] files = file. list ();
  3. // Watch out
  4. If (files! = Null ){
  5. For (int I = 0; I <files. length; I ++ ){
  6. ...
  7. }
  8. }
  9. }

3. Do not trust "-1"

I know this is paranoid, but in Javadoc for String. the indexOf () method explicitly states that the position index of the specified character appears for the first time in the object. If it is-1, it indicates that the character is not in the character sequence.

So using-1 is taken for granted, right? See the following code:

 
  1. // Bad 
  2. If (string. indexOf (character )! =-1 ){...}
  3. // Good
  4. If (string. indexOf (character)> = 0 ){...}

Who knows. Maybe they changed the encoding method and the string is not case sensitive. Maybe the better way is to return-2? Who knows.

4. Avoid accidental assignment

Yes. This kind of thing may happen frequently.

 
  1. // Ooops 
  2. If (variable = 5 ){...}
  3. // Better (because causes an error)
  4. If (5 = variable ){...}
  5. // Intent (remember. Paranoid JavaScript: =)
  6. If (5 = variable ){...}

So you can place the Compare constant on the left side, so that no unexpected assignment error will occur.

5. Check Null and Length

In any case, make sure that you have a set, array, and so on, and it is not empty.

 
  1. // Bad 
  2. If (array. length> 0 ){...}
  3. // Good
  4. If (array! = Null & array. length> 0 ){...}

You don't know where these arrays come from, maybe from JDK APIs of earlier versions. Who knows.

6. All methods are final

You may tell me your open/closed principles, but this is all nonsense. I don't believe that you inherit all the sub-classes of my parent class correctly), and I don't believe that I accidentally inherit all sub-classes of my parent class ). Therefore, for those methods with clear meanings, use final identification strictly.

 
  1. // Bad 
  2. Public void boom (){...}
  3. // Good. Don't touch.
  4. Public final void dontTouch (){...}

7. All variables and parameters are final

As I said. I don't believe that I don't want to overwrite my value by myself ). Even so, I don't trust myself because...

... This is why all variables and parameters are final.

 
  1. // Bad 
  2. Void input (String importantMessage ){
  3. String answer = "...";
  4. Answer = importantMessage = "LOL accident ";
  5. }
  6. // Good
  7. Final void input (final String importantMessage ){
  8. Final String answer = "...";
  9. }

8. Do not trust the generic type during overload.

Yes, it can happen. You believe that the super nice-looking API you write is very intuitive. Then, some users simply convert the original type to the Object type until the damn compiler stops complaining, and suddenly they will link the wrong method and think this is your error.

See the following code:

 
  1. // Bad 
  2. <T> void bad (T value ){
  3. Bad (Collections. singletonList (value ));
  4. }
  5. <T> void bad (List <T> values ){
  6. ...
  7. }
  8. // Good
  9. Final <T> void good (final T value ){
  10. If (value instanceof List)
  11. Good (List <?>) Value );
  12. Else
  13. Good (Collections. singletonList (value ));
  14. }
  15. Final <T> void good (final List <T> values ){
  16. ...
  17. }

Because, you know ...... Your users are like

 
  1. // This library sucks 
  2. @ SuppressWarnings ("all ")
  3. Object t = (Object) (List) Arrays. asList ("abc ");
  4. Bad (t );

Believe me. I have seen all this. Including the following

This type of paranoia is good.

9. An exception is always thrown in the Default of the Switch statement.

Switch statement ...... I don't know whether to fear or cry about one of them, but in any case, since we insist on using the switch, we may wish to use it perfectly. Let's look at the following code:

 
  1. // Bad 
  2. Switch (value ){
  3. Case 1: foo (); break;
  4. Case 2: bar (); break;
  5. }
  6. // Good
  7. Switch (value ){
  8. Case 1: foo (); break;
  9. Case 2: bar (); break;
  10. Default:
  11. Throw new ThreadDeath ("That'll teach them ");
  12. }

When value = 3, a prompt cannot be found, so it is not unknown.

10. The Switch statement is enclosed in curly brackets.

In fact, switch is the most evil statement, such as some people who are drunk or have a bet are writing code. Let's look at the example below:

 
  1. // Bad, doesn't compile 
  2. Switch (value ){
  3. Case 1: int j = 1; break;
  4. Case 2: int j = 2; break;
  5. }
  6. // Good
  7. Switch (value ){
  8. Case 1 :{
  9. Final int j = 1;
  10. Break;
  11. }
  12. Case 2 :{
  13. Final int j = 2;
  14. Break;
  15. }
  16. // Remember:
  17. Default:
  18. Throw new ThreadDeath ("That'll teach them ");
  19. }

In a switch statement, each case statement has only one row of statements. In fact, these case statements are not even true statements, just like the jump mark in a goto statement.

Conclusion

Paranoid programming seems incredible, sometimes because code is often proven to be more detailed, but not required. You may think, "Oh, this will never happen," but as I said. After about 20 years of programming, you don't want to fix these stupid bugs, because the programming language is so old and flawed. Because you know...

Now you are ready! What are the most paranoid quirks in programming?

Top 10 Useful, Yet Paranoid, Java Programmer Techniques

 

 

 

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.