Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Thursday, July 18, 2019

How memory works in Java?

As a developer, it is extremely important to understand how memory management in java works. It can help avoid creating difficult to trace problems.

This blog post would give a simplistic view of memory management in java.

With respect to memory management of Java applications, you need to understand two terms, the stack and the heap
The memory of a Java application is divided into two sections, the STACK and the HEAP.

STACK

In a single Java application, there can be one or more than one stack(s). That is, each thread in Java has its own stack.

Stack is a last in first out data structure. The JVM knows exactly when the data on the stack can be destroyed.
All local variables are created on the stack, and they are automatically popped from the stack on encountering the closing braces of the block that created the variable.

As each thread has its own stack, the data on the stack can only be seen by the thread that owns the stack.

HEAP

Heap allows us to store data that has a longer lifetime than a single code block.
In an application you have a single heap, that is shared across all threads.
In java all objects are stored on the heap.
For an object on the heap, the pointer reference to it will be stored on the stack.

Monday, July 15, 2019

Java Strings


String literals and String Objects


String s1 = "abc";
String s2 = "abc";

Both string s1 and s2 refer to the same string object and value residing in the string literal pool.


String A = new String("abc");
String B = new String("abc");


The two strings A & B are two different string objects, because we used the string constructor to create these two objects. These live in the heap.

Usually you would create string literals over string objects because it gives the compiler a chance to optimize your code.

Immutability of strings.


Strings are also immutable in java. For understanding immutability you can read my post here.

Since strings are immutable, we have classes like StringBuilder and StringBuffer to make string like objects that are immutable.
Both StringBuilder and StringBuffer provide methods like append(), insert(), delete(), substring(), toString() etc. for string manipulation.

You can look at the String APIs here.

StringBuilder vs. StringBuffer


StringBuffer is thread safe as its methods are synchronized whereas StringBuilder is not.


String equality


Given below are three strings.

String a = "hello";
String b = "hello";
String obj = new String("hello");

What would the following equality operators return?

a==obj; // false
a==b; // true
a.equals(obj); //true
a.equals(b); //true

P.S From Java9, strings are now stored as byte arrays instead of char arrays.

Tuesday, July 9, 2019

Java Static Initialization vs. Instance Initialization - When to use which?


Static Initialization

Typically static initialization block is used to initialize static variables of a class. The block is called at the time of class initialization. It is called only once. You can initialize static variables inline. If more complicated logic is required for initialization, a static initialization block can be used. The static initialization blocks are called in the order in which they occur, and they are called before the constructors.

For example:


The output of the above code is as shown below.


Instance Initialization

Instance Initialization or Initializer Block is called whenever an instance of the class is created.
It can be used to execute code that is common to all constructors. This block is executed before the constructor is executed.

For example:

The output of the above code is as shown below.


Ref: https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

Thursday, March 31, 2016

Accessing Solr Cloud on AWS from SolrJ

We have a Solr cloud installation on AWS EC2 instances. We use the SolrJ Client from our Java application. Till date we used to have a Solr Cloud installation on our local machine in order to test the code against. As the team started growing, we realized that we should have a way to access the AWS Solr Cloud from our local boxes, so that the Solr Cloud setup on local is not a blocker for feature development.

When I started looking around the web for a solution to this issue, I had to mix a few things from a few different documentation pages and this stackoverflow page. Decided to write this blog post to help out others who are running into the same issue. I hope it helps.

So first let's try to understand the reason behind why you get the java.net.UnknownHostException from the SolrJ client.
When the solr cloud is run, each instance registers itself with the zookeeper that is running. This is done with the private IP of the solr machine. So when SolrJ connects to zookeeper, it gets the private IP. And then SolrJ tries to hit the Solr instance with the private IP, leading to an unknown host exception.

In order to get around this you can follow these steps:
Step 1: Run the solr instance with a host name. Zookeeper will use this hostname.
./bin/solr start -cloud -h hostname -p 8985 -z localhost:2181

Step 2: Add the host entry to the /etc/hosts file on your local machine corresponding to the public ip of the solr machine.

And you are done. You can run the java application that uses SolrJ client on your local machine and access the Solr Cloud running on your AWS instance :)

Monday, October 26, 2015

Interfaces in Java8

Interfaces are a key feature of object oriented programming. An interface provides a set of methods that an implementing class must provide. One can assign instances of the class to variables of the interface type. As of Java8, an interface can contain default methods that an implementing class can inherit or override. Default methods (also known as Defender Methods) enable us to add new functionalities to interfaces without breaking the classes that implements the interface.


1. Declaring an interface

Interfaces are declared by specifying a keyword "interface"


2. Implementing an interface

The class implementing the interface has to provide the implementation of all the methods in the interface


The @Override annotation tells the compiler that this method is inherited from the interface.

Output



3. Default methods in Interface

Java 8 onwards, you can provide default implementation of methods in interfaces. If the class implementing the interface does not provide an implementation of the method, then the default implementation is used.


Let's change the main() method to call the newMethod. Observe that the interface implementation has not changed.



4. Using Default Methods or Abstract Classes

After the introduction of default methods, it may seem that there are no differences between abstract classes, and interfaces. However, it is not so. Abstract classes can define constructor. They can have a state associated with them. In contrast, default methods can only be implemented in terms of invoking other interface methods, with no reference to a particular implementation's state.

5. Default methods and Multiple inheritance ambiguity

A Java class can implement multiple interfaces. Each interface can define default method with same method signature, therefore, the methods can conflict with each other.

Let's consider an example:
Declare two interfaces with default methods implemented with the same method signature.




The above code will give a compilation error:
java: class InterfaceImpl inherits unrelated defaults for method() from types InterfaceA and InterfaceB

We need to provide an implementation of the default method in order to resolve this conflict.



Summary

To summarise, default methods enable addition of new functionality without breaking existing implementations.
When we extend an interface containing the default method, we can do one of the following:
1. Not override the default method and the implementing class will inherit the default method.
2. Override the default method similar to other methods we override in subclass.
3. Redeclare default method as abstract, which forces the subclass to override it.

Reference: Java Documentation and D Zone

Tuesday, July 28, 2015

Immutability in Java - What it takes to build an immutable class


Immutability means something that cannot be changed. In java an immutable class is one whose state cannot be changed once it has been created. This post aims to give a guideline on how to make a class immutable. The post contains an example of creating an immutable class.
The complete code is available on Github

The Java documentation gives a list of guidelines for creating an immutable class. We will try to understand it better.

To make a class immutable, follow the following steps:
  1. Declare the class as final. 
  2. Make all its fields final and private.
  3. For all mutable fields, make sure that the class creates a copy and only returns the copy to the calling code.
  4. Do not provide any setter methods.

Let's try to understand why we need to do all of the above for making a class immutable. We need to ensure that the subclasses do not override any of the class methods. Declaring the class as final ensures that the class cannot be overridden. A more sophisticated approach is to make the constructor private and use a factory method to create an instance of the class. Making all the fields private will ensure that the fields cannot be changed outside the class, and making them final will ensure that we do not alter the field even by mistake. For all the mutable fields, we are making sure that no other object from outside can change the data by creating a defensive copy of the object and only returning this copy to the calling code. Setter methods are usually used to change the state of the object and as the goal of an immutable class is to avoid state changes, hence we do not provide any setter methods.

Lets look at an example of Immutable class:



We have three fields in the class, first field of Integer type, second field of String type, and third field of Date type. The String and Integer classes are immutable, however the Date class is mutable. Thus, we create a new Date object when assigning the Date to the class field.
That's all for immutability.


Reference: Java Documentation

Tuesday, July 14, 2015

Getting Started with TestNG

TestNG is a testing framework which, inspired by JUnit and NUnit, but introduces things like dependency testing, grouping concept to make testing more powerful and easier to do. It is designed to cover all categories of tests: unit, functional, end-to-end, integration, etc...
The NG in TestNG stands for Next Generation. TestNG requires JDK7 or higher.
Reference: http://testng.org/doc/index.html

In this post, we will be discussing how to use TestNG to write a simple test:

Firstly, add the TestNG library in the pom.xml


Lets create a simple Java class that has a method that returns the String passed to it.


Create a test case like this:


Thats it, a simple TestNG test case is created.


Tuesday, August 12, 2014

Multiple Java Installations on OSX and switching between them

Sometimes it may be necessary to have two versions of java on your OSX, and to switch between the two in a fast,reliable and convenient manner. This post aims to show how this can be achieved.

I am currently using version 10.9.4 of OSX, and I was required to have both JAVA6 and JAVA7 on my system, as some of the codebases I was working on were dependent on JAVA6 and some were dependent on JAVA7.

Download the required jdk versions from Oracle downloads page.

After the installations are done, run the following command to know the java version currently being used.
$java -version
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

Run the following command. Replace 1.6 with the version you want to switch to.
$/usr/libexec/java_home -v 1.6
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

Export the output of the above code as JAVA_HOME as follows:
$export JAVA_HOME="/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home"

Now run the command to know the java version:
$java -version
java version “1.6.0_65”
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

In this way, switching between the two versions can be done easily.

Monday, August 11, 2014

Java Inheritance - Super keyword

Inheritance is an important principle in object oriented programming. It is a mechanism in which one object acquires the property of another. The object which gives the properties is called as super/base/parent class and the one that receives the property is called as the sub/derived/child class. The child class inherits all fields and methods of the parent class extending it to add its own functionality by adding fields and methods.
One of the major advantages of Inheritance is reusability. The derived class gets the properties of the base class, thereby the code within the base is reused in the derived class, leading to faster development cycle.

This post looks at the effect inheritance has on the constructor and the methods, and particularly the role of super keyword in inheritance.

Incase of inheritance when an object of derived class is created the compiler first calls the base class constructor and then the derived class constructor. In case of multilevel inheritance the constructor would be called according to the order of inheritance.

Incase we have a method belonging to the base and derived class that have the same signatures, and if this common method is called, the compiler overrides the method belonging to the base class and calls the method belonging to the derived class.

Lets define a simple class A as shown in the snippet below. This is going to be our parent class.
class A{
    //Constructor of A
    A(){
        System.out.println("A's constructor");
    }
    public void method(){
 System.out.println("A's get method");
    }
}

We define a child class that extends the above class as folows.
class B extends A{
    //Constructor of B
    B(){
        System.out.println("B's constructor");
    }
}

Here is a sample test main method for testing the inheritance.
public static void main(String[] args){
    System.out.println("JAVA - INHERITANCE");
    B objectB = new B();
}

The output of the above code is as shown below.
JAVA - INHERITANCE
A's constructor
B's constructor

As we see, the base class constructor is called implicitly. We can also call the base class constructor explicitly by using super(). However, the super call should be the first statement in the derived class constructor. The following code snippet will give a compiler error.
class B extends A{
    //Constructor of B
    B(){
        System.out.println("B's constructor");  //This is not allowed
        super();
    }
}

The super() call has to be the first line in the constructor, as its important to initialize the base class before the derived class is initialized.
The correct way of writing the above code is as follows:
class B extends A{
    //Constructor of B
    B(){
        super();
    }
}

However, a base class method can be called from any line of the method in the derived class using the keyword super. This is shown in the snippet below.

class B extends A{
    //Constructor of B
    B(){
        super();
    }
 
    @Override
    public void method(){
    System.out.println("B's get method");
       super.method();
    }
}

Here is the sample main function where we call the derived class method..
public static void main(String[] args){
    System.out.println("JAVA - INHERITANCE");
    B objectB = new B();
    objectB.method();
}

The output of the above code is as shown below.
JAVA - INHERITANCE
A's constructor
B's constructor
B's get method
A's get method


Thus we have seen in this post that the parent class constructor is executed before the child class constructor. If the base class contains a constructor with one or more arguments, then it is mandatory for the derived class to have a constructor and pass the arguments to the base class constructor