DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Coding
  3. Java
  4. Find Java Bugs with FindBugs

Find Java Bugs with FindBugs

Muhammad Ali Khojaye user avatar by
Muhammad Ali Khojaye
CORE ·
Jul. 08, 10 · Interview
Like (0)
Save
Tweet
Share
19.79K Views

Join the DZone community and get the full member experience.

Join For Free

This post is regarding a static analysis tool that finds defects in Java programs. Static analysis tools can find real bugs and real issues in the code. We can effectively incorporate static analysis into our software development process.

FindBugs

FindBugs is an open source static analysis tool that analyzes Java class files, looking for programming defects. The analysis engine reports nearly 300 different bug patterns. Each bug pattern is grouped into a category (e.g., correctness, bad practice, performance and internationalization), and each report of a bug pattern is assigned a priority, high, medium or low.

Let’s start with some of the selected bug categories with the examples.

Correctness

Comparing incompatable types for equality


Consider the following code,

if ((!value.equals(null)) && (!value.equals(""))) {      
  Map spaces = (Map) vm.get(SpaceConstants.AVAILABLESPACEMAP);
}

Onewould expect that the condition would true, when value is not null andis not empty. However, value.equals(null) according to the contract ofthe equals() method, would always return false.


Consider the another similar example,


if ((bean.getNoteRate() != null) && !bean.getNoteRate().equals("") && (bean.getNoteRate() > 0)) {     
  item.setNoteRate(bean.getNoteRate());
}


Wemight expect that the condition would true, when noteRate is not null,not empty and is greater than 0. However, the condition would never betrue.


The reason is that bean.getNoteRate().equals("") wouldalways return false regardless of being equal value. According to thecontract of equals(), objects of different classes should always compare as unequal; therefore, according to the contract defined by java.lang.Object.equals(Object), the result of this comparison will always be false at runtime.

Null pointer dereference

Consider the following code,

if ((list == null) && (list.size() == 0)) {     
  return null;
}


This will lead to a NullPointerException when the code is executed when list is null.


Suspicious reference comparison


Consider the following code,

if (bean.getPaymentAmount() != null    && bean.getPaymentAmount() !=       currBean.getPrincipalPaid()) {          
  // code to execute
}

Thiscode compares two reference values (Double paymentAmount) using the !=operator, where the correct way to compare instances of this type isgenerally with the equals() method. It is possible to create distinct instances that are equal but do not compare as == since they are different objects.


Doomed test for equality to NaN

Consider the following code,

if ((newValue == Double.NaN) || (newValue < 0d)) {            
  // the code to execute
}

This code checks to see if a floating point value is equal to the special Not A Number value. However, because of the special semantics of NaN, no value is equal to Nan, including NaN. Thus, x == Double.NaN always evaluates to false. To check to see if a value contained in x is the special Not A Number value, use Double.isNaN(x) (or Float.isNaN(x) if x is floating point precision).


Also see How can you compare NaN values?.


Method whose return value should not ignore

string is immutable object. So ignoring the return value of the method would consider as bug.

String name = "Muhammad";name.toUpper();if (name.equals("MUHAMMAD"))



Performance


Method invokes inefficient Boolean constructor;use Boolean.valueOf(...) instead


Consider the following code,

if ((record.getAmount() != null) && !record.getAmount().equals(        
  new Boolean(bean.isCapitalizing()))) {            
  // code to execute
}


Creating new instances of java.lang.Boolean wastes memory, since Boolean objects are immutable and there are only two useful values of this type. Use the Boolean.valueOf()method (or Java 1.5 autoboxing) to create Boolean objects instead.


Inefficient use of keySet iterator instead of entrySet iterator

Consider the following code,

Iterator iter = balances.keySet().iterator();        
while (iter.hasNext()) {            
  // code to execute
}

This method accesses the value of a Map entry, using a key that was retrieved from a keySet iterator. It is more efficient to use an iterator on the entrySet of the map, to avoid the Map.get(key) lookup.

Method invokes inefficient Number constructor; use static valueOf instead

Consider the following code,

Integer number1 = new Integer(123);
Integer number2 = Integer.valueOf(123); 
System.out.println("number1 =  " + number1);
System.out.println("number2 =  " + number2);

Usingnew Integer(int) is guaranteed to always result in a new object whereasInteger.valueOf(int) allows caching of values to be done by the classlibrary, or JVM. Using of cached values avoids object allocation andthe code will be faster.


Also see: http://faq.javaranch.com/java/JavaIntermediateFaq#integerAutoBoxing


Method concatenates strings using + in a loop


for (int x = 0; x < exceptions.size(); x++) {    
  errorMessage += getStackTrace(exceptions.get(x) + "\n");
}


In each iteration, the String is converted to a StringBuffer/StringBuilder,appended to, and converted back to a String. This can lead to a costquadratic in the number of iterations, as the growing string isrecopied in each iteration.

Better performance can be obtained by using a StringBuilder explicitly.

Dodgy

Code that is confusing, anomalous, or written in a way that leads itself to errors. Examples include dead local stores, switch fall through, unconfirmed casts, and redundant null check of value known to be null.

instanceof will always return true

The instanceof test will always return true (unless the value being tested is null)

NodeList nodeList = root.getElementsByTagName("node"); 
int nodeListLength = nodeList.getLength(); 
for (int i = 0; i < nodeListLength; i++) {   
  Node node = nodeList.item(i);   
  if (node instanceof Node &&       
      node.getParentNode() == root) {       
    //do code   
  }
}

 

Test for floating point equality

Consider the following code,

private double value = 0d; if (value > diff) {         
  // code to excute
} else if (value == diff) {        
  // code to excute
}

Theabove code compares two floating point values for equality. Becausefloating point calculations may involve rounding, calculated float anddouble values may not be accurate. For values that must be precise,such as monetary values, BigDecimal would be more appropriate.

See Floating-Point Operations

Also see Effective Java 2nd Ed, Item 48:Avoid float and double if exact answers are required

Integral division result cast to double or float

Consider the code,

int x = 2;int y = 5; 
// Wrong: yields result 0.0
double value1 =  x / y;

 

This code casts the result of an integral division operation to double or float.Doing division on integers truncates the result to the integer valueclosest to zero. The fact that the result was cast to double suggeststhat this precision should have been retained. We should cast one orboth of the operands to double before performing the division like

// Right: yields result 0.4double value2 =  x / (double) y; 

References:

Download the latest version of FindBugs.

Visit the blog.

Using the FindBugs Ant task.

Using the FindBugs Eclipse plugin.

PMD

 

From http://muhammadkhojaye.blogspot.com/2010/06/find-java-bugs-with-findbugs.html

Java (programming language) FindBugs

Published at DZone with permission of Muhammad Ali Khojaye, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Kubernetes vs Docker: Differences Explained
  • Why Open Source Is Much More Than Just a Free Tier
  • Easy Smart Contract Debugging With Truffle’s Console.log
  • Deploying Java Serverless Functions as AWS Lambda

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: