eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

1. Introduction

Project Lombok helps to reduce Java’s verbosity for repetitive tasks in our source code. In this tutorial, we’ll explain how to infer types by declaring local val and var variables in Lombok.

2. Declaring val and var Variables in Lombok

Lombok provides intelligent capabilities to avoid boilerplate code. For instance, it hides getters and setters from domain model objects. Builder annotation is another interesting feature that helps to implement the Builder pattern properly.

In the following sections, we’ll focus on the Lombok feature to define local variables without specifying the type. We’ll use Lombok val and var types to declare the variables and avoid extra lines in our source code.

val was introduced in version 0.10. When using val, Lombok declares the variable as final and automatically infers the type after initializing it. Thus, the initializing expression is mandatory.

var was introduced in version 1.16.20. As with val, it also infers the type from the initializing expression with the big difference that the variable is not declared as final. Therefore, further assignments are allowed, but they should comply with the type specified when declaring the variable.

3. Implementing val and var Examples in Lombok

3.1. Dependencies

To implement the examples, we’ll simply add the Lombok dependency to our pom.xml:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.30</version>
    <scope>provided</scope>
</dependency>

We can check for the most recent available version here.

3.2. val Variable Declaration

First, we’ll import the val type from Lombok:

import lombok.val;

Second, we’ll declare different local variables using val. For instance, we can start with a simple String:

public Class name() {
    val name = "name";
    System.out.println("Name: " + name);
    return name.getClass();
}

Lombok automatically generates the following vanilla Java:

final java.lang.String name = "name";

Then, let’s create an Integer:

public Class age() {
    val age = Integer.valueOf(30);
    System.out.println("Age: " + age);
    return age.getClass();
}

As we can see, Lombok generates the proper type:

final java.lang.Integer age = Integer.valueOf(30);

We can also declare a List:

public Class listOf() {
    val agenda = new ArrayList<String>();
    agenda.add("Day 1");
    System.out.println("Agenda: " + agenda);
    return agenda.getClass();
}

Lombok infers not only the List but also the type inside it:

final java.util.ArrayList<java.lang.String> agenda = new ArrayList<String>();

Now, let’s create a Map:

public Class mapOf() {
    val books = new HashMap<Integer, String>();
    books.put(1, "Book 1");
    books.put(2, "Book 2");
    System.out.println("Books:");
    for (val entry : books.entrySet()) {
        System.out.printf("- %d. %s\n", entry.getKey(), entry.getValue());
    }
    return books.getClass();
}

Again, the proper types are inferred:

final java.util.HashMap<java.lang.Integer, java.lang.String> books = new HashMap<Integer, String>();
// ...
for (final java.util.Map.Entry<java.lang.Integer, java.lang.String> entry : books.entrySet()) {
   // ...
}

We can see Lombok declares the proper types as final. So, if we try to modify the name, the build will fail due to the final nature of val:

name = "newName";

[12,9] cannot assign a value to final variable name

Next, we’ll run some tests to verify Lombok generates the proper types:

ValExample val = new ValExample();
assertThat(val.name()).isEqualTo(String.class);
assertThat(val.age()).isEqualTo(Integer.class);
assertThat(val.listOf()).isEqualTo(ArrayList.class);
assertThat(val.mapOf()).isEqualTo(HashMap.class);

Finally, we can see in the console output the objects with specific types:

Name: name
Age: 30
Agenda: [Day 1]
Books:
- 1. Book 1
- 2. Book 2

3.3. var Variable Declaration

var declaration is pretty similar to val with the particularity that the variable is not final:

import lombok.var;

var name = "name";
name = "newName";

var age = Integer.valueOf(30);
age = 35;

var agenda = new ArrayList<String>();
agenda.add("Day 1");
agenda = new ArrayList<String>(Arrays.asList("Day 2"));

var books = new HashMap<Integer, String>();
books.put(1, "Book 1");
books.put(2, "Book 2");
books = new HashMap<Integer, String>();
books.put(3, "Book 3");
books.put(4, "Book 4");

Let’s have a look at the vanilla Java generated:

var name = "name";

var age = Integer.valueOf(30);

var agenda = new ArrayList<String>();

var books = new HashMap<Integer, String>();

This is because Java 10 supports var declaration to infer types of local variables using the initializer expression. However, we’ll need to take into account some constraints when using it.

As the declared variable is not final, we can do further assignments. Nevertheless, the objects must fit the appropriate inferred type from the initializer expression.

If we try to assign a different type, we’ll get an error during compilation:

books = new ArrayList<String>();

[37,17] incompatible types: java.util.ArrayList<java.lang.String> cannot be converted to java.util.HashMap<java.lang.Integer,java.lang.String>

Let’s change the tests slightly and check the new assignments:

VarExample varExample = new VarExample();
assertThat(varExample.name()).isEqualTo("newName");
assertThat(varExample.age()).isEqualTo(35);
assertThat("Day 2").isIn(varExample.listOf());
assertThat(varExample.mapOf()).containsValue("Book 3");

And finally, the console output is also different from the previous section:

Name: newName
Age: 35
Agenda: [Day 2]
Books:
- 3. Book 3
- 4. Book 4

4. Compound Types

There are cases in which we’ll need to use compound types as the initializer expression:

val compound = isArray ? new ArrayList<String>() : new HashSet<String>();

In the above snippet, the assignment depends on the boolean value, and the most common superclass is inferred.

Lombok assigns AbstractCollection as the type as the vanilla code shows:

final java.util.AbstractCollection<java.lang.String> compound = isArray ? new ArrayList<String>() : new HashSet<String>();

In ambiguous cases, such as with null values, the class Object is inferred.

5. Configuration Keys

Lombok allows configuring the features in one file across the entire project. Thus, it is possible to include directives and settings for the project located in one place.

Sometimes, as part of enforcing development standards in our project, we may want to restrict the use of Lombok’s var and val. And, if someone does use them inadvertently, we may want to generate a warning during compilation.

For those cases, we can flag any usage of var or val as a warning or error by including the following in the lombok.config file:

lombok.var.flagUsage = error
lombok.val.flagUsage = warning

We’ll receive an error about the illegal use of var across the project:

[12,13] Use of var is flagged according to lombok configuration.

In the same way, we’ll receive a warning message about the use of val:

ValExample.java:18: warning: Use of val is flagged according to lombok configuration.
val age = Integer.valueOf(30);

6. Conclusion

In this article, we showed how to use Lombok to define local variables without specifying the type. Furthermore, we learned the intricacies of declaring val and var variables.

We also demonstrated how the generic declaration of local variables works with compound types.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

Course – LS – NPI (cat=Java)
announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)