GC Explained: Heap :: Generational Garbage Collectors

JVM heap is divided into two different Generations. One is called Young and the second one is the Old (sometimes referred to as Tenured). The Young Generation is further separated into two main logical sections: Eden and Survivor spaces. There are also Virtual spaces for both Young and the Old Generations which are used by Garbage Collectors to resize other regions – mainly to meet different GC goals.

Image title

Weak Generational Hypothesis

Why is heap divided into the Young and Old Generations? It’s because lots of objects are usually created and used for a relatively short period of time. This observation is called Weak Generational Hypothesis in GC theory. Imagine some objects created and used only inside the loop – assuming that they are not going to be scalarized, every iteration discards previously created objects and creates new ones.

Object Lifecycle

Objects start their journey in Eden of the Young Generation. When Eden fills up, so called Minor GC is performed: all application threads are stopped (stop-the-world pause), objects which are not used anymore are discarded and all other objects from the Eden are moved to the first Survivor space (S0). Next time a Minor GC is performed, the objects go from S0 to the second Survivor space (S1). All live objects from Eden go to S1 as well. Notice that it leads to a differently aged object in the Survivor space – we have objects from Eden and objects which were already in the Survivor space. Next iteration of Minor GC moves the objects from S1 back to the S0, so the Survivor spaces switch every GC. Why do we have two Survivor spaces and why do we switch them? It’s pretty simple – when the object reaches certain age threshold, it is promoted to the Old Generation. It leads to Survivor space fragmentation which can be easily eliminated with moving all objects from S0 to S1 and back every Minor GC.

Eventually, when the Old Generation fills up, a Major GC will be performed on the Old Generation which cleans it up and compacts that space. If and how stop-the-world pauses occur during Major GC depends on specific GC algorithm used.

Besides Minor and Major GC, there is also a Full GC which is about cleaning the entire heap – both Young (by Minor GC) and Old (Tenured) (by Major GC) Generations. Because a Full GC includes Minor GC, it also causes stop-the-world pauses.


There are two main advantages of having the heap divided into two regions. Firstly, it’s always faster to process only some portion of the heap (stop-the-world pauses take less). Secondly, during Minor GC, all objects from Eden are either moved or discarded which automatically means that this part of the heap is compacted.

Rules for method overriding:

  • In java, a method can only be written in Subclass, not in same class.
  • The argument list should be exactly the same as that of the overridden method.
  • The return type should be the same or a subtype of the return type declared in the original overridden method in the super class.
  • The access level cannot be more restrictive than the overridden method’s access level. For example: if the super class method is declared public then the overridding method in the sub class cannot be either private or protected.
  • Instance methods can be overridden only if they are inherited by the subclass.
  • A method declared final cannot be overridden.
  • A method declared static cannot be overridden but can be re-declared.
  • If a method cannot be inherited then it cannot be overridden.
  • A subclass within the same package as the instance’s superclass can override any superclass method that is not declared private or final.
  • A subclass in a different package can only override the non-final methods declared public or protected.
  • An overriding method can throw any uncheck exceptions, regardless of whether the overridden method throws exceptions or not. However the overriding method should not throw checked exceptions that are new or broader than the ones declared by the overridden method. The overriding method can throw narrower or fewer exceptions than the overridden method.
  • Constructors cannot be overridden.

Iterator vs ListIterator

In this tutorial we will learn about the difference between Iterator and ListIterator . We will also look at the examples of Iterator and ListIterator one by one. We have already discussed different type of iterators  i.e fail-fast iterator and fail-safe iterator.

Difference between Iterator and ListIterator in Java with Example
1. Traversal Direction  :  ListIterator allows the programmers to iterate the list objects in both directions i.e forward as well as backward direction using previous() and next() method.
Iterator can be used to  iterate the list,map and set object in one direction i.e forward.

2.  Set and Map implemented Objects Traversal : ListIterator can be used to traverse List object only . But Iterator can be used to traverse Map, List and Set implemented objects.

for example
// ListIterator object is created
ListIterator listIteratorObject = List.listIterator();
// Iterator object is created
Iterator  iteratorObject  = List.iterator();

3. Add or Set operation at any index : According to ListIterator Oracle docs,
ListIterator can modify the list  during iteration using add(E e) , remove() or set(E e).
Iterator can not add the element during traversal but they can remove the element from the underlying collection during the iteration as they only consist of remove() method. There is no add(E e) and set(E e) method in Iterator.

4. Determine Iterator’s current position :  ListIterator can obtain the iterator’s current position in the list. Iterator’s current position during traversal can not be determined using Iterator.

5. Retrieve Index of the element : ListIterator can obtain the index of the elements using previousIndex(E e) or nextIndex(E e) methods. We can not obtain the index using Iterator as there is no such methods present.

Example of Iterator and ListIterator 

import java.util.Iterator;
import java.util.ListIterator;

public class IteratorListIteratorExample {
public static void main(String[] args) {

List listObject = new ArrayList();
listObject.add(“Alive is awesome”);
listObject.add(“Love yourself”);

ListIterator listIteratorObject = listObject.listIterator();
System.out.println(“ListIterator object output in forward direction:”);
while( listIteratorObject.hasNext() )

System.out.println(“ListIterator object output in backward direction:”);
while( listIteratorObject.hasPrevious() )

List iteratorListObject = new ArrayList();


Iterator javaHungryIterator = iteratorListObject.iterator();
System.out.println(“Iterator object output in forward direction:”);

while( javaHungryIterator.hasNext() )


Output :

ListIterator object output in forward direction:
Alive is awesome
Love yourself
ListIterator object output in backward direction:
Love yourself
Alive is awesome
Iterator object output in forward direction:

Similarities between Iterator and ListIterator in Java

1. Interfaces : Both Iterator and ListIterator are interfaces . ListIterator extends Iterator interface.

2. Collection Framework : Both Iterator and ListIterator are member of the Java Collection Framework.

3. Traversal : Both are used to iterate over the collection of objects .

4. Interfaces added to jdk : Both interfaces are added to the jdk in java 1.2

Recap : Difference between Iterator and ListIterator in Java with Example 

ListIterator Iterator
Traversal Direction Both , forward and backward Forward
Objects traversal List only Map, Set and List
Add and Set operations Allows both operations Not possible
Iterator’s current position Yes , can be determined Not possible.
Retrieve Index Yes Not possible

Gradle vs. Maven

Gradle is one of several Java development tools featured in Stackify’s Comprehensive Java Developer’s Guide, but it’s not the only build automation tool to consider. Maven is an older and commonly used alternative, but which build system is best for your project? With other tools, such as Spring, allowing developers to choose between the two systems, coupled with an increasing number of integrations for both, the decision is largely up to you.

The size of your project, your need for customization, and a few other variables can help you choose. Let’s take a look.


Gradle is a build automation system that is fully open source and uses the concepts you see on Apache Maven and Apache Ant. It uses domain-specific language based on the programming language Groovy, differentiating it from Apache Maven, which uses XML for its project configuration. It also determines the order of tasks run by using a directed acyclic graph.

Several developers created Gradle and first released in 2007, and in 2013, it was adopted by Google as the build system for Android projects. It was designed to support multi-project builds that are expected to be quite huge. It also allows for incrementally adding to your build, because it knows which parts of your project are updated. Tasks that are dependent on updated parts are no longer re-executed. For now, the latest stable release is version 3.4, which was launched in February 2017. It supports development and subsequent deployment using Java, Scala, and Groovy, with other project workflows and languages being introduced in the future.


Maven is used for project build automation using Java. It helps you map out how a particular software is built, as well as its different dependencies. It uses an XML file to describe the project that you are building, the dependencies of the software with regards to third-party modules and parts, the build order, as well as the needed plugins. There are pre-defined targets for tasks such as packaging and compiling.

Maven will download libraries and plugins from the different repositories and then puts them all in a cache on your local machine. While predominantly used for Java projects, you can use it for Scala, Ruby, and C#, as well as a host of other languages.

Gradle vs. Maven

There are some fundamental differences in the way that the two systems approach builds. Gradle is based on a graph of task dependencies – in which tasks are the things that do the work – while Maven is based on a fixed and linear model of phases. With Maven, goals are attached to project phases, and goals serve a similar function to Gradle’s tasks, being the “things that do the work.”

Performance-wise, both allow for multi-module builds to run in parallel. However, Gradle allows for incremental builds because it checks which tasks are updated or not. If it is, then the task is not executed, giving you a much shorter build time. Other distinguishing performance features you can find on Gradle include:

  • Incremental compilations for Java classes
  • Compile avoidance for Java
  • The use of APIs for incremental subtasks
  • A compiler daemon that also makes compiling a lot faster

When it comes to managing dependencies, both Gradle and Maven can handle dynamic and transitive dependencies, to use third-party dependency caches, and to read POM metadata format. You can also declare library versions via central versioning definition and enforce central versioning. Both download transitive dependencies from their artifact repositories. Maven has Maven Central while Gradle has JCenter, and you can define your own private company repository as well. If there are several dependencies required, Maven can download these simultaneously.

Gradle, however, wins when it comes to API and implementation dependencies, as well as inherently allowing concurrent safe caches. It also keeps repository metadata along with cached dependencies, ensuring that two or more projects using the same cache will not overwrite each other, and it has a checksum-based cache and can synchronize cache with the repository. Furthermore, Gradle is compatible with IVY Metadata, allowing you to define custom rules to specify a version for a dynamic dependency, and resolving version conflicts. These are not available on Maven.

Other dependency management features that you can find only on Gradle are:

  • The use of substitution rules for compatible libraries
  • The use of ReplacedBy rules
  • Better metadata resolution
  • The ability to dynamically replace project dependencies with external ones, and vice versa

Gradle also gives you an easier time when working with composite builds, and it enables you to work with ad-hoc and permanent composite builds, as well as combine different builds and importing a composite build into Eclipse of IntelliJ IDEA.

As far as execution models are concerned, both have task groups and descriptions. Both enable you to build only the specified project and its dependencies. Gradle, however, has a fully configurable DAG, while with Maven, a goal can be attached only to one other goal. Multiple goals take on the form of an ordered list. Gradle also allows task exclusions, transitive exclusions, and task dependency inference. Gradle also has advanced features for task ordering and finalizers, among others.

Administering build infrastructure is another strong point for Gradle as it uses wrappers that accept auto provisioning, while with Maven, you need to have an extension to support self-provisioning builds. Gradle also enables you to configure version-based build environments without having to set these up manually. It also allows custom distributions.

Code Examples

In a comparison of Ant, Gradle, and Maven, Naresh Joshi compares the code required to create a build script that compiles, performs static analysis, runs unit tests, and creates JAR files at Programming Mitra.

Here’s the code required to achieve this with Maven:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

To run the Maven goal that creates the JAR file, you would execute the following:

mvn package

Note that using this code, you’re setting the parameters but not specifying the tasks that must be carried out. You can add plugins (such as Maven CheckStyle, FindBugs and PMD) to execute the static analysis as a single target together with unit tests, but you’ll want to specify the path to the customs check style configuration to ensure that it fails on error, using code such as:


To run the goal to achieve this, execute the following:

mvn verify

It requires quite a bit of XML code to achieve some basic and common tasks, and for this reason, projects in Maven with a large number of tasks and dependencies can result in pom.xml files that consist of hundreds to thousands of lines of code.

To compare, here’s an example of build.gradle code that achieves a similar outcome:

apply plugin:'java'
apply plugin:'checkstyle'
apply plugin:'findbugs'
apply plugin:'pmd'
version ='1.0'
repositories {
dependencies {
 testCompile group:'junit', name:'junit', version:'4.11'

This code is shorter and also introduces some useful tasks that aren’t covered with the Maven code above. Execute the following for a list of tasks that Gradle can run with the current configuration:

gradle tasks --all

How to Choose

Overall, both tools have their respective strengths and weaknesses.

  • Customized builds. With Maven, you can easily define your project’s metadata and dependencies, but creating a highly customized build might be a nightmare for Maven users. The POM file can easily get bloated as your project grows and might as well be an unreadable XML file later on.
  • Dependency management and directory structure. Still, Maven provides simple yet effective dependency management, and since it has a directory structure for your projects, you have some sort of standard layout for all your projects. It uses a declarative XML file for its POM file and has a host of plugins that you can use. Gradle uses the directory structure you see on Maven, but this can be customized. It also uses the same GAV format that Maven uses to identify artifacts.
  • Plugins and integrations. Maven also supports a wide variety of build life-cycle steps and integrates seamlessly with third-party tools such as CI servers, code coverage plugins, and artifact repository systems, among others. As far as plugins go, there is a growing number of available plugins now, and there are large vendors that have Gradle-compatible plugins. However, there are still more available plugins for Maven compared to the number available for Gradle.
  • Flexibility. Gradle, on the other hand, is very flexible and is based on a script. Custom builds would be easy to do on Gradle. However, because Gradle is virtually a newcomer, the number of developers who know Gradle inside-out might be limited.

In the end, what you choose will depend primarily on what you need. Gradle is more powerful.  However, there are times that you really do not need most of the features and functionalities it offers. Maven might be best for small projects, while Gradle is best for bigger projects. If you’ve been working with Maven and find that your project has outgrown it, it is possible to migrate from Maven to Gradle.

Additional Resources and Tutorials on Gradle and Maven

For further reading and more information, including helpful tutorials, visit the following resources:

Difference between Setter vs Constructor Injection in Spring

Spring Setter vs Constructor Injection

Spring supports two types of dependency Injection, using setter method e.g. setXXX() where XXX is a dependency or via a constructor argument. The first way of dependency injection is known as setter injection while later is known as constructor injection. Both approaches of Injecting dependency on Spring bean has there pros and cons, which we will see in this Spring framework article. The difference between Setter Injection and Constructor Injection in Spring is also a popular Spring framework interview question.Some time interviewer also asks as When do you use Setter Injection over Constructor injection in Spring or simply benefits of using setter vs constructor injection in Spring framework. Points discussed in this article not only help you to understand Setter vs Constructor Injection but also Spring’s dependency Injection process.

By the way, if you are new in Spring framework and learning it, you may want to take a look at my list of 5 good books to learn Spring framework. That will certainly help in  your learning process. Since Spring is now a must have skill for Java programmers, it worth putting time and effort to learn this powerful framework

Difference between Setter and Constructor Injection in Spring framework

As I said earlier Spring supports both setter and constructor Injection which are two standard way of injecting dependency on beans managed by IOC constructor. Spring framework doesn’t support Interface Injection on which dependency is injected by implementing a particular interface. In this section we will see a couple of difference between setter and constructor Injection, which will help you decide when to use setter Injection over constructor Injection in Spring and vice-versa.

1) The fundamental difference between setter and constructor injection, as their name implies is How dependency is injected.  Setter injection in Spring uses setter methods like setDependency() to inject dependency on any bean managed by Spring’s IOC container. On the other hand constructor injection uses constructor to inject dependency on any Spring-managed bean.
2) Because of using setter method, setter Injection in more readable than constructor injection in Spring configuration file usually applicationContext.xml . Since setter method has name e.g. setReporotService() by reading Spring XML config file you know which dependency you are setting. While in constructor injection, since it uses an index to inject the dependency, it’s not as readable as setter injection and you need to refer either Java documentation or code to find which index corresponds to which property.
3) Another difference between setter vs constructor injection in Spring and one of the drawback of  setter injection is that it does not ensures dependency Injection. You can not guarantee that certain dependency is injected or not, which means you may have an object with incomplete dependency. On other hand constructor Injection does not allow you to construct object, until your dependencies are ready.
4) One more drawback of setter Injection is Security. By using setter injection, you can override certain dependency which is not possible which is not possible with constructor injection because every time you call the constructor, a new object is gets created.

5) One of our reader Murali Mohan Reddy pointed out one more difference between Setter and Constructor injection in Spring, where later can help if there is a circular dependency between two object A and B.
If Object A and B are dependent each other i.e A is depends ob B and vice-versa. Spring throws ObjectCurrentlyInCreationException while creating objects of A and B bcz A object cannot be created until B is created and vice-versa. So spring can resolve circular dependencies through setter-injection. Objects constructed before setter methods invoked.
See comment section for more inputs from other readers.

When to use Setter Injection over Constructor Injection in Spring

Setter Injection has upper hand over Constructor Injection in terms of readability. Since for configuring Spring we use XML files, readability is much bigger concern. Also drawback of setter Injection around ensuring mandatory dependency injected or not can be handled by configuring Spring to check dependency using “dependency-check” attribute of  tag or tag. Another worth noting point to remember while comparing Setter Injection vs Constructor Injection is that, once number of dependency crossed a threshold e.g. 5 or 6 its handy manageable to passing dependency via constructor. Setter Injection is preferred choice when number of dependency to be injected is lot more than normal, if some of those arguments is optional than using Builder design pattern is also a good option.
In Summary, both Setter Injection and Constructor Injection has there own advantage and disadvantage. The good thing about Spring is that it doesn’t restrict you to use either Setter Injection or Constructor Injection and you are free to use both of them in one Spring configuration file. Use Setter injection when a number of dependencies are more or you need readability. Use Constructor Injection when Object must be created with all of its dependency.


Spring Security Example Tutorial – How to limit number of User Session in Java

Spring security can limit number of session a user can have. If you are developing web application specially secure web application in Java J2EE then you must have come up with requirement similar to online banking portals have e.g. only one session per user at a time or no concurrent session per user. You can also implement this functionality without using spring security but with Spring security its just piece of cake with coffee :). Spring Security provides lots of Out of Box functionality a secure enterprise or web application needed like authentication, authorization, session management, password encoding, secure access, session timeout etc. In our spring security example we have seen how to do LDAP Authentication in Active directory using spring security and in this spring security example we will see how to limit number of session user can have in Java web application or restricting concurrent user session.

Spring Security Example: Limit Number of User Session

As I said it’s simple and easy when you use spring security framework or library. In fact is all declarative and no code is require to enable concurrent session disable functionality. You will need to include following xml snippet in your Spring Security Configuration file mostly named as applicaContext-security.xml. Here is sample spring security Example of limiting user session in Java web application:

<session-management invalid-session-url="/logout.html">
    <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />

As you see you can specify how many concurrent session per user is allowed, most secure system like online banking portals allow just one authenticate session per user. You can even specify a URL where user will be taken if they submit an invalid session identifier can be used to detect session timeout. Session-management element is used to capture session related stuff. Max-session specify how many concurrent authenticated session is allowed and if error-if-maximum-exceeded set to true it will flag error if user tries to login into another session.


This code has dependency on spring-security framework. You need to download spring security jar like spring-security-web-3.1.0.jar and add into application classpath.

This simple example of spring security shows power of spring security, a small piece of xml snippet can add very useful and handy security feature in your Java web application. I recommend using spring security for your new or existing Java web application created using Servlet JSP.

That’s all on how to limit number of user session using spring security in Java web application. Let me know if you face any issue while implementing this security feature in your project.


10 Object Oriented Design Principles Java Programmer should know

Object Oriented Design Principles are core of OOP programming, but I have seen most of the Java programmers chasing design patterns like Singleton pattern, Decorator pattern or Observer pattern, and not putting enough attention on learning Object oriented analysis and design. It’s important to learn basics of Object oriented programming like Abstraction, Encapsulation, Polymorphism and Inheritance. But, at the same time, it’s equally important to know object oriented design principles, to create clean and modular design. I have regularly seen Java programmers and developers of various experience level, who either doesn’t heard about these OOP and SOLID design principle, or simply doesn’t know what benefits a particular design principle offers, or how to apply these design principle in coding.

Bottom line is, always strive for highly cohesive and loosely couple solution, code or design. Looking open source code from Apache and Sun are good examples of learning Java and OOPS design principles. They show us,  how design principles should be used in coding and Java programs. Java Development Kit follows several design principle like Factory Pattern in BorderFactory class,  Singleton pattern in Runtime class, Decorator pattern on various java.io classes. By the way if you really interested more on Java coding practices then read Effective Java by Joshua Bloch , a gem by the guy who wrote Java Collection API.

If you are interested in learning object oriented principles and patterns, then you can look at my another personal favorite Head First Object Oriented Analysis and Design. This an excellent book and probably the best material available in object oriented analysis and design, but it often shadowed by its more popular cousin Head First Design Pattern by Eric Freeman. Later is more about how these principle comes together to create pattern you can use directly to solve known problems. These books helps a lot to write better code, taking full advantage of various Object oriented and SOLID design principles.

Though best way of learning any design principle or pattern is real world example and understanding the consequences of violating that design principle, subject of this article is Introducing Object oriented design principles for Java Programmers, who are either not exposed to it or in learning phase. I personally think each of these OOPS and SOLID design principle need an article to explain them clearly, and I will definitely try to do that here, but for now just get yourself ready for quick bike ride on design principle town 🙂

DRY (Don’t repeat yourself)

Our first object oriented design principle is DRY, as name suggest DRY (don’t repeat yourself) means don’t write duplicate code, instead use Abstraction to abstract common things in one place. If you have block of code in more than two place consider making it a separate method, or if you use a hard-coded value more than one time make them public final constant. Benefit of this Object oriented design principle is in maintenance. It’s important  not to abuse it, duplication is not for code, but for functionality . It means, if you used common code to validate OrderID and SSN it doesn’t mean they are same or they will remain same in future. By using common code for two different functionality or thing you closely couple them forever and when your OrderID changes its format , your SSN validation code will break. So beware of such coupling and just don’t combine anything which uses similar code but are not related.

Encapsulate What Changes

Only one thing is constant in software field and that is “Change”, So encapsulate the code you expect or suspect to be changed in future. Benefit of this OOPS Design principle is that Its easy to test and maintain proper encapsulated code. If you are coding in Java then follow principle of making variable and methods private by default and increasing access step by step e.g. from private to protected and not public. Several of design pattern in Java uses Encapsulation, Factory design pattern is one example of Encapsulation which encapsulate object creation code and provides flexibility to introduce new product later with no impact on existing code.

Open Closed Design Principle

Classes, methods or functions should be Open for extension (new functionality) and Closed for modification. This is another beautiful SOLID design principle, which prevents some-one from changing already tried and tested code. Ideally if you are adding new functionality only than your code should be tested and that’s the goal of Open Closed Design principle. By the way, Open Closed principle is “O” from SOLID acronym.

Single Responsibility Principle (SRP)

Single Responsibility Principle is another SOLID design principle, and represent  “S” on SOLID acronym. As per SRP, there should not be more than one reason for a class to change, or a class should always handle single functionality. If you put more than one functionality in one Class in Java  it introduce coupling between two functionality and even if you change one functionality there is chance you broke coupled functionality,  which require another round of testing to avoid any surprise on production environment.

Dependency Injection or Inversion principle

Don’t ask for dependency it will be provided to you by framework. This has been very well implemented in Spring framework, beauty of this design principle is that any class which is injected by DI framework is easy to test with mock object and easier to maintain because object creation code is centralized in framework and client code is not littered with that.There are multiple ways to  implemented Dependency injection like using  byte code instrumentation which some AOP (Aspect Oriented programming) framework like AspectJ does or by using proxies just like used in Spring. See this example of IOC and DI design pattern to learn more about this SOLID design principle. It represent “D” on SOLID acronym.

Favor Composition over Inheritance

Always favor composition over inheritance ,if possible. Some of you may argue this, but I found that Composition is lot more flexible than Inheritance. Composition allows to change behavior of a class at run-time by setting property during run-time and by using Interfaces to compose a class we use polymorphism which provides flexibility of to replace with better implementation any time. Even Effective Java advise to favor composition over inheritance. See here to learn more about why you Composition is better than Inheritance for reusing code and functionality.

Liskov Substitution Principle (LSP)

According to Liskov Substitution Principle, Subtypes must be substitutable for super type i.e. methods or functions which uses super class type must be able to work with object of sub class without any issue”. LSP is closely related to Single responsibility principle and Interface Segregation Principle. If a class has more functionality than subclass might not support some of the functionality ,and does violated LSP. In order to follow LSP SOLID design principle, derived class or sub class must enhance functionality, but not reduce them. LSP represent  “L” on SOLID acronym.

Interface Segregation principle (ISP)

Interface Segregation Principle stats that, a client should not implement an interface, if it doesn’t use that. This happens mostly when one interface contains more than one functionality, and client only need one functionality and not other.Interface design is tricky job because once you release your interface you can not change it without breaking all implementation. Another benefit of this design principle in Java is, interface has disadvantage to implement all method before any class can use it so having single functionality means less method to implement.


Programming for Interface not implementation

Always program for interface and not for implementation this will lead to flexible code which can work with any new implementation of interface. So use interface type on variables, return types of method or argument type of methods in Java. This has been advised by many Java programmer including in Effective Java and Head First design pattern book.

Delegation principle

Don’t do all stuff  by yourself,  delegate it to respective class. Classical example of delegation design principle is equals() and hashCode() method in Java. In order to compare two object for equality we ask class itself to do comparison instead of Client class doing that check. Benefit of this design principle is no duplication of code and pretty easy to modify behavior.
Here is nice summary of all these OOP design principles :

All these object oriented design principle helps you write flexible and better code by striving high cohesion and low coupling. Theory is first step, but what is most important is to develop ability to find out when to apply these design principle. Find out, whether we are violating any design principle and compromising flexibility of code, but again as nothing is perfect in this world, don’t always try to solve problem with design patterns and design principle they are mostly for large enterprise project which has longer maintenance cycle.