Thursday, January 5, 2012

Static vs. Instance Methods

Static vs. Instance Methods

  • Static methods can access only static data and invoke other static methods.
    • Often serve as helper procedures/functions
    • Use when the desire is to provide a utility or access to class data only
  • Instance methods can access both instance and static data and methods.
    • Implement behavior for individual objects
    • Use when access to instance data/methods is required
  • An example of static method use is Java’s Math class.
    • All of its functionality is provided as static methods implementing mathematical functions (e.g., Math.sin()).
    • The Math class is designed so that you don’t (and can’t) create actual Math instances.
  • Static methods also are used to implement factory methods for creating objects, a technique discussed later in this class.
class Employee {
    String name;
    String ssn;
    String emailAddress;
    int yearOfBirth;
    int extraVacationDays = 0;
    static int baseVacationDays = 10;

    Employee(String name, String ssn) {
        this.name = name;
        this.ssn = ssn;
    }

    static void setBaseVacationDays(int days) {
        baseVacationDays = days < 10? 10 : days;
    }

    static int getBaseVacationDays() {
        return baseVacationDays;
    }

    void setExtraVacationDays(int days) {
        extraVacationDays = days < 0? 0 : days;
    }

    int getExtraVacationDays() {
        return extraVacationDays;
    }

    void setYearOfBirth(int year) {
        yearOfBirth = year;
    }

    int getVacationDays() {
        return baseVacationDays + extraVacationDays;
    }

    void print() {
        System.out.println("Name: " + name);
        System.out.println("SSN: " + ssn);
        System.out.println("Email Address: " + emailAddress);
        System.out.println("Year Of Birth: " + yearOfBirth);
        System.out.println("Vacation Days: " + getVacationDays());
    }
}
To change the company vacation policy, do Employee.setBaseVacationDays(15);
To give one employee extra vacation, do e2.setExtraVacationDays(5);

Wednesday, January 4, 2012

Static vs. Instance Data Fields

Static vs. Instance Data Fields

  • Static (or class) data fields
    • Unique to the entire class
    • Shared by all instances (objects) of that class
    • Accessible using ClassName.fieldName
    • The class name is optional within static and instance methods of the class, unless a local variable of the same name exists in that scope
    • Subject to the declared access mode, accessible from outside the class using the same syntax
  • Instance (object) data fields
    • Unique to each instance (object) of that class (that is, each object has its own set of instance fields)
    • Accessible within instance methods and constructors using this.fieldName
    • The this. qualifier is optional, unless a local variable of the same name exists in that scope
    • Subject to the declared access mode, accessible from outside the class from an object reference using objectRef.fieldName
Say we add the following to our Employee class:
static int vacationDays = 10;
and we print this in the Employee’s print() method:
System.out.println("Vacation Days: " + vacationDays);
In the EmployeeDemo’s main() method, we change vacationDays to 15:
Employee.vacationDays = 15;
Now, e1.print() and e2.print() will both show the vacation days set to 15. This is because both e1 and e2 (and any other Employee object) share the static vacationDays integer field.
The field vacationDays is part of the Employee class, and this is also stored on the heap, where it is shared by all objects of that class.
Static fields that are not protected (which we will soon learn how to do) are almost like global variables — accessible to anyone.
Note that it is possible to access static fields through instance variables (e.g., e1.vacationDays = 15; will have the same effect), however this is discouraged. You should always access static fields by ClassName.staticFieldName, unless you are within the same class, in which case you can just say staticFieldName.

Tuesday, January 3, 2012

Garbage Collection

Garbage Collection

  • Unlike some OO languages, Java does not support an explicit destructor method to delete an object from memory.
    • Instead, unused objects are deleted by a process known as garbage collection.
  • The JVM automatically runs garbage collection periodically. Garbage collection:
    • Identifies objects no longer in use (no references)
    • Finalizes those objects (deconstructs them)
    • Frees up memory used by destroyed objects
    • Defragments memory
  • Garbage collection introduces overhead, and can have a major affect on Java application performance.
    • The goal is to avoid how often and how long GC runs.
    • Programmatically, try to avoid unnecessary object creation and deletion.
    • Most JVMs have tuning parameters that affect GC performance.
Benefits of garbage collection:
  • Frees up programmers from having to manage memory. Manually identifying unused objects (as in a language such as C++) is not a trivial task, especially when programs get so complex that the responsibility of object destruction and memory deallocation becomes vague.
  • Ensures integrity of programs:
    • Prevents memory leaks — each object is tracked down and disposed off as soon as it is no longer used.
    • Prevents deallocation of objects that are still in use or have already been released. In Java it is impossible to explicitly deallocate an object or use one that has already been deallocated. In a language such as C++ dereferencing null pointers or double-freeing objects typically crashes the program.
Through Java command-line switches (java -X), you can:
  • Set minimum amount of memory (e.g. -Xmn)
  • Set maximum amount of memory (e.g. -Xmx, -Xss)
  • Tune GC and memory integrity (e.g. -XX:+UseParallelGC)
For more information, see: http://java.sun.com/docs/hotspot/VMOptions.html and http://www.petefreitag.com/articles/gctuning/

Monday, January 2, 2012

Accessing Objects through References

Accessing Objects through References

Employee e1 = new Employee();
Employee e2 = new Employee();

// e1 and e2 refer to two independent Employee objects on the heap

Employee e3 = e1;

// e1 and e3 refer to the *same* Employee object

e3 = e2;

// Now e2 and e3 refer to the same Employee object

e1 = null;

// e1 no longer refers to any object. Additionally, there are no references
// left to the Employee object previously referred to by e1. That "orphaned"
// object is now eligible for garbage collection.
[Note]Note
The statement Employee e3 = e2; sets e3 to point to the same physical object as e2. It does not duplicate the object. Changes to e3 are reflected in e2 and vice-versa.

Set Thread Name

package org.best.example;

    /*
            Set Thread Name Example
            This Java example shows how to set name of thread using setName method
            of Thread class.
    */
    
    public class SetThreadNameExample {
    
            public static void main(String[] args) {
                  
                    //get currently running thread object
                    Thread currentThread = Thread.currentThread();
                    System.out.println(currentThread);
                  
                    /*
                     * To set name of thread, use
                     * void setName(String threadName) method of
                     * Thread class.
                     */
                  
                    currentThread.setName("Set Thread Name Example");
                  
                    /*
                     * To get the name of thread use,
                     * String getName() method of Thread class.
                     */
                    System.out.println("Thread Name : "+ currentThread.getName());
            }
    }
    
    /*
    Output of the example would be
    Thread[main,5,main]
    Thread Name : Set Thread Name Example
    */

Sunday, January 1, 2012

Java Memory Model

Java Memory Model

  • Java variables do not contain the actual objects, they contain references to the objects.
    • The actual objects are stored in an area of memory known as the heap.
    • Local variables referencing those objects are stored on the stack.
    • More than one variable can hold a reference to the same object.
Figure 1. Java Memory Model
Java Memory Model


As previously mentioned, the stack is the area of memory where local variables (including method parameters) are stored. When it comes to object variables, these are merely references (pointers) to the actual objects on the heap.
Every time an object is instantiated, a chunk of heap memory is set aside to hold the data (state) of that object. Since objects can contain other objects, some of this data can in fact hold references to those nested objects.
In Java:
  • Object references can either point to an actual object of a compatible type, or be set to null (0 is not the same as null).
  • It is not possible to instantiate objects on the stack. Only local variables (primitives and object references) can live on the stack, and everything else is stored on the heap, including classes and static data.



Pause Thread Using Sleep Method

package org.best.example;

    /*
            Pause Thread Using Sleep Method Example
            This Java example shows how to pause currently running thread using
            sleep method of Java Thread class.
    */
    
    public class PauseThreadUsingSleep {
    
            public static void main(String[] args) {
                  
                    /*
                     * To pause execution of a thread, use
                     * void sleep(int milliseconds) method of Thread class.
                     *
                     * This is a static method and causes the suspension of the thread
                     * for specified period of time.
                     *
                     * Please note that, this method may throw InterruptedException.
                     */
                  
                    System.out.println("Print number after pausing for 1000 milliseconds");
                    try{
                          
                            for(int i=0; i< 5; i++){
                                  
                                    System.out.println(i);
                                  
                                    /*
                                     * This thread will pause for 1000 milliseconds after
                                     * printing each number.
                                     */
                                    Thread.sleep(1000);
                            }
                    }
                    catch(InterruptedException ie){
                            System.out.println("Thread interrupted !" + ie);
                    }
                  
            }
    }
    
    /*
    Output of this example would be
    
    Print number after pausing for 1000 milliseconds
    0
    1
    2
    3
    4
    */