Google

Aug 8, 2013

Core Java Best Practices -- Part 1

"Best Practices" is one of the key areas, and often you can impress your interviewers, peers, and code reviewers by applying the best practices to your code.  Here is a sample class that can be used as a key to store data in Maps or in Hibernate queries to as where clause parameters. The best practices applied are

  1. Make your objects immutable where possible as immutable classes are inherently thread safe.
  2. Don't reinvent the wheel, and use proven third-party libraries. 
  3.  Use the Comparable interface if you want to sort your objects naturally.
  4. Implement the hashCode( ) and equals( ) method properly.
  5. override the toString( )as it is handy for logging and debugging. 
  6. make the fields final where appropriate. 
  7. Using log4j as opposed to System.out.println(......)

Here is the sample code that implements the above best practices.


package com.myapp;

import com.myapp.ValuationTypeCd;

import java.util.Date;

import javax.annotation.concurrent.Immutable;

import org.apache.commons.lang.builder.CompareToBuilder;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;



@Immutable
public class DECalcRunKey implements Comparable<DECalcRunKey>
{
    private static final Logger LOG = LoggerFactory.getLogger(ReportKey.class);
    
    final private long batchId;
    final private String entity;
    final private Date valuationDate;
    final ValuationTypeCd valuationType;
    
    private DECalcRunKey(long batchId, String entity, Date valuationDate, ValuationTypeCd valuationType)
    {
        super();
        this.batchId = batchId;
        this.entity = entity;
        this.valuationDate = valuationDate;
        this.valuationType = valuationType;
    }
    
    public static DECalcRunKey newInstance(long batchId, String entity, Date valuationDate,
            ValuationTypeCd valuationType)
    {
        Assert.notNull(batchId);
        Assert.notNull(entity);
        Assert.notNull(valuationDate);
        Assert.notNull(valuationType);
        return new DECalcRunKey(batchId, entity, valuationDate, valuationType);
    }
    
    public long getBatchId()
    {
        return batchId;
    }
    
    public String getEntity()
    {
        return entity;
    }
    
    public Date getValuationDate()
    {
        return new Date(valuationDate.getTime()); //defensive copy
    }
    
    public ValuationTypeCd getValuationType()
    {
        return valuationType;
    }
    
    @Override
    public int hashCode()
    {
        return new HashCodeBuilder().append(batchId).append(entity).append(valuationDate).append(valuationType)
                .toHashCode();
    }
    
    @Override
    public boolean equals(final Object obj)
    {
        if (obj instanceof DECalcRunKey)
        {
            final DECalcRunKey runKey = (DECalcRunKey) obj;
            return new EqualsBuilder().append(this.batchId, runKey.batchId)
                    .append(this.entity, runKey.entity).append(this.valuationDate, runKey.valuationDate)
                    .append(this.valuationType, runKey.valuationType)
                    .isEquals();
        }
        return false;
    }
    
    @Override
    public int compareTo(DECalcRunKey runKey)
    {
        return new CompareToBuilder().append(this.batchId, runKey.batchId)
                .append(this.entity, runKey.entity).append(this.valuationDate, runKey.valuationDate)
                .append(this.valuationType, runKey.valuationType).toComparison();
    }
    
    @Override
    public String toString()
    {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
    
} 


You will also like: How to write immutable Java classes? -- Core Java Best Practices -- Part 2

Labels:

1 Comments:

Anonymous Anonymous said...

good tips, but your equals() method is a nullpointerexception waiting to happen.

Best practice would be to return false on null, true on this, and then use the EqualsBuilder to do the actual equality test.

Also, depending on the scenario, use getClass().equals(obj.getClass()) (even if that occasionally leads to issues with proxied classes).

4:29 PM, September 15, 2014  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home