Sunday, June 23, 2024
HomeAndroidUsing Java 8 Features in Android - Android Java 8 Tutorial #1

Using Java 8 Features in Android – Android Java 8 Tutorial #1


Java 8 is a major release in Java history with lots of new features. With the direct support of Java 8 features in Android,  we can now utilise those features into our Android Project which can help write code more efficient and less error prone.

This tutorial is all about a brief overview of how to set up our Android Project to support Java 8 and how to use Java 8 features in our Android Project. Lets get started.

Jack Toolchain is Deprecated

[adinserter block=”3″]

Previously, to use Java 8 Features, we need to add Jack Toolchain to our project. But now, support for Jack Toolchain was deprecated as announced by Google since they were integrating the support for Java 8 features straight ahead into default toolchain. Now, we can use Java 8 in our Project by switching to Latest Preview version of Android Studio. However, if you want to use Java 8 features directly into stable version of Android Studio, you should continue to use Jack Toolchain. Lets hope that we can see the direct support for Java 8 in Stable version too.


Note: Currently, only Preview version of Android Studio supports Java 8 features directly.


3 Simple steps to Setup Project to support # Android Java 8 features:

[adinserter block=”3″]

1. Install Android Studio Preview:

Download and install the latest preview version of Android Studio from the following link.

2. Modify Project’s build.gradle file:

We need to modify our Android’s Plugin Version from our Project’s build.gradle file as follows:

buildscript {
  dependencies {
    classpath ''
3. Modify Apps build.gradle:

Now modify app module’s build.gradle file as follows:

android {
  // Configure only for each module that uses Java 8
  // language features (either in its source code or
  // through dependencies).
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8

Related Articles:

Android upload file to server

Java Interview Questions

Supported Android Java 8 Features as of now:

[adinserter block=”3″]

  1. Lambda Expressions,
  2. Method References,
  3. Default and Static interface methods
  4. Type Annotations, (Only at compile time as of now, not runtime)
  5. Repeating Annotations,

In this article, we will briefly go through the above features. In later articles, we’ll address each of the above features in depth.

1. Lambda Expressions

Lambda Expressions are one of the most powerful features introduced into Java 8. Its reshaping the language in a similar way how Generics reshaped Java when they were introduced in Java 5.


  1. Reduces boilerplate code.
  2. Eliminates unnecessary creation of objects which reduces garbage collection work
  3. Pass functions as method arguments, which can be executed on demand.


  1. It can be used with functional interfaces which should consist of only one abstract method.

Usage Example:

[adinserter block=”3″]

Here is the demonstration of a simple example from Android on Button’s click event listener. The following is the code where we use Anonymous inner class to perform action after listening to click event:

button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "Button Clicked!", Toast.LENGTH_SHORT).show();

Notice that we implemented anonymous inner class by calling new keyword where we’ve implemented View class’s OnclickListener interface which consists of only one method which is perfectly suitable to replace with Lambda Expression.

So the above code can be reduced to the following code below:

button.setOnClickListener(v -> Toast.makeText(MainActivity.this, "Button Clicked!", Toast.LENGTH_SHORT).show());

This explains the beauty of Lambda expressions where boilerplate code is simply reduced to one-liner and Java 8 takes care of the rest of the things such as Type Inference etc.

[adinserter block=”3″]

2. Method References

Method references are used to further reduce the coding and lambda expressions if the arguments are simply a passthrough.

Simple Example:

Suppose let us take a list of items for which we need to print them one by one. Here is the example code:

List<String> shoppingList = Arrays.asList("Brush",
                "Hand Wash"
        shoppingList.forEach(s -> System.out.println(s));

If we take a look at the above example, here forEach() method takes Consumer’s object as a parameter (Consumer is a functional interface, functional interfaces will soon be explained in next tutorial in depth along with Lambda Expressions).

We can observe that each item is directly being passed as an argument for lambda expression we are simply printing the list. We can observe that the variable is directly a passthrough which is a perfect match where we can use Method Reference.

The above code can be further simplified using Method references as follows:

List<String> shoppingList = Arrays.asList("Brush",
                "Hand Wash"

The last line demonstrates the usage of Method reference. We will cover the method reference types and usages in further depth in our future tutorials.

[adinserter block=”3″]

3. Default and Static interface methods

Prior to Java 8 only abstract methods, i.e., only methods without a body are allowed inside interface. But then default and static methods were introduced.

Both default and static methods contains bodies where they can be used to implement methods. Both are used for specific purposes:

Default methods can be overridden by the class implementing the interface containing that default method. It means a specific default statements can be added which will be performed when an overriding class doesnot have its own implementation.

Static methods cannot be overridden by the class implementing the interface. Static methods can only be called by Interface class reference variable but not by the implementing class variable.

Consider the following example below::

public class MyClass {
    public interface MyInterface {
        default void defaultMethod() {
        static void staticMethod() {
            System.out.println("Static from My Interface");

    public static void main(String[] args) {

        MyInterface.staticMethod(); //valid
    static void staticMethod() {
        System.out.println("Static from My Class");

If we observe carefully, both interface and class contains same method named staticMethod(). One doesnot override other. If we consider main method, both will be printed successfully and the output would be:

Static from My Class
Static from My Interface
4. Type Annotations

[adinserter block=”3″]

Prior to Java 8, annotations could only be applied to declarations. After Java 8 release, annotations can be applied to anywhere where we use a type.

Annotations make sure that compiler will check for errors in before hand. For example, we can check null pointer exceptions for a variable by using @NonNull annotation for it as follows:

@NonNull String myStr;

By using type annotations we can write code that is stronger and less prone to error.

5. Repeating Annotations

If we want to apply same annotation more than once to a declaration or data type, we would use Repeating annotations.

Here is an Example:

@Schedule(dayOfWeek="Fri", hour="23")
public void performRequiredTask() {

Java compiler automatically generates the container annotation to store the repeating annotations for compatibility issues. In order for compiler to do this, we require to perform two steps in our code:

[adinserter block=”3″]

  1. Repeatable annotation type declaration
    • We need to mark the annotation type with @Repeatable meta-annotation
      import java.lang.annotation.Repeatable;
      public @interface Schedule {
        String dayOfMonth() default "first";
        String dayOfWeek() default "Mon";
        int hour() default 12;
    • The value of the @Repeatable meta-annotation, in parentheses, is the type of the container annotation that the Java compiler generates to store repeating annotations. In this example, the containing annotation type is Schedules, so repeating @Schedule annotations is stored in an @Schedules annotation.
    • Applying the same annotation to a declaration without first declaring it to be repeatable results in a compile-time error.
  2. Containing Annotation type declaration
    • The containing annotation type must have a value element with an array type. The component type of the array type must be the repeatable annotation type. The following is the declaration for the Schedules containing annotation type:
      public @interface Schedules {
          Schedule[] value();


This completes our brief overview of Java 8 features and how to use them in our Android project. In upcoming tutorials, we will discuss in depth about lambda expressions, method references.

[adinserter block=”3″]


Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.


SOLID Principles in Android with Kotlin Examples

Recently I had an interview experience where I went blank when the interviewer posed an Interesting Question - Explain SOLID Principles and how they are...

Building a Multi Module App in Android | Modularization in Android #1

Recently, I was in requirement for developing a Multi Module app in Android and I was going through this great lecture on it. This article...

Lambda function in Kotlin with Examples

Lambda function is powerful feature in any Programming language and Lambda function in Kotlin is no exception. In this article, we will look at how...

Higher Order Functions in Kotlin with examples

There are many advanced features in Kotlin which gives an edge for the user using this language over Java. One such feature is Higher Order...

Follow us


Most Popular