Java Objects && Garbage Collection Tutorial

I needed to make a simple object in Java and decided to do quick write up on how you can design your own objects in Java. Most of what is going to be covered on objects will carry over to other languages, you’ll just have to re-adjust to a different syntax. Garbage collection can be handle differently between languages. In Java’s case it’s mostly handled for you but there are a few things you can do to help prevent memory leaks and boost performance.

Also you interested in garbage collection in java then read this short article. It also contains reference links if you still interested.
http://www.leepoint.net/notes-java/background/60garbage_collection.html


I’m just going to crawl through the code and explain things line by line. The “package PoJo;” line is the source folder where this code is contained in my project. I named it PoJo because this folder would be dedicated to java objects and PoJo stands for “Plain old Java objects”.

The next four lines are the variables contained in this object. Private means that can’t “normally” be accessed outside the class source code unless specificity allowed to. In this object case, I wan’t every student to have an id ( integer ), gpa score ( double ), first name ( string ), last name ( string ), and a middle initial ( char ).

package PoJo;

public class Student {
	private int id;
	private double gpa;
	private String firstName, lastName;
        private char middleInitial;

Next lets move onward on coding a constructor. A constructor controls how an object will be initialized, and you can create multiple constructors if needed. The next code snippet will be the default constructor in this class. In my case I want every integer and double to have a default value of -1 to make sure it’s easy to check error value inside the object. Strings and characters are set to there null values.

public Student(){
	this.id = -1;
	this.gpa = -1;
	this.firstName = null;
	this.lastName = null;
	this.middleInitial = '\u0000';
}

Now as you can imagine having this code doesn’t help to much because we will then have to later set each variable value. The next constructor has all the parameters need to set every variable and is pretty long so I’m going to break it up in parts. In my case I only want to accept student IDs within the range of 1 – 1000000, if a id of 1000001 gets passed in then the default value will be set at -1 and write out a message out to standard error. In the line, this.id = id, is where we set the objects id variable with the id variable passed in the parameter.

Student( int id, String firstName, char middleInitial, String lastName, double gpa ){
	if ( id > 0 && id <= 1000000 )
		this.id = id;
	else {
		this.id = -1;
		System.err.println("Invalid id input; Set at -1!");
	}

Next is the code block that sets the gpa but before that I’m going to mention that Java you don’t need to create a deconstructor. I’m not going to cover whats a deconstructor is but you shouldn’t ever need the create within Java. You can do something similar to a deconstructor with using finalize but that’s more of a sanity check the any real use. Back on track, I only want to accept values between gpa scores between 0 and 4. If any other double is passed in the Student’s gpa variable will be set to -1.

	if ( gpa >= 0.0 & gpa <= 4.0)
		this.gpa = gpa;
	else {
		this.gpa = -1;
		System.err.println("Invalid gpa input; Set at -1!");
	}

This next snippet contains the code blocks for setting the first name and last name since I handled them in the same fashion. I only want to accept strings that are at least two characters long and not over 50 characters long. I’m sure 50 is over kill for anyone’s first or last name but at this point I’m not too worried about unnaturally long strings being inserted into my object.

        if ( firstName.length() >= 2 && firstName.length() <= 50)
			this.firstName = firstName;
	else{
		this.firstName = null;
		System.err.println("Invalid first name input; Set at null!");
	}
		
	if ( lastName.length() >= 2 && lastName.length() <= 50)
		this.lastName = lastName;
	else{
		this.lastName = lastName;
		System.err.println("Invalid last name input; Set at null!");
	}

One more variable left to set. The following snippet will set the middle initial variable for our Student object. This one might be a little more confusing the other ones. The first line sets the object variable to the parameters upper case equivalent. If someone enters an ‘f’ the variable will be set to ‘F’. The next if statement might seem somewhat weird to you and before I explain it let me tell you this. Strings are made up characters, and characters are really just numbers. In this if statement it will check if new uppercase letter is out of range of for being an character between ‘A’ and ‘Z’. If you want to check what a character’s integer value is you could just cast it as a integer. Here is how you can cast in Java, (int) someChar, and if you put that into a print statement it will display it’s integer value. Also the null value for a character is ‘\u0000’.

        this.middleInitial = Character.toUpperCase( middleInitial );

	if( this.middleInitial < 65 || this.middleInitial > 90 ){
		this.middleInitial = '\u0000';
		System.err.println("Invalid middle initial input; Set at null!");
	}

Not done yet, remember this was also a garbage collection tutorial. This is where it that section comes in. The following parameter variables are being set to their null values. Java takes care of garbage collection for the most part but doing this will help guard against memory leaks and may boost performance of the garbage collection process.

	id = 0;
	gpa = 0;
	firstName = null; 
	lastName = null;
	middleInitial = '\u0000';
}

That’s it for the coverage on constructors, I have few more constructors in my source code but their all essentially coded in the same way. Next lets move on to getters. Since I made my class variables to private I need to create methods that return the variables if I want them to be called outside the Student class object. Getters are super simple and can be written in a single line. Here are my Student object’s getters.

public int    getID()            { return( this.id );            }
public double getGPA()           { return( this.gpa );           }
public String getFirstName()     { return( this.firstName );     }
public String getLastName()      { return( this.lastName );      }
public char   getMiddleInitial() { return( this.middleInitial ); }

It can also be useful to create methods that can alter the value of the Student objects internal variables. The method code will look familiar to the code snippet from the constructor and I’m not going to cover all of my setters. I’ll post my full source code at the bottom of the post if you want to check it out. I pick this method out because it’s the only one that more unique. The first line sets the parameter value to the uppercase letter of the parameter’s character. Essentially we are creating an new upper case character using the parameter and setting the parameter with this new value.

public void setMiddleInitial( char middleInitial ){
	middleInitial = Character.toUpperCase( middleInitial );
	if( middleInitial >= 65 || middleInitial <= 90 )
		this.middleInitial = middleInitial;
	else
		System.err.println("Invalid last name input; Set at" + this.lastName +"!");
		
	middleInitial = '\u0000';
}

My object has a few extra methods but for the most part are just generic auto-generated methods created by my IDE. Here is the full source code of my Student object.

/* PoJo.Student
 * Class object for a student's data
 * 
 * Author: Daniel Moore
 * ----------------------------------------------------------------
 * Class Constructors:
 *   Student()
 *   Student( int id )
 *   Student( String firstName, String lastName )
 *   Student( int id, String firstName, String lastName )
 *   Student( int id, String firstName, String lastName, long gpa )
 *   Student( String firstName, char middleInitial, String lastName )
 *   Student( int id, String firstName, char middleInitial, String lastName )
 *   Student( int id, String firstName, char middleIntial, String lastName, long gpa )
 *
 * ----------------------------------------------------------------
 * Class Methods:
 *
 *  - Getters
 * 	public int    getID()         
 *	public double   getGPA()       
 *	public String getFirstName() 
 *	public String getLastName()
 *  public char   getMiddleInitial()
 *
 *  - Setters  
 *	public void setID( int id )
 *	public void setGPA( double gpa ) 
 *	public void setFirstName( String firstName )
 *	public void setMiddleInitial( char middleInitial )
 *
 * - Custom Override Method
 *	public String toString()
 *
 * - Auto-Generated Methods  
 *	public int     hashCode()
 *	public boolean equals(Object obj)
 * ----------------------------------------------------------------
 * Variable Error Values:
 *   id = -1
 *   gpa = -1
 *   firstName = null
 *   lastName = null
 *   middleInitial = \u0000
 * ----------------------------------------------------------------
 * Variable Requirements:
 *   id must be between 1 to 1000000
 *   gpa must be between 0.0 to 4.0
 *   firstName length must be between 2 characters to 50 characters
 *   lastName length must be between 2 characters to 50 characters
 *   middleInitial must be between 'A' to 'Z' ( middleInital >= 65 Or middleInital <= 90 )
 * -----------------------------------------------------------------
 * Example Case:
 *   Student bit = new Student( 1, Bit, Diddler, 4.0 );
 *   bit.id = 1
 *   bit.firstName = Bit
 *   bit.lastName = Diddler
 *   bit.middleInitial = \u0000
 *   bit.gpa = 4.0
 *   
 * -----------------------------------------------------------------
 * ToDo's:
 *  - Log Reporting for invalid inputs
 *    * As of now error messages are just sent to standard error.
 *  - Re-design equals(obj)
 *    * As of now the compared object must have all the same fields to return true
*/

package PoJo;

public class Student {
	private int id;
	private double gpa;
	private String firstName, lastName;
	private char middleInitial;
	
	public Student(){
		this.id = -1;
		this.gpa = -1;
		this.firstName = null;
		this.lastName = null;
		this.middleInitial = '\u0000';
	}
	
	public Student( int id ) {
		if ( id > 0 && id <= 1000000 )
			this.id = 1;
		else
			this.id = -1;
		
		this.gpa = -1;
		this.firstName = null;
		this.lastName = null;
		this.middleInitial = '\u0000';
		
		id = 0;
	}
	
	public Student( String firstName, String lastName ){
		this.id = -1;
		this.gpa = -1;
		
		if ( firstName.length() > 2 && firstName.length() <= 50)
			this.firstName = firstName;
		else{
			this.firstName = null;
			System.err.println("Invalid first name input; Set at null!");
		}
		
		if ( lastName.length() > 2 && lastName.length() <= 50)
			this.lastName = lastName;
		else{
			this.lastName = lastName;
			System.err.println("Invalid last name input; Set at null!");
		}
		
		this.middleInitial = '\u0000';
		
		firstName = null;
		lastName = null;
	}
	
	public Student( int id, String firstName, String lastName ) {
	
		if ( id > 0 && id <= 1000000 )
			this.id = id;
		else {
			this.id = -1;
			System.err.println("Invalid id input; Set at -1!");
		}
		
		this.gpa = -1;
		
		if ( firstName.length() > 2 && firstName.length() <= 50)
			this.firstName = firstName;
		else{
			this.firstName = null;
			System.err.println("Invalid first name input; Set at null!");
		}
		
		if ( lastName.length() > 2 && lastName.length() <= 50)
			this.lastName = lastName;
		else{
			this.lastName = lastName;
			System.err.println("Invalid last name input; Set at null!");
		}
		
		this.middleInitial = '\u0000';
		
		id = 0;
		firstName = null; 
		lastName = null;
	}
	
	public Student( int id, String firstName, String lastName, long gpa ){
		if ( id > 0 && id <= 1000000 )
			this.id = id;
		else {
			this.id = -1;
			System.err.println("Invalid id input; Set at -1!");
		}
		
		if ( gpa >= 0.0 & gpa <= 4.0)
			this.gpa = gpa;
		else {
			this.gpa = -1;
			System.err.println("Invalid gpa input; Set at -1!");
		}
		
		if ( firstName.length() >= 2 && firstName.length() <= 50)
			this.firstName = firstName;
		else{
			this.firstName = null;
			System.err.println("Invalid first name input; Set at null!");
		}
		
		if ( lastName.length() >= 2 && lastName.length() <= 50)
			this.lastName = lastName;
		else{
			this.lastName = lastName;
			System.err.println("Invalid last name input; Set at null!");
		}
		
		this.middleInitial = '\u0000';
			
		id = 0;
		gpa = 0;
		firstName = null; 
		lastName = null;
	}
	
	public Student( String firstName, char middleInitial, String lastName ) {
		this.id = -1;
		this.gpa = -1;
		
		if ( firstName.length() > 2 && firstName.length() <= 50)
			this.firstName = firstName;
		
		else{
			this.firstName = null;
			System.err.println("Invalid first name input; Set at null!");
		}
		
		if ( lastName.length() > 2 && lastName.length() <= 50)
			this.lastName = lastName;
		
		else{
			this.lastName = lastName;
			System.err.println("Invalid last name input; Set at null!");
		}
		
		this.middleInitial = Character.toUpperCase( middleInitial );
		
		if( this.middleInitial < 65 || this.middleInitial > 90 ){
			this.middleInitial = '\u0000';
			System.err.println("Invalid middle initial input; Set at null!");
		}
			
		firstName = null; 
		lastName = null;
		middleInitial = '\u0000';
	}
	public Student( int id, String firstName, char middleInitial, String lastName ){
		if ( id > 0 && id <= 1000000 )
			this.id = id;
		else {
			this.id = -1;
			System.err.println("Invalid id input; Set at -1!");
		}
		
		this.gpa = -1;
		
		if ( firstName.length() > 2 && firstName.length() <= 50)
			this.firstName = firstName;
		else{
			this.firstName = null;
			System.err.println("Invalid first name input; Set at null!");
		}
		
		if ( lastName.length() > 2 && lastName.length() <= 50)
			this.lastName = lastName;
		else{
			this.lastName = lastName;
			System.err.println("Invalid last name input; Set at null!");
		}
		
		this.middleInitial = Character.toUpperCase( middleInitial );
		
		if( this.middleInitial < 65 || this.middleInitial > 90 ){
			this.middleInitial = '\u0000';
			System.err.println("Invalid middle initial input; Set at null!");
		}
			
		id = 0;
		firstName = null; 
		lastName = null;
		middleInitial = '\u0000';
	}
	
	public Student( int id, String firstName, char middleInitial, String lastName, double gpa ){
		if ( id > 0 && id <= 1000000 )
			this.id = id;
		else {
			this.id = -1;
			System.err.println("Invalid id input; Set at -1!");
		}
		
		if ( gpa >= 0.0 & gpa <= 4.0)
			this.gpa = gpa;
		else {
			this.gpa = -1;
			System.err.println("Invalid gpa input; Set at -1!");
		}
		
		if ( firstName.length() > 2 && firstName.length() <= 50)
			this.firstName = firstName;
		else{
			this.firstName = null;
			System.err.println("Invalid first name input; Set at null!");
		}
		
		if ( lastName.length() > 2 && lastName.length() <= 50)
			this.lastName = lastName;
		else{
			this.lastName = lastName;
			System.err.println("Invalid last name input; Set at null!");
		}
		
		this.middleInitial = Character.toUpperCase( middleInitial );
		
		if( this.middleInitial < 65 || this.middleInitial > 90 ){
			this.middleInitial = '\u0000';
			System.err.println("Invalid middle initial input; Set at null!");
		}
			
		id = 0;
		gpa = 0;
		firstName = null; 
		lastName = null;
		middleInitial = '\u0000';
	}
	
	public int    getID()            { return( this.id );            }
	public double getGPA()           { return( this.gpa );           }
	public String getFirstName()     { return( this.firstName );     }
	public String getLastName()      { return( this.lastName );      }
	public char   getMiddleInitial() { return( this.middleInitial ); }
	
	public void setId(int id) {
		if ( id > 0 && id <= 1000000 )
			this.id = id;
		else
			System.err.println("Invalid ID input; Set at" + this.id +"!");
		id = 0;
	}

	public void setGPA(double gpa) {
		if ( gpa >= 0.0 & gpa <= 4.0)
			this.gpa = gpa;
		else
			System.err.println("Invalid GPA input; Set at" + this.gpa +"!");
		
		gpa = 0;
	}

	public void setFirstName(String firstName) {
		if ( firstName.length() > 2 && firstName.length() <= 50)
			this.firstName = firstName;
		else
			System.err.println("Invalid first name input; Set at" + this.firstName +"!");
		
		firstName = null;
	}
	
	public void setLastName( String lastName ) {
		if ( lastName.length() > 2 && lastName.length() <= 50 )
			this.lastName = lastName;
		else
			System.err.println("Invalid last name input; Set at" + this.lastName +"!");
		
		lastName = null;
	}
	
	public void setMiddleInitial( char middleInitial ){
		middleInitial = Character.toUpperCase( middleInitial );
		if( middleInitial >= 65 || middleInitial <= 90 )
			this.middleInitial = middleInitial;
		else
			System.err.println("Invalid last name input; Set at" + this.lastName +"!");
		
		middleInitial = '\u0000';
	}
	
	@Override
	public String toString() {
		return (this.lastName + ", " + this.firstName + " " + this.middleInitial +". \n"
				+"ID: " + this.id + "; GPA: " + this.gpa );
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((firstName == null) ? 0 : firstName.hashCode());
		long temp;
		temp = Double.doubleToLongBits(gpa);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		result = prime * result + id;
		result = prime * result
				+ ((lastName == null) ? 0 : lastName.hashCode());
		result = prime * result + middleInitial;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (firstName == null) {
			if (other.firstName != null)
				return false;
		} else if (!firstName.equals(other.firstName))
			return false;
		if (Double.doubleToLongBits(gpa) != Double.doubleToLongBits(other.gpa))
			return false;
		if (id != other.id)
			return false;
		if (lastName == null) {
			if (other.lastName != null)
				return false;
		} else if (!lastName.equals(other.lastName))
			return false;
		if (middleInitial != other.middleInitial)
			return false;
		return true;
	}	
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s