<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mayur Bodhare</title>
    <description>The latest articles on DEV Community by Mayur Bodhare (@mayur_bodhare).</description>
    <link>https://dev.to/mayur_bodhare</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4167032%2F2a906238-cd94-4e9a-8793-d74e5f19b225.png</url>
      <title>DEV Community: Mayur Bodhare</title>
      <link>https://dev.to/mayur_bodhare</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mayur_bodhare"/>
    <language>en</language>
    <item>
      <title>What Does SpringApplication.run Actually Do?</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Tue, 27 Oct 2026 07:01:48 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/what-does-springapplicationrun-actually-do-h3n</link>
      <guid>https://dev.to/mayur_bodhare/what-does-springapplicationrun-actually-do-h3n</guid>
      <description>&lt;p&gt;When I started writing bigger Java programs, I noticed something annoying. Every class created the objects it needed with &lt;code&gt;new&lt;/code&gt;. A &lt;code&gt;Dev&lt;/code&gt; class created its own &lt;code&gt;Laptop&lt;/code&gt;. The &lt;code&gt;Laptop&lt;/code&gt; class created its own &lt;code&gt;Battery&lt;/code&gt;. And when I wanted to change one small thing, like using a &lt;code&gt;Desktop&lt;/code&gt; instead, I had to open and edit class after class.&lt;/p&gt;

&lt;p&gt;Then someone told me about Spring, and described it like this: &lt;strong&gt;"You don't create the objects. Spring creates them for you when you need them."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That one sentence is the base idea behind both the &lt;strong&gt;Spring Framework&lt;/strong&gt; and &lt;strong&gt;Spring Boot&lt;/strong&gt;. In this post, we'll unpack it step by step: what problem Spring solves, what IoC and DI really mean, how the Spring container works, how configuration worked in the XML days (and what &lt;code&gt;&amp;lt;beans&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;bean&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;property&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;constructor-arg&amp;gt;&lt;/code&gt;, &lt;code&gt;autowire&lt;/code&gt; and &lt;code&gt;primary&lt;/code&gt; do), how annotations like &lt;code&gt;@Component&lt;/code&gt;, &lt;code&gt;@Autowired&lt;/code&gt;, &lt;code&gt;@Primary&lt;/code&gt; and &lt;code&gt;@Qualifier&lt;/code&gt; replaced it, and finally what Spring Boot adds on top, including the meaning of that starter code everyone copies without understanding.&lt;/p&gt;

&lt;p&gt;I wrote this for &lt;strong&gt;Spring Framework 7&lt;/strong&gt; and &lt;strong&gt;Spring Boot 4.x&lt;/strong&gt;, which need &lt;strong&gt;Java 17 or newer&lt;/strong&gt;. I've drawn the key pictures in text so you can see how everything connects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
The problem: creating objects yourself

&lt;ul&gt;
&lt;li&gt;Tight coupling with new&lt;/li&gt;
&lt;li&gt;Loose coupling with an interface&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
What is the Spring Framework?

&lt;ul&gt;
&lt;li&gt;A short history&lt;/li&gt;
&lt;li&gt;The main modules&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
IoC and DI

&lt;ul&gt;
&lt;li&gt;Inversion of Control&lt;/li&gt;
&lt;li&gt;Dependency Injection&lt;/li&gt;
&lt;li&gt;IoC vs DI&lt;/li&gt;
&lt;li&gt;The Spring container and beans&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Spring with XML: the classic way

&lt;ul&gt;
&lt;li&gt;Project setup&lt;/li&gt;
&lt;li&gt;The Java classes&lt;/li&gt;
&lt;li&gt;Understanding spring.xml&lt;/li&gt;
&lt;li&gt;Running the XML configuration&lt;/li&gt;
&lt;li&gt;Injecting with property and constructor arguments&lt;/li&gt;
&lt;li&gt;Autowiring in XML: byName and byType&lt;/li&gt;
&lt;li&gt;Resolving conflicts with primary&lt;/li&gt;
&lt;li&gt;Scope: singleton and prototype&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Annotation and Java configuration

&lt;ul&gt;
&lt;li&gt;Stereotype annotations: @Component and friends&lt;/li&gt;
&lt;li&gt;Java configuration: @Configuration and @Bean&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
What is Spring Boot?

&lt;ul&gt;
&lt;li&gt;The base idea&lt;/li&gt;
&lt;li&gt;What Spring Boot adds&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Spring vs Spring Boot vs Spring Web&lt;/li&gt;
&lt;li&gt;
Spring Boot architecture

&lt;ul&gt;
&lt;li&gt;Inside Spring Boot&lt;/li&gt;
&lt;li&gt;How @SpringBootApplication works&lt;/li&gt;
&lt;li&gt;The layers of a Spring Boot application&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Your first Spring Boot application

&lt;ul&gt;
&lt;li&gt;Creating the project with Spring Initializr&lt;/li&gt;
&lt;li&gt;Understanding the starter code&lt;/li&gt;
&lt;li&gt;Adding beans: Dev, Computer and Laptop&lt;/li&gt;
&lt;li&gt;Running the application&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
The three types of dependency injection

&lt;ul&gt;
&lt;li&gt;Constructor injection&lt;/li&gt;
&lt;li&gt;Setter injection&lt;/li&gt;
&lt;li&gt;Field injection&lt;/li&gt;
&lt;li&gt;Which injection to use&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Resolving ambiguity: @Primary and @Qualifier&lt;/li&gt;
&lt;li&gt;The lifecycle of a bean&lt;/li&gt;
&lt;li&gt;Building a web endpoint with Spring Web&lt;/li&gt;
&lt;li&gt;Configuration with application.properties&lt;/li&gt;
&lt;li&gt;Running, packaging and testing&lt;/li&gt;
&lt;li&gt;Best practices&lt;/li&gt;
&lt;li&gt;Which one should I use?&lt;/li&gt;
&lt;li&gt;Common mistakes&lt;/li&gt;
&lt;li&gt;Quick recap&lt;/li&gt;
&lt;li&gt;Try it yourself&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The problem: creating objects yourself
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tight coupling with new
&lt;/h3&gt;

&lt;p&gt;Let's start with plain Java, no Spring. A developer (&lt;code&gt;Dev&lt;/code&gt;) builds a project on a laptop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Laptop&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Compiling on Laptop"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Laptop&lt;/span&gt; &lt;span class="n"&gt;laptop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Laptop&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;      &lt;span class="c1"&gt;// Dev creates its own helper&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dev is building the project..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;laptop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dev is building the project...
Compiling on Laptop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works, but look at the problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Dev&lt;/code&gt; is &lt;strong&gt;stuck with &lt;code&gt;Laptop&lt;/code&gt;&lt;/strong&gt;. To use a &lt;code&gt;Desktop&lt;/code&gt;, you must edit the &lt;code&gt;Dev&lt;/code&gt; class.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Dev&lt;/code&gt; must know &lt;strong&gt;how to build&lt;/strong&gt; its helper. If &lt;code&gt;Laptop&lt;/code&gt; needs a &lt;code&gt;Battery&lt;/code&gt; and a &lt;code&gt;Charger&lt;/code&gt;, &lt;code&gt;Dev&lt;/code&gt; has to create those too.&lt;/li&gt;
&lt;li&gt;It's hard to &lt;strong&gt;test&lt;/strong&gt; &lt;code&gt;Dev&lt;/code&gt; alone, because you can't replace the real &lt;code&gt;Laptop&lt;/code&gt; with a fake one.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   TIGHT COUPLING

   Dev  ---- creates ----&amp;gt;  new Laptop()        Dev decides AND builds its own helper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Loose coupling with an interface
&lt;/h3&gt;

&lt;p&gt;The first fix is to depend on an &lt;strong&gt;interface&lt;/strong&gt;, and to &lt;strong&gt;receive&lt;/strong&gt; the helper from outside, instead of creating it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Laptop&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Compiling on Laptop"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Desktop&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Compiling on Desktop"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;            &lt;span class="c1"&gt;// the helper is GIVEN to Dev&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dev is building the project..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Laptop&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;      &lt;span class="c1"&gt;// or new Dev(new Desktop())&lt;/span&gt;
&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now &lt;code&gt;Dev&lt;/code&gt; doesn't care which computer it gets. It only knows the &lt;code&gt;Computer&lt;/code&gt; interface. That's called &lt;strong&gt;dependency injection&lt;/strong&gt;, and we just did it by hand.&lt;/p&gt;

&lt;p&gt;But there's a new problem: &lt;strong&gt;someone has to write all that wiring code.&lt;/strong&gt; In a real application with hundreds of classes, &lt;code&gt;main&lt;/code&gt; would become a giant list of &lt;code&gt;new&lt;/code&gt; calls in exactly the right order. This is what Spring automates. It builds the objects and passes them to each other for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Spring Framework?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Spring Framework&lt;/strong&gt; is an open-source Java framework. Its core is a &lt;strong&gt;container&lt;/strong&gt; that creates your objects, connects them to each other and manages their whole life. On top of that core, Spring offers support for web applications, databases, transactions, security, testing and more.&lt;/p&gt;

&lt;h3&gt;
  
  
  A short history
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In the early 2000s, enterprise Java (J2EE) was heavy and complicated, especially &lt;strong&gt;EJBs&lt;/strong&gt;. Rod Johnson described a simpler approach in his 2002 book, and the code that came with it grew into Spring.&lt;/li&gt;
&lt;li&gt;Spring's idea was that you write &lt;strong&gt;plain Java objects&lt;/strong&gt; (POJOs), and the framework connects them. The name is often explained as a "fresh start" after the heavy J2EE years.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring Framework 1.0&lt;/strong&gt; came out in 2004. It has been updated steadily since. Version 6 (2022) moved to Java 17 and the &lt;code&gt;jakarta&lt;/code&gt; packages, and version 7 arrived in late 2025.&lt;/li&gt;
&lt;li&gt;Plain Spring still needed a lot of setup, so &lt;strong&gt;Spring Boot 1.0&lt;/strong&gt; was released in 2014 to remove most of it. Spring Boot 4.0 came out in November 2025, built on Spring Framework 7, and 4.1 followed in June 2026.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The main modules
&lt;/h3&gt;

&lt;p&gt;Spring is split into modules, so you only use what you need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   SPRING FRAMEWORK
   +--------------------------------------------------------------------+
   |  CORE CONTAINER     core, beans, context, expression language      |  &amp;lt;- IoC and DI live here
   +--------------------------------------------------------------------+
   |  AOP                aspect-oriented programming (logging, security)|
   |  DATA ACCESS        JDBC, ORM (Hibernate/JPA), transactions        |
   |  WEB                spring-web, spring-webmvc, spring-webflux      |
   |  TEST               support for JUnit and mock environments        |
   +--------------------------------------------------------------------+

   Related projects built on it: Spring Data, Spring Security, Spring Batch, Spring Cloud ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything else depends on the core container, so that's what we'll focus on first.&lt;/p&gt;

&lt;h2&gt;
  
  
  IoC and DI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Inversion of Control
&lt;/h3&gt;

&lt;p&gt;Normally, &lt;strong&gt;your code is in control&lt;/strong&gt;: it decides which objects to create, when to create them and how to connect them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inversion of Control (IoC)&lt;/strong&gt; flips that. You describe what you need, and a &lt;strong&gt;container&lt;/strong&gt; takes control of creating and connecting objects. The control is "inverted": from your code to the framework. People sometimes call it the Hollywood principle: &lt;em&gt;"Don't call us, we'll call you."&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   WITHOUT IoC                                     WITH IoC (Spring)

   your code:                                      your code:
     laptop = new Laptop()                           "I need a Dev"
     dev    = new Dev(laptop)                              |
     dev.build()                                           v
                                                    SPRING CONTAINER
   YOU create and wire everything                     creates Laptop
                                                      creates Dev, gives it the Laptop
                                                      hands you the finished Dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dependency Injection
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;dependency&lt;/strong&gt; is an object that another object needs. &lt;code&gt;Dev&lt;/code&gt; depends on a &lt;code&gt;Computer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependency Injection (DI)&lt;/strong&gt; means the dependency is &lt;strong&gt;handed in from outside&lt;/strong&gt;, instead of being created inside. Think of a company: a developer doesn't build their own laptop. The IT department &lt;strong&gt;gives&lt;/strong&gt; them one. The developer just uses it.&lt;/p&gt;

&lt;p&gt;In Spring, the container is the IT department. It builds the &lt;code&gt;Laptop&lt;/code&gt;, builds the &lt;code&gt;Dev&lt;/code&gt;, and &lt;strong&gt;injects&lt;/strong&gt; the laptop into the dev. There are three ways it can hand things over: through the constructor, through a setter method or directly into a field. We'll look at all three later.&lt;/p&gt;

&lt;h3&gt;
  
  
  IoC vs DI
&lt;/h3&gt;

&lt;p&gt;These two terms are mixed up constantly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IoC&lt;/strong&gt; is the &lt;strong&gt;big principle&lt;/strong&gt;: some framework controls object creation and wiring, not your code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DI&lt;/strong&gt; is the &lt;strong&gt;technique&lt;/strong&gt; used to achieve it: the container gives each object what it needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All DI is IoC, but IoC is a bigger idea. There's also a second form of IoC called &lt;strong&gt;dependency lookup&lt;/strong&gt;, where your code &lt;em&gt;asks&lt;/em&gt; the container for an object. A call like &lt;code&gt;context.getBean(Dev.class)&lt;/code&gt; is a lookup, not an injection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   IoC   (the principle: the container is in control)
     |
     |-- Dependency Injection   the container GIVES objects what they need   (most common)
     +-- Dependency Lookup      your code ASKS the container:  context.getBean(...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Spring container and beans
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Spring container&lt;/strong&gt; (also called the &lt;strong&gt;IoC container&lt;/strong&gt;) is the part of Spring that creates objects, connects them and &lt;strong&gt;manages their entire lifecycle&lt;/strong&gt;: creating them, injecting their dependencies, initializing them and finally destroying them. The objects it manages are called &lt;strong&gt;beans&lt;/strong&gt;. A bean isn't a special kind of class. It's just an ordinary Java object that the container created and looks after.&lt;/p&gt;

&lt;p&gt;To know what to create, the container needs &lt;strong&gt;configuration metadata&lt;/strong&gt;. That can be XML, annotations or Java code, and we'll see all three.&lt;/p&gt;

&lt;p&gt;There are two container interfaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;BeanFactory&lt;/code&gt;&lt;/strong&gt;: the basic container, which creates and wires beans.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ApplicationContext&lt;/code&gt;&lt;/strong&gt;: extends &lt;code&gt;BeanFactory&lt;/code&gt; with more features, like event publishing, reading properties, resource loading, internationalization and easy integration with other Spring features. &lt;strong&gt;This is the one you use.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When people say "the context," they mean the &lt;code&gt;ApplicationContext&lt;/code&gt;: the box that holds all your beans.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   configuration metadata            your classes
   (XML / annotations / Java)        (Laptop, Dev ...)
              \                         /
               v                       v
          +----------------------------------+
          |   SPRING CONTAINER               |
          |   (ApplicationContext)           |
          |   creates, wires, manages        |
          |   [laptop]  [dev]  [...]         |   &amp;lt;- the beans
          +----------------------------------+
                      |
                      v   getBean(...)  or  injection
                  your application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Spring with XML: the classic way
&lt;/h2&gt;

&lt;p&gt;Before annotations, Spring was configured with &lt;strong&gt;XML files&lt;/strong&gt;. It's still fully supported, you'll meet it in older projects and interviews, and understanding it makes the modern annotation style much clearer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project setup
&lt;/h3&gt;

&lt;p&gt;Create a plain Maven project (see my Maven post) and add Spring's core context library. I'll import the Spring BOM so the versions stay in sync:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;maven.compiler.release&amp;gt;&lt;/span&gt;17&lt;span class="nt"&gt;&amp;lt;/maven.compiler.release&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-framework-bom&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;7.0.10&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;type&amp;gt;&lt;/span&gt;pom&lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;import&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencyManagement&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-context&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Use the newest 7.0.x version you can find.) The XML file goes in the resources folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   my-spring-app/
   |-- pom.xml
   +-- src/main/
        |-- java/com/example/   &amp;lt;- Computer, Laptop, Desktop, Dev, App
        +-- resources/spring.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Java classes
&lt;/h3&gt;

&lt;p&gt;We reuse &lt;code&gt;Computer&lt;/code&gt;, &lt;code&gt;Laptop&lt;/code&gt; and &lt;code&gt;Desktop&lt;/code&gt; from before. &lt;code&gt;Dev&lt;/code&gt; now has setters and two constructors, so Spring can build it in different ways:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;comp&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;comp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;comp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;comp&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setComp&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;comp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;comp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;comp&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" is building the project..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;comp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice there's &lt;strong&gt;no Spring code at all&lt;/strong&gt; in these classes. They're plain Java objects. All the Spring knowledge lives in the XML.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding spring.xml
&lt;/h3&gt;

&lt;p&gt;Here is the configuration file, &lt;code&gt;src/main/resources/spring.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;beans&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.springframework.org/schema/beans"&lt;/span&gt;
       &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
       &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://www.springframework.org/schema/beans
                           https://www.springframework.org/schema/beans/spring-beans.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"laptop"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Laptop"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"dev"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Dev"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"comp"&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"laptop"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What each part means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;?xml ...?&amp;gt;&lt;/code&gt;&lt;/strong&gt;: the standard first line of any XML file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;beans&amp;gt;&lt;/code&gt;&lt;/strong&gt;: the &lt;strong&gt;root tag&lt;/strong&gt;. Everything inside is a bean definition. Its attributes (&lt;code&gt;xmlns&lt;/code&gt;, &lt;code&gt;xsi:schemaLocation&lt;/code&gt;) tell the XML parser which schema (a rule book) defines the valid tags. They also let your IDE autocomplete and check the file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;bean&amp;gt;&lt;/code&gt;&lt;/strong&gt;: defines &lt;strong&gt;one object&lt;/strong&gt;.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;id&lt;/code&gt;&lt;/strong&gt;: a unique name for this bean. You use it in &lt;code&gt;ref&lt;/code&gt; and in &lt;code&gt;getBean("dev")&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;class&lt;/code&gt;&lt;/strong&gt;: the full class name Spring should create. Spring creates it using reflection, with the &lt;strong&gt;no-argument constructor&lt;/strong&gt; unless you provide &lt;code&gt;&amp;lt;constructor-arg&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;property&amp;gt;&lt;/code&gt;&lt;/strong&gt;: &lt;strong&gt;setter injection&lt;/strong&gt;.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;name&lt;/code&gt;&lt;/strong&gt;: the property name. &lt;code&gt;name="comp"&lt;/code&gt; makes Spring call &lt;code&gt;setComp(...)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;value&lt;/code&gt;&lt;/strong&gt;: a plain value (a string, number or boolean). Spring converts &lt;code&gt;"Asha"&lt;/code&gt; to a &lt;code&gt;String&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ref&lt;/code&gt;&lt;/strong&gt;: a reference to &lt;strong&gt;another bean&lt;/strong&gt;, by its &lt;code&gt;id&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;constructor-arg&amp;gt;&lt;/code&gt;&lt;/strong&gt;: &lt;strong&gt;constructor injection&lt;/strong&gt; (we'll use it in a moment).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can think of this file as Spring executing the Java code you used to write yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Laptop&lt;/span&gt; &lt;span class="n"&gt;laptop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Laptop&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setComp&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;laptop&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running the XML configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.support.ClassPathXmlApplicationContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ClassPathXmlApplicationContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
                     &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ClassPathXmlApplicationContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"spring.xml"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

            &lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Asha is building the project...
Compiling on Laptop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ClassPathXmlApplicationContext("spring.xml")&lt;/code&gt;&lt;/strong&gt; creates the container. It looks for &lt;code&gt;spring.xml&lt;/code&gt; on the &lt;strong&gt;classpath&lt;/strong&gt; (the &lt;code&gt;resources&lt;/code&gt; folder ends up there), reads the bean definitions and creates the objects. (&lt;code&gt;FileSystemXmlApplicationContext&lt;/code&gt; loads a file from a disk path instead.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;context.getBean(Dev.class)&lt;/code&gt;&lt;/strong&gt; asks the container for the bean of type &lt;code&gt;Dev&lt;/code&gt;. You can also ask by id: &lt;code&gt;context.getBean("dev")&lt;/code&gt;, or by both: &lt;code&gt;context.getBean("dev", Dev.class)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The context is closable, so try-with-resources shuts it down (and destroys the beans) at the end.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice we never wrote &lt;code&gt;new Dev()&lt;/code&gt;. The container made it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Injecting with property and constructor arguments
&lt;/h3&gt;

&lt;p&gt;Besides &lt;code&gt;&amp;lt;property&amp;gt;&lt;/code&gt;, you can inject through the constructor with &lt;strong&gt;&lt;code&gt;&amp;lt;constructor-arg&amp;gt;&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"dev"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Dev"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;constructor-arg&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;constructor-arg&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"laptop"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, the arguments are matched &lt;strong&gt;in order&lt;/strong&gt;. You can be explicit with &lt;code&gt;index="0"&lt;/code&gt;, &lt;code&gt;type="..."&lt;/code&gt; or &lt;code&gt;name="comp"&lt;/code&gt;. The output is the same.&lt;/p&gt;

&lt;p&gt;Now the best part. To switch to a desktop, change &lt;strong&gt;one word&lt;/strong&gt; in the XML, with no Java changes at all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;constructor-arg&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"desktop"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(After adding &lt;code&gt;&amp;lt;bean id="desktop" class="com.example.Desktop"/&amp;gt;&lt;/code&gt;.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Asha is building the project...
Compiling on Desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A rule of thumb: use &lt;strong&gt;&lt;code&gt;&amp;lt;constructor-arg&amp;gt;&lt;/code&gt;&lt;/strong&gt; for things the object &lt;em&gt;must&lt;/em&gt; have, and &lt;strong&gt;&lt;code&gt;&amp;lt;property&amp;gt;&lt;/code&gt;&lt;/strong&gt; for optional or changeable settings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Autowiring in XML: byName and byType
&lt;/h3&gt;

&lt;p&gt;Writing &lt;code&gt;ref&lt;/code&gt; for every dependency gets tedious. &lt;strong&gt;Autowiring&lt;/strong&gt; lets Spring find the dependencies itself. The &lt;code&gt;autowire&lt;/code&gt; attribute has these main values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;no&lt;/code&gt;&lt;/strong&gt;: the default. No autowiring. You write &lt;code&gt;ref&lt;/code&gt; yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;byType&lt;/code&gt;&lt;/strong&gt;: Spring looks at the &lt;strong&gt;type&lt;/strong&gt; of each property (&lt;code&gt;Computer&lt;/code&gt;) and finds a bean of that type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;byName&lt;/code&gt;&lt;/strong&gt;: Spring looks at the &lt;strong&gt;name&lt;/strong&gt; of each property (&lt;code&gt;comp&lt;/code&gt;) and finds a bean with the &lt;strong&gt;same id&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;constructor&lt;/code&gt;&lt;/strong&gt;: like &lt;code&gt;byType&lt;/code&gt;, but for constructor arguments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(The values are case-sensitive: write &lt;code&gt;byType&lt;/code&gt;, not &lt;code&gt;ByType&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;byType&lt;/code&gt;&lt;/strong&gt; with exactly one &lt;code&gt;Computer&lt;/code&gt; bean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"laptop"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Laptop"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"dev"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Dev"&lt;/span&gt; &lt;span class="na"&gt;autowire=&lt;/span&gt;&lt;span class="s"&gt;"byType"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's no &lt;code&gt;&amp;lt;property name="comp" ...&amp;gt;&lt;/code&gt;. Spring noticed that &lt;code&gt;Dev&lt;/code&gt; has a &lt;code&gt;setComp(Computer)&lt;/code&gt; method, found the one &lt;code&gt;Computer&lt;/code&gt; bean (&lt;code&gt;laptop&lt;/code&gt;) and injected it. Autowiring only applies to &lt;strong&gt;objects&lt;/strong&gt;. Simple values like the &lt;code&gt;name&lt;/code&gt; string still need &lt;code&gt;&amp;lt;property value="..."&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now add a second &lt;code&gt;Computer&lt;/code&gt; bean, and Spring can't decide:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"laptop"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Laptop"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"desktop"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Desktop"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"dev"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Dev"&lt;/span&gt; &lt;span class="na"&gt;autowire=&lt;/span&gt;&lt;span class="s"&gt;"byType"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UnsatisfiedDependencyException: Error creating bean with name 'dev' ...
Unsatisfied dependency expressed through bean property 'comp':
No qualifying bean of type 'com.example.Computer' available:
expected single matching bean but found 2: laptop,desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two beans match the type, so Spring refuses to guess. One fix is &lt;strong&gt;&lt;code&gt;byName&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"comp"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Laptop"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"desktop"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Desktop"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"dev"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Dev"&lt;/span&gt; &lt;span class="na"&gt;autowire=&lt;/span&gt;&lt;span class="s"&gt;"byName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Asha is building the project...
Compiling on Laptop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works because &lt;code&gt;Dev&lt;/code&gt; has a property named &lt;code&gt;comp&lt;/code&gt;, and there's a bean whose id is &lt;code&gt;comp&lt;/code&gt;. The &lt;code&gt;desktop&lt;/code&gt; bean is ignored. The matching is by &lt;strong&gt;name&lt;/strong&gt;, so the bean id and the property name must agree exactly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolving conflicts with primary
&lt;/h3&gt;

&lt;p&gt;The other fix is to mark one bean as the preferred choice with &lt;strong&gt;&lt;code&gt;primary="true"&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"laptop"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Laptop"&lt;/span&gt; &lt;span class="na"&gt;primary=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"desktop"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Desktop"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"dev"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Dev"&lt;/span&gt; &lt;span class="na"&gt;autowire=&lt;/span&gt;&lt;span class="s"&gt;"byType"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;property&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Asha is building the project...
Compiling on Laptop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When several beans match, Spring picks the primary one. There's also a related attribute, &lt;strong&gt;&lt;code&gt;autowire-candidate="false"&lt;/code&gt;&lt;/strong&gt;, which removes a bean from autowiring completely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"desktop"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Desktop"&lt;/span&gt; &lt;span class="na"&gt;autowire-candidate=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scope: singleton and prototype
&lt;/h3&gt;

&lt;p&gt;By default, Spring creates &lt;strong&gt;one instance&lt;/strong&gt; of each bean and shares it. That's the &lt;strong&gt;singleton&lt;/strong&gt; scope (one per container, not the same as the singleton design pattern). You can ask for a new object every time with &lt;code&gt;scope="prototype"&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;bean&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"dev"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"com.example.Dev"&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"prototype"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Default (singleton): prints &lt;code&gt;true&lt;/code&gt;. Both variables hold the same object.&lt;/li&gt;
&lt;li&gt;With &lt;code&gt;scope="prototype"&lt;/code&gt;: prints &lt;code&gt;false&lt;/code&gt;. Each &lt;code&gt;getBean&lt;/code&gt; creates a new one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Singleton beans are created &lt;strong&gt;when the container starts&lt;/strong&gt; (eagerly). Add &lt;code&gt;lazy-init="true"&lt;/code&gt; to create one only when it's first needed. In web applications there are more scopes too, like &lt;code&gt;request&lt;/code&gt; and &lt;code&gt;session&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;XML works, but it has downsides: it's wordy, the configuration is far from the code, and typos in class names show up only at run time. That's why Spring moved toward annotations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Annotation and Java configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stereotype annotations: @Component and friends
&lt;/h3&gt;

&lt;p&gt;Instead of declaring each bean in XML, you put &lt;strong&gt;&lt;code&gt;@Component&lt;/code&gt;&lt;/strong&gt; on the class. Spring finds those classes by &lt;strong&gt;component scanning&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Laptop&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To turn scanning on in plain Spring, you add a configuration class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="nd"&gt;@ComponentScan&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.example"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;AnnotationConfigApplicationContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AnnotationConfigApplicationContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AppConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(In XML, the same switch is &lt;code&gt;&amp;lt;context:component-scan base-package="com.example"/&amp;gt;&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@Component&lt;/code&gt; has specialized versions that say what the class is for. They're all components underneath:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Service&lt;/code&gt;&lt;/strong&gt;: business logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Repository&lt;/code&gt;&lt;/strong&gt;: data access (it also converts database exceptions into Spring's exception types).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Controller&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;@RestController&lt;/code&gt;&lt;/strong&gt;: web request handlers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The default bean name is the class name with a lowercase first letter (&lt;code&gt;Laptop&lt;/code&gt; becomes &lt;code&gt;laptop&lt;/code&gt;). You can set your own with &lt;code&gt;@Component("comp")&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's how the XML ideas you just learned map to annotations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   XML                                       ANNOTATIONS
   &amp;lt;bean id="laptop" class="...Laptop"/&amp;gt;     @Component on the class Laptop
   &amp;lt;property ref&amp;gt; / &amp;lt;constructor-arg ref&amp;gt;    constructor parameter, or @Autowired
   autowire="byType"                         @Autowired (matches by type)
   autowire="byName"                         @Autowired + @Qualifier("name")
   primary="true"                            @Primary
   scope="prototype"                         @Scope("prototype")
   lazy-init="true"                          @Lazy
   init-method / destroy-method              @PostConstruct / @PreDestroy
   ClassPathXmlApplicationContext            AnnotationConfigApplicationContext
                                             (or SpringApplication.run in Spring Boot)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Java configuration: @Configuration and &lt;a class="mentioned-user" href="https://dev.to/bean"&gt;@bean&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;What if you can't put &lt;code&gt;@Component&lt;/code&gt; on a class, because it comes from a library? Or the creation needs custom steps? Use a &lt;strong&gt;&lt;code&gt;@Bean&lt;/code&gt; method&lt;/strong&gt; in a &lt;strong&gt;&lt;code&gt;@Configuration&lt;/code&gt;&lt;/strong&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="nf"&gt;laptop&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Laptop&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="nf"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// Spring supplies "computer"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bean's name is the &lt;strong&gt;method name&lt;/strong&gt; (&lt;code&gt;laptop&lt;/code&gt;, &lt;code&gt;dev&lt;/code&gt;), and method parameters are injected by Spring. A quick rule: use &lt;strong&gt;&lt;code&gt;@Component&lt;/code&gt;&lt;/strong&gt; for classes you write, and &lt;strong&gt;&lt;code&gt;@Bean&lt;/code&gt;&lt;/strong&gt; for classes you don't own or that need special setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Spring Boot?
&lt;/h2&gt;

&lt;p&gt;With the Spring Framework alone, you still have a lot to do before your first line of real code. You must pick compatible versions of many libraries, write configuration for the database, the web layer and transactions, install and configure a server like Tomcat, and package the app for deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spring Boot&lt;/strong&gt; removes most of that work. It isn't a different framework. It's &lt;strong&gt;Spring, with the setup done for you&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The base idea
&lt;/h3&gt;

&lt;p&gt;Remember the sentence at the start? &lt;strong&gt;Spring Boot creates the objects for you, when you need them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You write your own classes and mark them (&lt;code&gt;@Component&lt;/code&gt;, &lt;code&gt;@Service&lt;/code&gt;, &lt;code&gt;@RestController&lt;/code&gt;). Boot's container creates them and wires them together, just like plain Spring. But Boot also creates the &lt;strong&gt;infrastructure objects&lt;/strong&gt; automatically, based on what's in your project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the &lt;strong&gt;web starter&lt;/strong&gt;, and Boot creates an embedded Tomcat server, the request dispatcher and the JSON converters.&lt;/li&gt;
&lt;li&gt;Add a &lt;strong&gt;database starter and driver&lt;/strong&gt;, and Boot creates a connection pool, and with JPA, Hibernate's factory and a transaction manager (the objects we built by hand in my Hibernate post).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   your classes  +  starters (what's on the classpath)  +  application.properties
                              |
                              v
                       SPRING BOOT
              creates and wires the beans for you
                              |
                              v
                   a running application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You describe &lt;em&gt;what&lt;/em&gt; you need, and Boot builds it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Spring Boot adds
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Starters:&lt;/strong&gt; one dependency (like &lt;code&gt;spring-boot-starter-webmvc&lt;/code&gt;) that brings a whole matching set of libraries. No more hunting for compatible versions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-configuration:&lt;/strong&gt; Boot configures beans automatically based on your classpath and properties.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An embedded server:&lt;/strong&gt; Tomcat is built in, so the app runs with &lt;code&gt;java -jar&lt;/code&gt;. No separate server and no WAR deployment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sensible defaults:&lt;/strong&gt; convention over configuration. You override only what you need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No XML&lt;/strong&gt; needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;application.properties&lt;/code&gt;:&lt;/strong&gt; one place for settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production features:&lt;/strong&gt; the Actuator module adds health checks and metrics, for example &lt;code&gt;/actuator/health&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer tools:&lt;/strong&gt; quick restarts, an initializer website, and good testing support.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Spring vs Spring Boot vs Spring Web
&lt;/h2&gt;

&lt;p&gt;These three names cause the most confusion, so here's how they relate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spring Framework&lt;/strong&gt; is the &lt;strong&gt;foundation&lt;/strong&gt;: the IoC container, dependency injection, transactions, data access and more. You configure everything yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring Web&lt;/strong&gt; is the part of the framework for &lt;strong&gt;web applications and REST APIs&lt;/strong&gt;. It has two main sets of modules: &lt;code&gt;spring-web&lt;/code&gt; (HTTP basics and clients) and &lt;strong&gt;&lt;code&gt;spring-webmvc&lt;/code&gt;&lt;/strong&gt; (Spring MVC, the controller-based web framework). There's also &lt;strong&gt;Spring WebFlux&lt;/strong&gt;, a reactive alternative. These are &lt;em&gt;modules inside&lt;/em&gt; the Spring Framework.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring Boot&lt;/strong&gt; is a &lt;strong&gt;layer on top&lt;/strong&gt; that sets all of this up for you: starters, auto-configuration, an embedded server and packaging.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   +--------------------------------------------------------------------------+
   |  SPRING BOOT                                                              |
   |  starters  ·  auto-configuration  ·  embedded server  ·  Actuator         |
   +--------------------------------------------------------------------------+
   |  SPRING WEB MVC / WEBFLUX      |  SPRING DATA  |  SPRING SECURITY  |  ... |
   +--------------------------------------------------------------------------+
   |  SPRING FRAMEWORK CORE: IoC container, dependency injection, AOP ...      |
   +--------------------------------------------------------------------------+
   |  JAVA / JVM                                                               |
   +--------------------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's how they differ in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Setup:&lt;/strong&gt; Spring needs manual setup (dependencies, configuration, server). Boot generates a ready project in seconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration:&lt;/strong&gt; Spring uses XML or Java config you write. Boot auto-configures and you override what you need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server:&lt;/strong&gt; with Spring you deploy a WAR to a server you installed. With Boot the server is embedded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versions:&lt;/strong&gt; with Spring you pick compatible library versions yourself. With Boot, the starters and parent manage them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Packaging:&lt;/strong&gt; Spring usually produces a WAR. Boot produces an executable JAR.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control:&lt;/strong&gt; Spring gives you full control, with more work. Boot gives sensible defaults, with less work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;About names: when you pick &lt;strong&gt;"Spring Web"&lt;/strong&gt; on the Spring Initializr website, you get Spring MVC and an embedded Tomcat. In Spring Boot 4, that starter is called &lt;code&gt;spring-boot-starter-webmvc&lt;/code&gt;. Before Boot 4, it was &lt;code&gt;spring-boot-starter-web&lt;/code&gt;. The old name is deprecated in the newest versions, but you'll still see it in older tutorials.&lt;/p&gt;

&lt;p&gt;Also remember: Boot doesn't replace Spring. Everything you learned about the container, beans and injection &lt;strong&gt;still applies&lt;/strong&gt;. That's why we learn those first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spring Boot architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Inside Spring Boot
&lt;/h3&gt;

&lt;p&gt;Spring Boot is built from a few key parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;SpringApplication&lt;/code&gt;&lt;/strong&gt;: the class that starts your application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Starters:&lt;/strong&gt; dependency bundles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-configuration:&lt;/strong&gt; the logic that creates beans for you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;Environment&lt;/code&gt;:&lt;/strong&gt; your settings, from &lt;code&gt;application.properties&lt;/code&gt;, environment variables and command-line arguments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The embedded server:&lt;/strong&gt; Tomcat by default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actuator:&lt;/strong&gt; optional monitoring.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's what happens when you call &lt;code&gt;SpringApplication.run(...)&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   SpringApplication.run(DemoApplication.class, args)
        |
        1. create the ApplicationContext   (the container)
        |
        2. load the environment            (application.properties, env variables, command line)
        |
        3. component scan                  find @Component, @Service, @RestController ... classes
        |
        4. auto-configuration              add beans based on the classpath and properties
        |                                  (web server, DataSource, JSON converters ...)
        5. create all singleton beans, inject their dependencies
        |
        6. start the embedded web server   (only if a web starter is present)
        |
        7. the application is running      (the context is closed when the app shuts down)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Spring Boot 4 also split its internals into smaller, focused modules, but the process above stays the same.)&lt;/p&gt;

&lt;h3&gt;
  
  
  How @SpringBootApplication works
&lt;/h3&gt;

&lt;p&gt;One annotation on your main class does a lot. &lt;strong&gt;&lt;code&gt;@SpringBootApplication&lt;/code&gt;&lt;/strong&gt; is a shortcut for three annotations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="c1"&gt;// ... is the same as combining:&lt;/span&gt;
&lt;span class="nd"&gt;@SpringBootConfiguration&lt;/span&gt;     &lt;span class="c1"&gt;// this class is a configuration class (like @Configuration)&lt;/span&gt;
&lt;span class="nd"&gt;@EnableAutoConfiguration&lt;/span&gt;     &lt;span class="c1"&gt;// turn on auto-configuration&lt;/span&gt;
&lt;span class="nd"&gt;@ComponentScan&lt;/span&gt;               &lt;span class="c1"&gt;// scan this package and its sub-packages for @Component classes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Auto-configuration&lt;/strong&gt; works like this. Spring Boot's jars contain a list of auto-configuration classes (in a file named &lt;code&gt;META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports&lt;/code&gt;). Each one is guarded by &lt;strong&gt;conditions&lt;/strong&gt;, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@ConditionalOnClass&lt;/code&gt;: only apply if a certain class is on the classpath.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@ConditionalOnMissingBean&lt;/code&gt;: only apply if &lt;em&gt;you&lt;/em&gt; haven't defined your own bean.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@ConditionalOnProperty&lt;/code&gt;: only apply if a property is set.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if a database driver is on the classpath and you haven't defined a &lt;code&gt;DataSource&lt;/code&gt; yourself, Boot creates one from your &lt;code&gt;spring.datasource.*&lt;/code&gt; properties. If you define your own &lt;code&gt;DataSource&lt;/code&gt;, Boot &lt;strong&gt;backs off&lt;/strong&gt; and uses yours. If you ever wonder why a bean exists (or doesn't), start the app with &lt;code&gt;--debug&lt;/code&gt; to print a report of every condition that was checked.&lt;/p&gt;

&lt;p&gt;An important consequence: &lt;strong&gt;component scanning starts at the package of your main class.&lt;/strong&gt; Classes outside that package and its sub-packages are &lt;strong&gt;not found&lt;/strong&gt;. That's why the main class sits in the root package of the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  The layers of a Spring Boot application
&lt;/h3&gt;

&lt;p&gt;A typical Spring Boot web application is organized in layers, and each layer is a bean that gets the next layer injected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Browser / mobile app / Postman
            |   HTTP request
            v
   EMBEDDED TOMCAT  --&amp;gt;  DispatcherServlet  (Spring MVC's front controller)
                              |
                              v
        +-------------------------------+
        |  CONTROLLER  (@RestController)|   handles HTTP: URLs, parameters, JSON
        +-------------------------------+
                      |  calls
                      v
        +-------------------------------+
        |  SERVICE     (@Service)       |   business logic, transactions
        +-------------------------------+
                      |  calls
                      v
        +-------------------------------+
        |  REPOSITORY  (@Repository)    |   talks to the database (JPA / JDBC)
        +-------------------------------+
                      |
                      v
                  DATABASE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rule: each layer talks only to the layer below it. Controllers don't touch the database, and repositories hold no business rules. Spring wires the layers together with dependency injection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your first Spring Boot application
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creating the project with Spring Initializr
&lt;/h3&gt;

&lt;p&gt;The easiest way to start is the &lt;strong&gt;Spring Initializr&lt;/strong&gt; website, &lt;code&gt;start.spring.io&lt;/code&gt;. Choose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project:&lt;/strong&gt; Maven&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language:&lt;/strong&gt; Java&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring Boot:&lt;/strong&gt; the newest stable 4.x version (not a SNAPSHOT or release candidate)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Group:&lt;/strong&gt; &lt;code&gt;com.example&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Artifact:&lt;/strong&gt; &lt;code&gt;demo&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Packaging:&lt;/strong&gt; Jar&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java:&lt;/strong&gt; 17 or newer (21 is a good choice)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependencies:&lt;/strong&gt; none for the first example. Later, we'll add &lt;strong&gt;Spring Web&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click &lt;strong&gt;Generate&lt;/strong&gt;, unzip the file and open the folder in your IDE. (IDEs like IntelliJ IDEA also have this built in.) You get this project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   demo/
   |-- pom.xml
   |-- mvnw, mvnw.cmd, .mvn/            &amp;lt;- the Maven Wrapper (run Maven without installing it)
   +-- src/
        |-- main/
        |    |-- java/com/example/demo/DemoApplication.java
        |    +-- resources/application.properties
        +-- test/java/com/example/demo/DemoApplicationTests.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated &lt;code&gt;pom.xml&lt;/code&gt; (trimmed) looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;parent&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-parent&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;4.1.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;relativePath/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/parent&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;java.version&amp;gt;&lt;/span&gt;21&lt;span class="nt"&gt;&amp;lt;/java.version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-test&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;parent&lt;/strong&gt; (&lt;code&gt;spring-boot-starter-parent&lt;/code&gt;) manages the versions of hundreds of libraries, and sets up sensible build defaults. That's why the dependencies below have no version numbers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;spring-boot-starter&lt;/code&gt;&lt;/strong&gt; is the core starter: Spring, logging and auto-configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;spring-boot-starter-test&lt;/code&gt;&lt;/strong&gt; brings testing tools (test scope only).&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Spring Boot Maven plugin&lt;/strong&gt; builds the runnable JAR.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(The version &lt;code&gt;4.1.0&lt;/code&gt; is just an example. Use whatever Initializr generates for you.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding the starter code
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;DemoApplication.java&lt;/code&gt;. This is the code everyone copies without understanding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example.demo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.SpringApplication&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.autoconfigure.SpringBootApplication&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DemoApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DemoApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's decode it word by word. First, a version of &lt;code&gt;main&lt;/code&gt; that actually uses the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ApplicationContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DemoApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@SpringBootApplication&lt;/code&gt;&lt;/strong&gt; marks this as the starting configuration class, and turns on auto-configuration and component scanning (see the earlier section).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;SpringApplication&lt;/code&gt;&lt;/strong&gt; is the Boot class that &lt;strong&gt;starts everything&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;SpringApplication.run(DemoApplication.class, args)&lt;/code&gt;&lt;/strong&gt;: this one call creates the container, loads the settings, scans for components, applies auto-configuration, creates all the beans and (for web apps) starts the server.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;DemoApplication.class&lt;/code&gt;&lt;/strong&gt; is the main configuration class, where scanning begins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;args&lt;/code&gt;&lt;/strong&gt; are the command-line arguments, like &lt;code&gt;--server.port=9090&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;context&lt;/code&gt;&lt;/strong&gt; (the &lt;code&gt;ApplicationContext&lt;/code&gt;) is the &lt;strong&gt;Spring container&lt;/strong&gt;: the object that holds all your beans. &lt;code&gt;run&lt;/code&gt; returns it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;context.getBean(Dev.class)&lt;/code&gt;&lt;/strong&gt; asks the container for the bean of type &lt;code&gt;Dev&lt;/code&gt; (dependency lookup).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A bean&lt;/strong&gt; is any object the container created and manages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Component&lt;/code&gt;&lt;/strong&gt; (next) is what makes &lt;code&gt;Dev&lt;/code&gt; a bean in the first place.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And notice the most important thing again: &lt;strong&gt;we never wrote &lt;code&gt;new Dev()&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding beans: Dev, Computer and Laptop
&lt;/h3&gt;

&lt;p&gt;Create these three files in &lt;code&gt;com.example.demo&lt;/code&gt;, next to &lt;code&gt;DemoApplication&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Laptop&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Compiling on Laptop"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dev is building the project..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Import &lt;code&gt;org.springframework.stereotype.Component&lt;/code&gt; in the last two.) Here's what's going on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@Component&lt;/code&gt; on &lt;code&gt;Laptop&lt;/code&gt; and &lt;code&gt;Dev&lt;/code&gt; makes them beans. Spring finds them because they're in the same package as the main class.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Dev&lt;/code&gt; needs a &lt;code&gt;Computer&lt;/code&gt;. Spring sees the constructor, finds a &lt;code&gt;Computer&lt;/code&gt; bean (&lt;code&gt;Laptop&lt;/code&gt;) and &lt;strong&gt;injects it automatically&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;There's &lt;strong&gt;no &lt;code&gt;@Autowired&lt;/code&gt;&lt;/strong&gt; on the constructor, because a class with a single constructor doesn't need it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Running the application
&lt;/h3&gt;

&lt;p&gt;Use the version of &lt;code&gt;main&lt;/code&gt; that calls &lt;code&gt;getBean&lt;/code&gt;, then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw spring-boot:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output (after the Spring banner and a few &lt;code&gt;INFO&lt;/code&gt; log lines):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dev is building the project...
Compiling on Laptop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What if you forget &lt;code&gt;@Component&lt;/code&gt; on &lt;code&gt;Laptop&lt;/code&gt;? Spring can't find a &lt;code&gt;Computer&lt;/code&gt;, and the app fails to start with a clear message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APPLICATION FAILED TO START

Description:

Parameter 0 of constructor in com.example.demo.Dev required a bean of type
'com.example.demo.Computer' that could not be found.

Action:

Consider defining a bean of type 'com.example.demo.Computer' in your configuration.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The three types of dependency injection
&lt;/h2&gt;

&lt;p&gt;There are three ways the container can hand a dependency to your object. Let's write &lt;code&gt;Dev&lt;/code&gt; all three ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constructor injection
&lt;/h3&gt;

&lt;p&gt;The dependency comes in through the &lt;strong&gt;constructor&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;       &lt;span class="c1"&gt;// no @Autowired needed&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;It needs &lt;strong&gt;no &lt;code&gt;@Autowired&lt;/code&gt;&lt;/strong&gt; when the class has &lt;strong&gt;one constructor&lt;/strong&gt; (this has been true since Spring 4.3). If a class has several constructors, mark the one Spring should use with &lt;code&gt;@Autowired&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Spring must create the &lt;code&gt;Laptop&lt;/code&gt; &lt;strong&gt;first&lt;/strong&gt;, then call the &lt;code&gt;Dev&lt;/code&gt; constructor with it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setter injection
&lt;/h3&gt;

&lt;p&gt;The dependency comes in through a &lt;strong&gt;setter method&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setComputer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;It &lt;strong&gt;needs &lt;code&gt;@Autowired&lt;/code&gt;&lt;/strong&gt; on the setter. Without it, Spring creates the object with the default constructor and never calls the setter, so &lt;code&gt;computer&lt;/code&gt; stays &lt;code&gt;null&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Spring creates &lt;code&gt;Dev&lt;/code&gt; first (with the no-argument constructor), then calls the setter.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Field injection
&lt;/h3&gt;

&lt;p&gt;The dependency is placed &lt;strong&gt;directly into the field&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;It &lt;strong&gt;needs &lt;code&gt;@Autowired&lt;/code&gt;&lt;/strong&gt; on the field.&lt;/li&gt;
&lt;li&gt;Spring creates &lt;code&gt;Dev&lt;/code&gt;, then uses &lt;strong&gt;reflection&lt;/strong&gt; to set the private field. There's no constructor or setter involved.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three give the same output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dev is building the project...
Compiling on Laptop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Which injection to use
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         NEEDS @Autowired?        BEST FOR
   Constructor           No (one constructor)     required dependencies  &amp;lt;-- recommended
   Setter                Yes                      optional or changeable dependencies
   Field                 Yes                      quick demos and test classes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;strong&gt;constructor injection&lt;/strong&gt; by default. The reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The dependency can be &lt;strong&gt;&lt;code&gt;final&lt;/code&gt;&lt;/strong&gt;, so the object can't be left half-built.&lt;/li&gt;
&lt;li&gt;Required dependencies are &lt;strong&gt;obvious&lt;/strong&gt; from the constructor.&lt;/li&gt;
&lt;li&gt;It's easy to &lt;strong&gt;test&lt;/strong&gt;: &lt;code&gt;new Dev(new FakeComputer())&lt;/code&gt;, with no Spring needed.&lt;/li&gt;
&lt;li&gt;Missing beans and &lt;strong&gt;circular dependencies&lt;/strong&gt; are caught at startup, not later. (Spring Boot refuses circular references by default.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Field injection looks shorter, but it hides the dependencies, can't use &lt;code&gt;final&lt;/code&gt;, can't be tested without Spring or reflection, and the field stays &lt;code&gt;null&lt;/code&gt; if someone creates the object with a plain &lt;code&gt;new&lt;/code&gt;. Setter injection is a good choice for &lt;em&gt;optional&lt;/em&gt; dependencies, and you can use &lt;code&gt;@Autowired(required = false)&lt;/code&gt; for those.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resolving ambiguity: &lt;a class="mentioned-user" href="https://dev.to/primary"&gt;@primary&lt;/a&gt; and @Qualifier
&lt;/h2&gt;

&lt;p&gt;What happens when two beans match? Add a &lt;code&gt;Desktop&lt;/code&gt; next to &lt;code&gt;Laptop&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Desktop&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Compiling on Desktop"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now &lt;code&gt;Dev&lt;/code&gt; asks for a &lt;code&gt;Computer&lt;/code&gt; and gets two candidates. Spring Boot refuses to start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APPLICATION FAILED TO START

Description:

Parameter 0 of constructor in com.example.demo.Dev required a single bean, but 2 were found:
    - desktop: defined in file [.../Desktop.class]
    - laptop: defined in file [.../Laptop.class]

Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans,
or using @Qualifier to identify the bean that should be consumed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error message itself tells you the fixes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix 1: &lt;code&gt;@Primary&lt;/code&gt;.&lt;/strong&gt; Mark one bean as the default choice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="nd"&gt;@Primary&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Laptop&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Compiling on Laptop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix 2: &lt;code&gt;@Qualifier&lt;/code&gt;.&lt;/strong&gt; Name the exact bean at the place where you inject it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Dev&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Qualifier&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"desktop"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Compiling on Desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The name &lt;code&gt;"desktop"&lt;/code&gt; is the bean's default name (the class name with a lowercase first letter). You can set your own with &lt;code&gt;@Component("fast")&lt;/code&gt; and then use &lt;code&gt;@Qualifier("fast")&lt;/code&gt;. With field injection, you write both annotations together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;
&lt;span class="nd"&gt;@Qualifier&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"desktop"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="n"&gt;computer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How they differ:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Primary&lt;/code&gt;&lt;/strong&gt; is a &lt;strong&gt;default&lt;/strong&gt; for the whole application: "if nobody says otherwise, use this one."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Qualifier&lt;/code&gt;&lt;/strong&gt; is an &lt;strong&gt;explicit choice&lt;/strong&gt; at one injection point. &lt;strong&gt;If both are present, &lt;code&gt;@Qualifier&lt;/code&gt; wins.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These map to the XML ideas you saw earlier: &lt;code&gt;@Primary&lt;/code&gt; is like &lt;code&gt;primary="true"&lt;/code&gt;, and &lt;code&gt;@Qualifier&lt;/code&gt; is like &lt;code&gt;autowire="byName"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are two more ways to deal with several beans:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Match by name:&lt;/strong&gt; if the parameter is named &lt;code&gt;desktop&lt;/code&gt; (&lt;code&gt;public Dev(Computer desktop)&lt;/code&gt;), Spring falls back to matching the name. It works, but renaming the parameter silently changes the behavior, so &lt;code&gt;@Qualifier&lt;/code&gt; is safer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inject them all:&lt;/strong&gt; ask for &lt;code&gt;List&amp;lt;Computer&amp;gt;&lt;/code&gt; or &lt;code&gt;Map&amp;lt;String, Computer&amp;gt;&lt;/code&gt;, and Spring gives you every matching bean.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The lifecycle of a bean
&lt;/h2&gt;

&lt;p&gt;Here's what "Spring manages the lifecycle of all your objects" means. Every bean goes through the same stages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   1. INSTANTIATE        the constructor is called
          |
          v
   2. INJECT             dependencies are set (constructor, setter or field)
          |
          v
   3. INITIALIZE         @PostConstruct methods run
          |
          v
   4. READY              the bean is used by your application
          |
          v
   5. DESTROY            @PreDestroy methods run when the container shuts down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's watch it happen by adding messages to &lt;code&gt;Laptop&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Laptop&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Laptop&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Laptop: constructor called"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@PostConstruct&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Laptop: @PostConstruct, ready to use"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Compiling on Laptop"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@PreDestroy&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Laptop: @PreDestroy, shutting down"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;code&gt;@PostConstruct&lt;/code&gt; and &lt;code&gt;@PreDestroy&lt;/code&gt; come from &lt;code&gt;jakarta.annotation&lt;/code&gt;.) Run the app. Output (between the Spring log lines):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Laptop: constructor called
Laptop: @PostConstruct, ready to use
Dev is building the project...
Compiling on Laptop
Laptop: @PreDestroy, shutting down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Things to notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Singleton beans are created &lt;strong&gt;when the application starts&lt;/strong&gt;, in dependency order (the &lt;code&gt;Laptop&lt;/code&gt; before the &lt;code&gt;Dev&lt;/code&gt; that needs it).&lt;/li&gt;
&lt;li&gt;Our &lt;code&gt;main&lt;/code&gt; didn't call any of these methods. The &lt;strong&gt;container&lt;/strong&gt; did.&lt;/li&gt;
&lt;li&gt;When the application ends, the container closes and calls &lt;code&gt;@PreDestroy&lt;/code&gt; on each singleton. This is the place to close resources like files or connections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A few related facts: the default scope is &lt;strong&gt;singleton&lt;/strong&gt; (one shared bean). You can use &lt;code&gt;@Scope("prototype")&lt;/code&gt; to get a new instance each time, but then Spring doesn't call destroy methods for it. &lt;code&gt;@Lazy&lt;/code&gt; delays creation until first use. And because singletons are shared by all threads, &lt;strong&gt;keep them stateless&lt;/strong&gt;: don't store per-request data in their fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a web endpoint with Spring Web
&lt;/h2&gt;

&lt;p&gt;Now let's use &lt;strong&gt;Spring Web&lt;/strong&gt;. Add the dependency (on Initializr, pick &lt;strong&gt;Spring Web&lt;/strong&gt;, or add this to &lt;code&gt;pom.xml&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-webmvc&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(In Spring Boot 3.x, this starter is called &lt;code&gt;spring-boot-starter-web&lt;/code&gt;.) Then add a service and a controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetingService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello, "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"!"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HelloController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;GreetingService&lt;/span&gt; &lt;span class="n"&gt;greetingService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;HelloController&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;GreetingService&lt;/span&gt; &lt;span class="n"&gt;greetingService&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;greetingService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;greetingService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/hello"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@RequestParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;defaultValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"World"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;greetingService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;greet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the app, and the log shows that Tomcat started (on port 8080 by default). The application keeps running, until you stop it with Ctrl+C. Now call it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/hello
curl &lt;span class="s2"&gt;"http://localhost:8080/hello?name=Asha"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello, World!
Hello, Asha!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what happened:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   curl  --&amp;gt;  embedded Tomcat  --&amp;gt;  DispatcherServlet  --&amp;gt;  HelloController.hello("Asha")
                                                                   |  (it was given a GreetingService
                                                                   v   by constructor injection)
                                                            GreetingService.greet("Asha")
                                                                   |
   curl  &amp;lt;--  response: "Hello, Asha!"  &amp;lt;-------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@RestController&lt;/code&gt;&lt;/strong&gt; means "this class handles web requests, and returns the data directly as the response body." (If you return an object instead of a string, Boot converts it to JSON for you.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@GetMapping("/hello")&lt;/code&gt;&lt;/strong&gt; maps HTTP &lt;code&gt;GET /hello&lt;/code&gt; to the method.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@RequestParam&lt;/code&gt;&lt;/strong&gt; reads the &lt;code&gt;name&lt;/code&gt; from the URL.&lt;/li&gt;
&lt;li&gt;Dependency injection works the same as before: the controller got its &lt;code&gt;GreetingService&lt;/code&gt; through its constructor.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuration with application.properties
&lt;/h2&gt;

&lt;p&gt;Spring Boot reads settings from &lt;code&gt;src/main/resources/application.properties&lt;/code&gt; (or &lt;code&gt;application.yml&lt;/code&gt;). Some examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;server.port&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;9090&lt;/span&gt;
&lt;span class="py"&gt;spring.application.name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;demo&lt;/span&gt;
&lt;span class="py"&gt;app.greeting&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Welcome&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;server.port&lt;/code&gt; changes the web server's port.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;app.greeting&lt;/code&gt; is &lt;strong&gt;your own&lt;/strong&gt; setting. Read it into a bean with &lt;code&gt;@Value&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetingService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;greeting&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;GreetingService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Value&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${app.greeting:Hello}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;greeting&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;greeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;greeting&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;greeting&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"!"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;:Hello&lt;/code&gt; part is a &lt;strong&gt;default&lt;/strong&gt; used if the property isn't set. With &lt;code&gt;app.greeting=Welcome&lt;/code&gt;, the endpoint now returns &lt;code&gt;Welcome, Asha!&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A few more useful facts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Settings can be overridden by &lt;strong&gt;environment variables&lt;/strong&gt; (&lt;code&gt;SERVER_PORT=9090&lt;/code&gt;) and by &lt;strong&gt;command-line arguments&lt;/strong&gt; (&lt;code&gt;--server.port=9090&lt;/code&gt;). Those are the &lt;code&gt;args&lt;/code&gt; we passed to &lt;code&gt;SpringApplication.run&lt;/code&gt;. Command-line arguments win over the properties file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Profiles&lt;/strong&gt; let you keep different settings per environment. Put them in &lt;code&gt;application-dev.properties&lt;/code&gt; and turn them on with &lt;code&gt;spring.profiles.active=dev&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For groups of related settings, look at &lt;code&gt;@ConfigurationProperties&lt;/code&gt;, which binds them to a Java class.&lt;/li&gt;
&lt;li&gt;Don't put real passwords in the file. Use environment variables or a secrets manager.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Running, packaging and testing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Run during development:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw spring-boot:run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Package a runnable JAR:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./mvnw clean package
java &lt;span class="nt"&gt;-jar&lt;/span&gt; target/demo-0.0.1-SNAPSHOT.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the Maven post, a plain JAR failed with "no main manifest attribute." A Spring Boot JAR works, because the Boot Maven plugin turns it into an &lt;strong&gt;executable "fat JAR"&lt;/strong&gt;: it contains your classes, all the libraries, the embedded server and the information about the main class. You can override settings at launch, like &lt;code&gt;java -jar target/demo-0.0.1-SNAPSHOT.jar --server.port=9090&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check the application's health.&lt;/strong&gt; Add the &lt;code&gt;spring-boot-starter-actuator&lt;/code&gt; dependency, and &lt;code&gt;http://localhost:8080/actuator/health&lt;/code&gt; returns &lt;code&gt;{"status":"UP"}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test it.&lt;/strong&gt; &lt;code&gt;@SpringBootTest&lt;/code&gt; starts the whole container for a test, and you can inject beans straight into the test class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DemoApplicationTests&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Dev&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;devBeanIsCreated&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertNotNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Field injection is perfectly fine in test classes. For testing just the web layer, there are focused test annotations like &lt;code&gt;@WebMvcTest&lt;/code&gt;. The test starter brings in JUnit, so everything in my JUnit post applies here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use constructor injection&lt;/strong&gt; for required dependencies, with &lt;code&gt;final&lt;/code&gt; fields.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never create beans with &lt;code&gt;new&lt;/code&gt;.&lt;/strong&gt; Let the container do it, otherwise injection and the lifecycle are skipped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Depend on interfaces&lt;/strong&gt; (&lt;code&gt;Computer&lt;/code&gt;), not concrete classes, so implementations can be swapped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep beans stateless.&lt;/strong&gt; Singletons are shared between threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep the layers clean:&lt;/strong&gt; controller, service, repository. Put business logic in services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Put the main class in the root package&lt;/strong&gt;, so component scanning finds everything below it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;@Qualifier&lt;/code&gt; with meaningful names&lt;/strong&gt;, and use &lt;code&gt;@Primary&lt;/code&gt; sparingly for the one obvious default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use the specific stereotypes&lt;/strong&gt; (&lt;code&gt;@Service&lt;/code&gt;, &lt;code&gt;@Repository&lt;/code&gt;, &lt;code&gt;@RestController&lt;/code&gt;) instead of plain &lt;code&gt;@Component&lt;/code&gt; everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Externalize configuration&lt;/strong&gt; in &lt;code&gt;application.properties&lt;/code&gt;, profiles and environment variables, and keep secrets out of code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid circular dependencies.&lt;/strong&gt; Redesign instead of fighting the container.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;getBean&lt;/code&gt; only in &lt;code&gt;main&lt;/code&gt; and tests.&lt;/strong&gt; In application code, use injection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Let the Boot parent or BOM manage versions&lt;/strong&gt;, and don't override library versions unless you must.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read the startup error.&lt;/strong&gt; Spring Boot's failure messages usually tell you exactly what to fix.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spring Framework alone or Spring Boot?&lt;/strong&gt; Spring Boot for almost every new project. Plain Spring for learning the core, and for older applications that already use it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XML, annotations or Java configuration?&lt;/strong&gt; Annotations (&lt;code&gt;@Component&lt;/code&gt;) for your own classes, &lt;code&gt;@Bean&lt;/code&gt; methods for classes you don't own, and XML only in legacy code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constructor, setter or field injection?&lt;/strong&gt; Constructor by default, setter for optional dependencies, and field injection only in tests or quick demos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Primary&lt;/code&gt; or &lt;code&gt;@Qualifier&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;@Primary&lt;/code&gt; for a clear default, &lt;code&gt;@Qualifier&lt;/code&gt; when a specific place needs a specific bean.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Component&lt;/code&gt; or &lt;code&gt;@Bean&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;@Component&lt;/code&gt; on your classes. &lt;code&gt;@Bean&lt;/code&gt; for library classes or special setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;BeanFactory&lt;/code&gt; or &lt;code&gt;ApplicationContext&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;ApplicationContext&lt;/code&gt;, always.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring MVC or WebFlux?&lt;/strong&gt; Spring MVC (&lt;code&gt;spring-boot-starter-webmvc&lt;/code&gt;) for most applications. WebFlux for reactive, non-blocking designs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Singleton or prototype?&lt;/strong&gt; Singleton (the default) for stateless beans. Prototype when each user of the bean needs its own instance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;getBean&lt;/code&gt; or injection?&lt;/strong&gt; Injection in application code. &lt;code&gt;getBean&lt;/code&gt; only where you have no other way in, like &lt;code&gt;main&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.properties&lt;/code&gt; or &lt;code&gt;.yml&lt;/code&gt;?&lt;/strong&gt; Either. YAML is neater for nested settings, and properties are simpler. Use the one your team prefers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Creating beans with &lt;code&gt;new&lt;/code&gt;.&lt;/strong&gt; If you write &lt;code&gt;new Dev()&lt;/code&gt; yourself, Spring doesn't know about that object, so its &lt;code&gt;@Autowired&lt;/code&gt; fields stay &lt;code&gt;null&lt;/code&gt; and you get a &lt;code&gt;NullPointerException&lt;/code&gt;. Ask the container for it, or inject it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing &lt;code&gt;@Component&lt;/code&gt;, or a class outside the scan.&lt;/strong&gt; The error says "required a bean of type ... that could not be found." Check the annotation, and check that the class is in the main class's package or one of its sub-packages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two beans of the same type.&lt;/strong&gt; You get "required a single bean, but 2 were found." Use &lt;code&gt;@Primary&lt;/code&gt; or &lt;code&gt;@Qualifier&lt;/code&gt;, or inject a &lt;code&gt;List&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forgetting &lt;code&gt;@Autowired&lt;/code&gt; on a setter or field.&lt;/strong&gt; Spring doesn't complain, and the dependency stays &lt;code&gt;null&lt;/code&gt;. (Constructor injection with a single constructor doesn't need it.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keeping state in singleton beans.&lt;/strong&gt; A singleton is shared by every request and thread. Fields that change per user lead to confusing bugs. Keep beans stateless.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XML slips.&lt;/strong&gt; &lt;code&gt;ByType&lt;/code&gt; instead of &lt;code&gt;byType&lt;/code&gt;, a wrong class name, a &lt;code&gt;&amp;lt;property name="comp"&amp;gt;&lt;/code&gt; with no &lt;code&gt;setComp&lt;/code&gt; method, a missing no-argument constructor, or a bean &lt;code&gt;id&lt;/code&gt; that doesn't match the property name when using &lt;code&gt;byName&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Creating objects with &lt;code&gt;new&lt;/code&gt; ties classes together. &lt;strong&gt;Dependency injection&lt;/strong&gt; gives an object its dependencies from outside, and &lt;strong&gt;Spring automates the wiring&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IoC&lt;/strong&gt; is the principle: the container, not your code, controls object creation. &lt;strong&gt;DI&lt;/strong&gt; is the technique (the container gives objects what they need). &lt;code&gt;getBean&lt;/code&gt; is the other form, called dependency lookup.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Spring container&lt;/strong&gt; (&lt;code&gt;ApplicationContext&lt;/code&gt;) creates &lt;strong&gt;beans&lt;/strong&gt;, injects their dependencies and manages their lifecycle: instantiate, inject, &lt;code&gt;@PostConstruct&lt;/code&gt;, ready, &lt;code&gt;@PreDestroy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XML configuration:&lt;/strong&gt; &lt;code&gt;&amp;lt;beans&amp;gt;&lt;/code&gt; is the root, &lt;code&gt;&amp;lt;bean id class&amp;gt;&lt;/code&gt; defines an object, &lt;code&gt;&amp;lt;property&amp;gt;&lt;/code&gt; is setter injection, &lt;code&gt;&amp;lt;constructor-arg&amp;gt;&lt;/code&gt; is constructor injection, &lt;code&gt;autowire="byName"&lt;/code&gt; or &lt;code&gt;"byType"&lt;/code&gt; lets Spring find dependencies, and &lt;code&gt;primary="true"&lt;/code&gt; resolves conflicts. You load it with &lt;code&gt;ClassPathXmlApplicationContext("spring.xml")&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Annotations:&lt;/strong&gt; &lt;code&gt;@Component&lt;/code&gt; (and &lt;code&gt;@Service&lt;/code&gt;, &lt;code&gt;@Repository&lt;/code&gt;, &lt;code&gt;@RestController&lt;/code&gt;) create beans, &lt;code&gt;@Configuration&lt;/code&gt; with &lt;code&gt;@Bean&lt;/code&gt; handles special cases, and &lt;code&gt;@Primary&lt;/code&gt; and &lt;code&gt;@Qualifier&lt;/code&gt; resolve ambiguity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Three kinds of DI:&lt;/strong&gt; constructor (no &lt;code&gt;@Autowired&lt;/code&gt; needed for a single constructor, and the best choice), setter (needs &lt;code&gt;@Autowired&lt;/code&gt;) and field (needs &lt;code&gt;@Autowired&lt;/code&gt;, and is discouraged).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring Boot&lt;/strong&gt; is Spring with the setup done for you: starters, auto-configuration, an embedded server and an executable JAR. It creates the objects you need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring&lt;/strong&gt; is the foundation, &lt;strong&gt;Spring Web&lt;/strong&gt; (Spring MVC) is its web module, and &lt;strong&gt;Spring Boot&lt;/strong&gt; is the layer that sets it all up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;SpringApplication.run(DemoApplication.class, args)&lt;/code&gt;&lt;/strong&gt; creates the container, scans, auto-configures, creates the beans and starts the server. It returns the &lt;code&gt;ApplicationContext&lt;/code&gt;, and &lt;code&gt;getBean(Dev.class)&lt;/code&gt; fetches a bean from it.&lt;/li&gt;
&lt;li&gt;A Boot application is layered: &lt;strong&gt;controller, service, repository&lt;/strong&gt;, each one injected into the layer above.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: build the &lt;code&gt;Dev&lt;/code&gt;, &lt;code&gt;Computer&lt;/code&gt;, &lt;code&gt;Laptop&lt;/code&gt; and &lt;code&gt;Desktop&lt;/code&gt; example twice. First use plain Spring with &lt;code&gt;spring.xml&lt;/code&gt;: wire it with &lt;code&gt;&amp;lt;property&amp;gt;&lt;/code&gt;, then with &lt;code&gt;&amp;lt;constructor-arg&amp;gt;&lt;/code&gt;, then with &lt;code&gt;autowire="byType"&lt;/code&gt;, and make the two-bean error happen on purpose before fixing it with &lt;code&gt;primary="true"&lt;/code&gt; and again with &lt;code&gt;byName&lt;/code&gt;. Then rebuild the same thing in Spring Boot with &lt;code&gt;@Component&lt;/code&gt;, and break it with a second &lt;code&gt;Computer&lt;/code&gt; bean before fixing it with &lt;code&gt;@Primary&lt;/code&gt; and &lt;code&gt;@Qualifier&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, add &lt;code&gt;@PostConstruct&lt;/code&gt; and &lt;code&gt;@PreDestroy&lt;/code&gt; messages to a bean and watch the order. Then add Spring Web, write a &lt;code&gt;/hello&lt;/code&gt; endpoint that uses a service with constructor injection, change the port with &lt;code&gt;--server.port=9090&lt;/code&gt;, and package everything into a JAR you can start with &lt;code&gt;java -jar&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

</description>
      <category>java</category>
      <category>spring</category>
      <category>springboot</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Why ORMs Exist: The Object-Relational Mismatch</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:13:48 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/why-orms-exist-the-object-relational-mismatch-b2n</link>
      <guid>https://dev.to/mayur_bodhare/why-orms-exist-the-object-relational-mismatch-b2n</guid>
      <description>&lt;p&gt;After learning JDBC, I was proud of myself. I could connect to a database, run queries and read the results. Then I built a real project with 12 tables, and my code filled up with the same pattern again and again: open a connection, prepare a statement, set five parameters, run it, loop over a &lt;code&gt;ResultSet&lt;/code&gt;, copy each column into an object, close everything. Changing one column name meant hunting through dozens of SQL strings.&lt;/p&gt;

&lt;p&gt;That's the problem &lt;strong&gt;ORM tools&lt;/strong&gt; were invented to solve, and &lt;strong&gt;Hibernate&lt;/strong&gt; is the most famous one in Java. You describe how your classes map to tables once, and Hibernate writes and runs the SQL for you.&lt;/p&gt;

&lt;p&gt;In this post, we'll learn what ORM is and which problem it solves, its pros and cons, what Hibernate is and how it works, how to use it &lt;strong&gt;with and without Maven&lt;/strong&gt; (using PostgreSQL), the common methods you'll use, how Hibernate relates to &lt;strong&gt;Jakarta Persistence (JPA)&lt;/strong&gt;, and a &lt;strong&gt;step-by-step example in the Spring Framework&lt;/strong&gt;. I've also added things beginners usually miss: the entity lifecycle, lazy loading, the N+1 problem, caching and versioning.&lt;/p&gt;

&lt;p&gt;A version note: I wrote this for &lt;strong&gt;Hibernate ORM 7.4&lt;/strong&gt; and &lt;strong&gt;Spring Framework 7.0&lt;/strong&gt;. Both need &lt;strong&gt;Java 17 or newer&lt;/strong&gt;. If you work on an older project (Hibernate 5 or 6), the section on older Hibernate methods tells you what changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
What is an ORM?

&lt;ul&gt;
&lt;li&gt;The problem: objects and tables do not match&lt;/li&gt;
&lt;li&gt;How an ORM solves it&lt;/li&gt;
&lt;li&gt;The same job, with and without an ORM&lt;/li&gt;
&lt;li&gt;Popular ORM tools&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Pros and cons of ORMs

&lt;ul&gt;
&lt;li&gt;Advantages&lt;/li&gt;
&lt;li&gt;Disadvantages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
What is Hibernate?

&lt;ul&gt;
&lt;li&gt;How Hibernate fits in&lt;/li&gt;
&lt;li&gt;The core pieces: SessionFactory, Session and Transaction&lt;/li&gt;
&lt;li&gt;The life of an entity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Setting up PostgreSQL for the examples&lt;/li&gt;
&lt;li&gt;
The common code: entity and main class

&lt;ul&gt;
&lt;li&gt;The entity class&lt;/li&gt;
&lt;li&gt;The main class&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Using Hibernate without Maven

&lt;ul&gt;
&lt;li&gt;Step by step without Maven&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Using Hibernate with Maven

&lt;ul&gt;
&lt;li&gt;Step by step with Maven&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Common Hibernate methods

&lt;ul&gt;
&lt;li&gt;Saving, reading, updating and deleting&lt;/li&gt;
&lt;li&gt;Queries with HQL&lt;/li&gt;
&lt;li&gt;Managing the persistence context&lt;/li&gt;
&lt;li&gt;Transactions and the safe pattern&lt;/li&gt;
&lt;li&gt;Methods from older Hibernate versions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Mapping relationships and loading data

&lt;ul&gt;
&lt;li&gt;One-to-many and many-to-one&lt;/li&gt;
&lt;li&gt;Lazy loading and the N+1 problem&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Hibernate vs Jakarta Persistence

&lt;ul&gt;
&lt;li&gt;What each one is&lt;/li&gt;
&lt;li&gt;The same code in both styles&lt;/li&gt;
&lt;li&gt;Which one to code against&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Hibernate in the Spring Framework

&lt;ul&gt;
&lt;li&gt;Step 1: Add the dependencies&lt;/li&gt;
&lt;li&gt;Step 2: Create the entity&lt;/li&gt;
&lt;li&gt;Step 3: Create the repository&lt;/li&gt;
&lt;li&gt;Step 4: Create the service&lt;/li&gt;
&lt;li&gt;Step 5: Configure Spring&lt;/li&gt;
&lt;li&gt;Step 6: Run the application&lt;/li&gt;
&lt;li&gt;How Spring and Hibernate work together&lt;/li&gt;
&lt;li&gt;The shortcut: Spring Boot and Spring Data JPA&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Other things worth knowing

&lt;ul&gt;
&lt;li&gt;Configuration settings&lt;/li&gt;
&lt;li&gt;Caching&lt;/li&gt;
&lt;li&gt;Optimistic locking with @Version&lt;/li&gt;
&lt;li&gt;Managing the schema in real projects&lt;/li&gt;
&lt;li&gt;Logging the SQL&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Best practices&lt;/li&gt;
&lt;li&gt;Which one should I use?&lt;/li&gt;
&lt;li&gt;Common mistakes&lt;/li&gt;
&lt;li&gt;Quick recap&lt;/li&gt;
&lt;li&gt;Try it yourself&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is an ORM?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ORM&lt;/strong&gt; stands for &lt;strong&gt;Object-Relational Mapping&lt;/strong&gt;. It's a technique (and a kind of tool) that connects the two worlds a Java developer lives in: &lt;strong&gt;objects&lt;/strong&gt; in your code and &lt;strong&gt;tables&lt;/strong&gt; in a relational database. A class maps to a table, an object maps to a row, and a field maps to a column. Instead of writing SQL for every operation, you work with objects, and the ORM does the translating.&lt;/p&gt;

&lt;h3&gt;
  
  
  The problem: objects and tables do not match
&lt;/h3&gt;

&lt;p&gt;With plain JDBC, you do all the translating by hand. Every query repeats the same steps, and your SQL strings are scattered through the code. That's tiring, but it's not the deepest problem.&lt;/p&gt;

&lt;p&gt;The deeper problem is that objects and tables are built on &lt;strong&gt;different ideas&lt;/strong&gt;. This gap has a name: the &lt;strong&gt;object-relational impedance mismatch&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   OBJECT WORLD (Java)                        RELATIONAL WORLD (database)
   classes, objects, fields                   tables, rows, columns
   references between objects                 foreign keys and joins
   inheritance (Dog extends Animal)           no inheritance (flat tables)
   identity with == and equals()              identity with a primary key
   walk the graph: s.getCourse().getTitle()   write a JOIN in SQL
   collections: List&amp;lt;Student&amp;gt;                 a separate table with a foreign key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what that means in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inheritance:&lt;/strong&gt; Java has it, tables don't. How do you store &lt;code&gt;Dog&lt;/code&gt; and &lt;code&gt;Cat&lt;/code&gt;, which both extend &lt;code&gt;Animal&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity:&lt;/strong&gt; two Java objects can hold the same data but be different objects. In a database, a row is identified by its primary key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Associations:&lt;/strong&gt; in Java, a &lt;code&gt;Student&lt;/code&gt; holds a reference to a &lt;code&gt;Course&lt;/code&gt;. In a database, the &lt;code&gt;student&lt;/code&gt; table holds a foreign key column.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Navigation:&lt;/strong&gt; in Java you walk from object to object. In SQL, you join tables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing the code that bridges all this by hand, for every class, is slow and full of bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  How an ORM solves it
&lt;/h3&gt;

&lt;p&gt;An ORM does the bridging for you. You describe the mapping once, usually with &lt;strong&gt;annotations&lt;/strong&gt; on your classes. Then the ORM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generates the SQL for creating, reading, updating and deleting objects,&lt;/li&gt;
&lt;li&gt;turns query results back into objects,&lt;/li&gt;
&lt;li&gt;handles relationships between objects,&lt;/li&gt;
&lt;li&gt;tracks which objects changed and saves only those changes,&lt;/li&gt;
&lt;li&gt;manages transactions and caching,&lt;/li&gt;
&lt;li&gt;adapts the SQL to each database's dialect.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Java object                                   table row
   Student(id=1, name="Asha", marks=88)          student: id=1 | name='Asha' | marks=88
        |                                              ^
        |  session.persist(student)                    |
        +--- the ORM writes the SQL for you -----------+   insert into student ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The same job, with and without an ORM
&lt;/h3&gt;

&lt;p&gt;Saving and loading one student with &lt;strong&gt;plain JDBC&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;insert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"INSERT INTO student (name, marks) VALUES (?, ?)"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConnection&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
     &lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMarks&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;select&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SELECT id, name, marks FROM student WHERE id = ?"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConnection&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
     &lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setLong&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLong&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"marks"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same two jobs with &lt;strong&gt;Hibernate&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;                           &lt;span class="c1"&gt;// INSERT&lt;/span&gt;
&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// SELECT ... WHERE id = ?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two lines instead of twenty, and no column names to copy by hand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Popular ORM tools
&lt;/h3&gt;

&lt;p&gt;In Java:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hibernate ORM:&lt;/strong&gt; the most widely used ORM, and the main topic of this post.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EclipseLink:&lt;/strong&gt; another full ORM, and the reference implementation of the JPA standard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring Data JPA:&lt;/strong&gt; not an ORM itself, but a layer on top of JPA (usually Hibernate) that writes repository code for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Related tools that are &lt;em&gt;not&lt;/em&gt; full ORMs: &lt;strong&gt;MyBatis&lt;/strong&gt; (you write the SQL, it maps results to objects), &lt;strong&gt;jOOQ&lt;/strong&gt; (a type-safe way to write SQL in Java) and Spring's &lt;strong&gt;JdbcTemplate&lt;/strong&gt; (less boilerplate for JDBC).&lt;/p&gt;

&lt;p&gt;Other languages have their own: Entity Framework (.NET), SQLAlchemy and the Django ORM (Python), ActiveRecord (Ruby), Prisma and TypeORM (JavaScript and TypeScript).&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros and cons of ORMs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Much less boilerplate.&lt;/strong&gt; No more connection, statement and result set code for every query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You think in objects.&lt;/strong&gt; Your code stays object-oriented, and SQL is mostly hidden.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relationships are handled for you.&lt;/strong&gt; You walk from a &lt;code&gt;Student&lt;/code&gt; to a &lt;code&gt;Course&lt;/code&gt; as if they were ordinary objects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portability.&lt;/strong&gt; The ORM generates SQL for the database you use, so switching databases is often a configuration change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in features:&lt;/strong&gt; change tracking (only modified rows are updated), caching, lazy loading, optimistic locking and schema generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safer by default.&lt;/strong&gt; Values are sent as parameters, which protects you from SQL injection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One place for mapping.&lt;/strong&gt; Table and column names live in your entity classes, not in dozens of SQL strings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A standard.&lt;/strong&gt; Code written against JPA works with several ORM providers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A learning curve.&lt;/strong&gt; Sessions, entity states, fetching strategies and flushing are real concepts to learn.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hidden SQL.&lt;/strong&gt; You don't see the queries, so you can create slow ones without noticing. The famous example is the &lt;strong&gt;N+1 problem&lt;/strong&gt; (covered later).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leaky abstraction.&lt;/strong&gt; You still need to understand SQL, indexes and transactions to tune performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not ideal for everything.&lt;/strong&gt; Bulk updates, complex reports and heavy analytics are often better in plain SQL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory and startup cost.&lt;/strong&gt; The ORM tracks your objects and builds its mapping metadata when the app starts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Magic" that surprises.&lt;/strong&gt; For example, changing a field on a managed object can cause an &lt;code&gt;UPDATE&lt;/code&gt; without any save call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overkill for tiny apps.&lt;/strong&gt; For a few simple queries, JDBC (or &lt;code&gt;JdbcTemplate&lt;/code&gt;) may be enough.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema changes need care.&lt;/strong&gt; Letting the ORM modify a production schema automatically is risky.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest summary: an ORM saves a lot of work, but it doesn't remove the need to understand databases.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Hibernate?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hibernate ORM&lt;/strong&gt; is an open-source ORM framework for Java. Gavin King started it in 2001, and it became the most popular persistence tool in the Java world. Its ideas strongly influenced the &lt;strong&gt;JPA&lt;/strong&gt; standard (more on that later), and today Hibernate is the most widely used JPA implementation. It also adds many extra features of its own.&lt;/p&gt;

&lt;p&gt;Some current facts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Its Maven groupId is &lt;code&gt;org.hibernate.orm&lt;/code&gt;, and the main artifact is &lt;code&gt;hibernate-core&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Hibernate 7 needs &lt;strong&gt;Java 17+&lt;/strong&gt; and implements &lt;strong&gt;Jakarta Persistence 3.2&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;At the time of writing, the latest stable series is &lt;strong&gt;7.4&lt;/strong&gt; (7.4.13.Final), and Hibernate 8.0 (aimed at Jakarta Persistence 4.0) is still in development.&lt;/li&gt;
&lt;li&gt;Since version 7.0, it uses the Apache License 2.0.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Hibernate fits in
&lt;/h3&gt;

&lt;p&gt;Hibernate doesn't replace JDBC. It sits &lt;strong&gt;on top of it&lt;/strong&gt;. Everything you learned about JDBC still happens underneath:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   YOUR APPLICATION   (entity classes + Hibernate or JPA API)
          |
          v
   HIBERNATE ORM
     - reads your mapping (annotations on the entities)
     - turns your calls and HQL queries into SQL for your database (the "dialect")
     - tracks changes, caches objects, manages relationships
          |
          v
   JDBC   (Connection, PreparedStatement, ResultSet ...)
          |
          v
   JDBC DRIVER (the postgresql jar)   --&amp;gt;   PostgreSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every query Hibernate runs becomes a &lt;code&gt;PreparedStatement&lt;/code&gt;, so values are always sent safely as parameters. Hibernate also finds out which database you're using from the connection and picks the right dialect on its own, so you usually don't configure one.&lt;/p&gt;

&lt;h3&gt;
  
  
  The core pieces: SessionFactory, Session and Transaction
&lt;/h3&gt;

&lt;p&gt;Three objects do most of the work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   SessionFactory
     one per database, created ONCE when the app starts
     expensive to create, thread-safe, shared by everyone
          |
          |  openSession()
          v
   Session   (also an EntityManager)
     one per unit of work (for example, one web request)
     cheap, NOT thread-safe, wraps one JDBC connection
     holds the persistence context: a cache of the objects it is tracking
          |
          |  beginTransaction()
          v
   Transaction  --&amp;gt;  commit() or rollback()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;SessionFactory&lt;/code&gt;&lt;/strong&gt;: built once from your configuration and mapping. Think of it as the "factory" that makes sessions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Session&lt;/code&gt;&lt;/strong&gt;: your working conversation with the database. You open it, do some work and close it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Transaction&lt;/code&gt;&lt;/strong&gt;: groups the work so it succeeds or fails as a unit (the same idea as in the JDBC post).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistence context&lt;/strong&gt;: the "first-level cache" inside every session. Hibernate remembers every object it loaded or saved, and watches it for changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The life of an entity
&lt;/h3&gt;

&lt;p&gt;An &lt;strong&gt;entity&lt;/strong&gt; is a Java object that Hibernate manages (one that maps to a table). At any moment, an entity is in one of four states:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        new Student("Asha", 88)
                 |
            TRANSIENT       a plain object; Hibernate doesn't know it; no row exists
                 |
                 |  persist()
                 v
   find() / query results --&amp;gt;  PERSISTENT   (also called managed)
                 |             tracked in the persistence context; changes are saved automatically
                 |                  |
   session closes, detach(),        |  remove()
   or clear()                       v
                 |             REMOVED    (the row is deleted when the work is flushed)
                 v
            DETACHED        has an id and a row exists, but no session is tracking it
                 |
                 |  merge()  --&amp;gt;  returns a PERSISTENT copy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three ideas follow from this picture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dirty checking.&lt;/strong&gt; For a persistent entity, Hibernate remembers its original values. At commit time, it compares them with the current values and sends an &lt;code&gt;UPDATE&lt;/code&gt; only if something changed. You don't call "save" to update a managed object.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flush.&lt;/strong&gt; The moment Hibernate sends the pending SQL to the database is called a &lt;strong&gt;flush&lt;/strong&gt;. It happens automatically before a query that might be affected and at commit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity guarantee.&lt;/strong&gt; Inside one session, asking for the same row twice gives you the &lt;strong&gt;same object&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up PostgreSQL for the examples
&lt;/h2&gt;

&lt;p&gt;All examples use &lt;strong&gt;PostgreSQL&lt;/strong&gt;. The quickest way to get one is Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; school-db &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;secret &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;school &lt;span class="nt"&gt;-p&lt;/span&gt; 5432:5432 &lt;span class="nt"&gt;-d&lt;/span&gt; postgres:17
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This starts a PostgreSQL server on port 5432 with a database called &lt;code&gt;school&lt;/code&gt;, the user &lt;code&gt;postgres&lt;/code&gt; and the password &lt;code&gt;secret&lt;/code&gt;. (That password is only for local practice. Use a strong one and read it from an environment variable in real projects.)&lt;/p&gt;

&lt;p&gt;If you don't use Docker, install PostgreSQL from &lt;code&gt;postgresql.org&lt;/code&gt;, then create the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"CREATE DATABASE school;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our connection details for the rest of the post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URL: &lt;code&gt;jdbc:postgresql://localhost:5432/school&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;User: &lt;code&gt;postgres&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Password: &lt;code&gt;secret&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The common code: entity and main class
&lt;/h2&gt;

&lt;p&gt;The Java code is the same whether you use Maven or not. Only the way you get the libraries differs.&lt;/p&gt;

&lt;h3&gt;
  
  
  The entity class
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.Column&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.Entity&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.GenerationType&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.Id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.Table&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Entity&lt;/span&gt;
&lt;span class="nd"&gt;@Table&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"student"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Id&lt;/span&gt;
    &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IDENTITY&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nullable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nf"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// required by Hibernate&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;marks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="nf"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;      &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;  &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getMarks&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;    &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setMarks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;marks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Student{id="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", name='"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"', marks="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"}"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What each annotation does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Entity&lt;/code&gt;&lt;/strong&gt;: this class is mapped to a table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Table(name = "student")&lt;/code&gt;&lt;/strong&gt;: the table name. (Without it, Hibernate uses the class name.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Id&lt;/code&gt;&lt;/strong&gt;: the primary key field.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@GeneratedValue(strategy = IDENTITY)&lt;/code&gt;&lt;/strong&gt;: the database generates the id (an auto-increment column). Another common strategy is &lt;code&gt;SEQUENCE&lt;/code&gt;, which suits batching better.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Column(nullable = false, length = 50)&lt;/code&gt;&lt;/strong&gt;: column settings. A field with no annotation (like &lt;code&gt;marks&lt;/code&gt;) is mapped by default, to a column with the same name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rules for an entity class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It needs an &lt;strong&gt;&lt;code&gt;@Id&lt;/code&gt;&lt;/strong&gt; field.&lt;/li&gt;
&lt;li&gt;It needs a &lt;strong&gt;no-argument constructor&lt;/strong&gt; (it can be &lt;code&gt;protected&lt;/code&gt;, so your own code can't misuse it).&lt;/li&gt;
&lt;li&gt;It must &lt;strong&gt;not be &lt;code&gt;final&lt;/code&gt;&lt;/strong&gt;, because Hibernate creates subclasses (proxies) of entities.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;jakarta.persistence.*&lt;/code&gt; imports. The old &lt;code&gt;javax.persistence&lt;/code&gt; is from Hibernate 5 and earlier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With &lt;code&gt;hbm2ddl.auto&lt;/code&gt; set to &lt;code&gt;update&lt;/code&gt; (we'll set it below), Hibernate creates a table similar to this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;bigint&lt;/span&gt; &lt;span class="k"&gt;generated&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;marks&lt;/span&gt; &lt;span class="nb"&gt;integer&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;primary&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The main class
&lt;/h3&gt;

&lt;p&gt;This program creates a student, reads it, updates it, queries and deletes it, using the classic &lt;code&gt;Session&lt;/code&gt; and &lt;code&gt;Transaction&lt;/code&gt; style:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.hibernate.Session&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.hibernate.SessionFactory&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.hibernate.Transaction&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.hibernate.jpa.HibernatePersistenceConfiguration&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SessionFactory&lt;/span&gt; &lt;span class="n"&gt;sessionFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;buildSessionFactory&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

            &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved with id "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Found: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;findStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

            &lt;span class="n"&gt;updateMarks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;95&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"After update: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;findStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Top students: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;findTopStudents&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

            &lt;span class="n"&gt;deleteStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Deleted student "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;SessionFactory&lt;/span&gt; &lt;span class="nf"&gt;buildSessionFactory&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HibernatePersistenceConfiguration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"school"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;managedClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jdbcUrl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"jdbc:postgresql://localhost:5432/school"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jdbcCredentials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"secret"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;property&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hibernate.hbm2ddl.auto"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"update"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createEntityManagerFactory&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="nf"&gt;createStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SessionFactory&lt;/span&gt; &lt;span class="n"&gt;sf&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openSession&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Transaction&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;beginTransaction&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;                  &lt;span class="c1"&gt;// INSERT&lt;/span&gt;
            &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="nf"&gt;findStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SessionFactory&lt;/span&gt; &lt;span class="n"&gt;sf&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openSession&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// SELECT by primary key&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;updateMarks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SessionFactory&lt;/span&gt; &lt;span class="n"&gt;sf&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;newMarks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openSession&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Transaction&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;beginTransaction&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMarks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newMarks&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;                &lt;span class="c1"&gt;// no "update" call: dirty checking&lt;/span&gt;
            &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;                               &lt;span class="c1"&gt;// the UPDATE is sent here&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findTopStudents&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SessionFactory&lt;/span&gt; &lt;span class="n"&gt;sf&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;minMarks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openSession&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                            &lt;span class="s"&gt;"from Student s where s.marks &amp;gt;= :min order by s.marks desc"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                            &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"min"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minMarks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResultList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;deleteStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SessionFactory&lt;/span&gt; &lt;span class="n"&gt;sf&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openSession&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Transaction&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;beginTransaction&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;                   &lt;span class="c1"&gt;// DELETE&lt;/span&gt;
            &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output (the id may be different on your machine, and Hibernate also prints a few start-up log lines, which are normal):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Saved with id 1
Found: Student{id=1, name='Asha', marks=88}
After update: Student{id=1, name='Asha', marks=95}
Top students: [Student{id=1, name='Asha', marks=95}]
Deleted student 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go through the new parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;HibernatePersistenceConfiguration&lt;/code&gt;&lt;/strong&gt; is the modern way (Hibernate 7 and Jakarta Persistence 3.2) to configure Hibernate in plain Java code, with no XML file. You give it a name, the entity classes (&lt;code&gt;managedClass&lt;/code&gt;), the JDBC URL, the credentials and any extra property.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;hibernate.hbm2ddl.auto = update&lt;/code&gt;&lt;/strong&gt; tells Hibernate to create or update tables to match your entities. It's handy for learning, but not for production (see the schema section later).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;createEntityManagerFactory()&lt;/code&gt;&lt;/strong&gt; builds and returns the &lt;code&gt;SessionFactory&lt;/code&gt;. We use try-with-resources so it's closed when the program ends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;openSession()&lt;/code&gt;&lt;/strong&gt; gives us a &lt;code&gt;Session&lt;/code&gt; for one unit of work. Each method opens its own and closes it automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;persist&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;remove&lt;/code&gt;&lt;/strong&gt; are the basic operations, and the update works through &lt;strong&gt;dirty checking&lt;/strong&gt;: we changed a field of a managed object, and Hibernate wrote the &lt;code&gt;UPDATE&lt;/code&gt; at &lt;code&gt;commit()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The HQL query&lt;/strong&gt; (&lt;code&gt;from Student s where ...&lt;/code&gt;) is written against the entity and its fields (&lt;code&gt;Student&lt;/code&gt;, &lt;code&gt;s.marks&lt;/code&gt;), not the table and column names. The &lt;code&gt;:min&lt;/code&gt; is a named parameter, bound safely.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using Hibernate without Maven
&lt;/h2&gt;

&lt;p&gt;"Without Maven" means you manage the library files yourself. You put the jars in a folder and tell Java where they are.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step by step without Maven
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Install the tools.&lt;/strong&gt; You need a JDK 17 or newer, and PostgreSQL running with the &lt;code&gt;school&lt;/code&gt; database (see the setup section).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Create the project folders.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   hibernate-demo/
   |-- lib/                       &amp;lt;- all the jar files go here
   |-- src/
   |    +-- com/example/
   |         |-- Student.java
   |         +-- Main.java
   +-- out/                      &amp;lt;- compiled classes will go here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Get the jars into &lt;code&gt;lib/&lt;/code&gt;.&lt;/strong&gt; This is the hard part. &lt;code&gt;hibernate-core&lt;/code&gt; alone isn't enough. It needs a set of other libraries (for example the Jakarta Persistence API, a logging library, a bytecode library, a parser library and a few more), and those may need others. You have two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Option A, fully by hand:&lt;/strong&gt; go to Maven Central, download &lt;code&gt;hibernate-core-7.4.13.Final.jar&lt;/code&gt;, open its &lt;code&gt;.pom&lt;/code&gt; file to read the dependency list, download each one, and repeat for those too. Then download the PostgreSQL driver &lt;code&gt;postgresql-42.7.13.jar&lt;/code&gt;. Expect roughly 15 to 25 jars, and the exact list changes between versions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Option B, use Maven only as a downloader:&lt;/strong&gt; create a small file called &lt;code&gt;fetch-pom.xml&lt;/code&gt; in the project folder:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;tmp&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;fetch-jars&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.hibernate.orm&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;hibernate-core&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;7.4.13.Final&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.postgresql&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;postgresql&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;42.7.13&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run this once. It copies every needed jar, including the transitive ones, into &lt;code&gt;lib/&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn &lt;span class="nt"&gt;-f&lt;/span&gt; fetch-pom.xml dependency:copy-dependencies &lt;span class="nt"&gt;-DoutputDirectory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, you can forget Maven and build with plain Java tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Add the code.&lt;/strong&gt; Put the &lt;code&gt;Student&lt;/code&gt; and &lt;code&gt;Main&lt;/code&gt; classes from the previous section into &lt;code&gt;src/com/example/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Compile.&lt;/strong&gt; The &lt;code&gt;"lib/*"&lt;/code&gt; part adds every jar in the folder to the classpath:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; out
javac &lt;span class="nt"&gt;-cp&lt;/span&gt; &lt;span class="s2"&gt;"lib/*"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; out src/com/example/&lt;span class="k"&gt;*&lt;/span&gt;.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6. Run.&lt;/strong&gt; Linux and macOS use &lt;code&gt;:&lt;/code&gt; to separate classpath entries, and Windows uses &lt;code&gt;;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-cp&lt;/span&gt; &lt;span class="s2"&gt;"out:lib/*"&lt;/span&gt; com.example.Main      &lt;span class="c"&gt;# Linux and macOS&lt;/span&gt;
java &lt;span class="nt"&gt;-cp&lt;/span&gt; &lt;span class="s2"&gt;"out;lib/*"&lt;/span&gt; com.example.Main      &lt;span class="c"&gt;# Windows&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;7. Check the result.&lt;/strong&gt; You'll see the output from the main class section. You can also look in the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; school-db psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-d&lt;/span&gt; school &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="s2"&gt;t"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Schema |  Name   | Type  |  Owner
--------+---------+-------+----------
 public | student | table | postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this approach costs you:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You track every jar and version by hand. Upgrading Hibernate means repeating step 3.&lt;/li&gt;
&lt;li&gt;Two libraries needing different versions of a third is your problem to solve.&lt;/li&gt;
&lt;li&gt;Every teammate must set up the same &lt;code&gt;lib/&lt;/code&gt; folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you prefer an XML or properties file for configuration, Hibernate still supports &lt;code&gt;hibernate.properties&lt;/code&gt; and &lt;code&gt;hibernate.cfg.xml&lt;/code&gt; (read by calling &lt;code&gt;new Configuration().configure()&lt;/code&gt;). The code-based approach above just avoids an extra file.&lt;/p&gt;

&lt;p&gt;This is exactly why build tools exist, as we saw in the Maven post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Hibernate with Maven
&lt;/h2&gt;

&lt;p&gt;With Maven, you list the two libraries you need, and Maven fetches everything else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step by step with Maven
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Create the project.&lt;/strong&gt; (If you read my Maven post, this is the same command.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn archetype:generate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-DgroupId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;com.example &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-DartifactId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;hibernate-demo &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-DarchetypeArtifactId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;maven-archetype-quickstart &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-DarchetypeVersion&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.5 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-DinteractiveMode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can delete the generated &lt;code&gt;App.java&lt;/code&gt; and the sample test, since we won't use them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Edit &lt;code&gt;pom.xml&lt;/code&gt;.&lt;/strong&gt; Set the Java version and add the two dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;maven.compiler.release&amp;gt;&lt;/span&gt;17&lt;span class="nt"&gt;&amp;lt;/maven.compiler.release&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.hibernate.orm&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;hibernate-core&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;7.4.13.Final&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.postgresql&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;postgresql&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;42.7.13&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;hibernate-core&lt;/code&gt; also brings the Jakarta Persistence API with it, so the &lt;code&gt;jakarta.persistence.*&lt;/code&gt; imports compile.&lt;/li&gt;
&lt;li&gt;The PostgreSQL driver uses &lt;strong&gt;&lt;code&gt;runtime&lt;/code&gt; scope&lt;/strong&gt;, because your code never uses the driver's classes directly, only the standard JDBC and Hibernate APIs.&lt;/li&gt;
&lt;li&gt;Use the newest versions you can find on Maven Central. These are the ones I used.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Add the code.&lt;/strong&gt; Put &lt;code&gt;Student.java&lt;/code&gt; and &lt;code&gt;Main.java&lt;/code&gt; in &lt;code&gt;src/main/java/com/example/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Run it.&lt;/strong&gt; The &lt;code&gt;exec&lt;/code&gt; plugin runs your main class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn compile &lt;span class="nb"&gt;exec&lt;/span&gt;:java &lt;span class="nt"&gt;-Dexec&lt;/span&gt;.mainClass&lt;span class="o"&gt;=&lt;/span&gt;com.example.Main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Check the output.&lt;/strong&gt; You'll see the same five lines as before, mixed in with Maven's own messages.&lt;/p&gt;

&lt;p&gt;To see everything Maven brought in for you, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn dependency:tree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see &lt;code&gt;hibernate-core&lt;/code&gt; with its whole list of transitive libraries underneath. That's the list you had to download by hand in the other approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Hibernate methods
&lt;/h2&gt;

&lt;p&gt;In Hibernate 7, &lt;code&gt;Session&lt;/code&gt; extends the standard JPA &lt;code&gt;EntityManager&lt;/code&gt;, so most of the methods have JPA names. Here are the ones you'll use most:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   METHOD                          WHAT IT DOES
   persist(entity)                 insert a NEW entity (it becomes managed)
   find(Class, id)                 load by primary key (null if it doesn't exist)
   getReference(Class, id)         a lazy proxy, no SQL until you use it
   merge(entity)                   copy a DETACHED entity's state into a managed one, returns it
   remove(entity)                  delete an entity
   refresh(entity)                 reload its state from the database
   detach(entity)                  stop tracking this entity
   contains(entity)                is this entity managed by the session?
   flush()                         send pending SQL to the database now
   clear()                         detach everything the session tracks
   createQuery(hql, Class)         run an HQL / JPQL query
   createNativeQuery(sql, Class)   run plain SQL
   beginTransaction()              start a transaction
   close()                         close the session
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Saving, reading, updating and deleting
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// inside an open session, within a transaction&lt;/span&gt;
&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;            &lt;span class="c1"&gt;// INSERT&lt;/span&gt;

&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;         &lt;span class="c1"&gt;// SELECT ... WHERE id = ?&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMarks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;                                      &lt;span class="c1"&gt;// UPDATE happens at commit (dirty checking)&lt;/span&gt;

&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;                                   &lt;span class="c1"&gt;// DELETE happens at commit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;find&lt;/code&gt; vs &lt;code&gt;getReference&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;999L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;          &lt;span class="c1"&gt;// runs a SELECT, returns null if missing&lt;/span&gt;
&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getReference&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// returns a proxy, no SQL yet&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;getReference&lt;/code&gt; only runs SQL when you actually use the object (for example &lt;code&gt;b.getName()&lt;/code&gt;), and if the row doesn't exist, you get an exception at that point. It's useful when you only need a reference, such as setting a foreign key.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;persist&lt;/code&gt; vs &lt;code&gt;merge&lt;/code&gt; is a common source of confusion:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;persist&lt;/code&gt;&lt;/strong&gt; is for &lt;strong&gt;new&lt;/strong&gt; (transient) entities. After the call, the same object you passed is managed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;merge&lt;/code&gt;&lt;/strong&gt; is for &lt;strong&gt;detached&lt;/strong&gt; entities (ones that came from an earlier, closed session). It copies the state into a managed instance and &lt;strong&gt;returns that instance&lt;/strong&gt;. The object you passed in stays detached, so always use the returned one.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;detached&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;findStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// its session is closed: detached&lt;/span&gt;
&lt;span class="n"&gt;detached&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMarks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;                                &lt;span class="c1"&gt;// changed outside any session&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openSession&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Transaction&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;beginTransaction&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;managed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;merge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detached&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// use "managed" from here on&lt;/span&gt;
    &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;                                      &lt;span class="c1"&gt;// the UPDATE is sent&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Queries with HQL
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;HQL&lt;/strong&gt; (Hibernate Query Language) looks like SQL, but works on &lt;strong&gt;entities and their fields&lt;/strong&gt;, not tables and columns. It's a superset of JPQL, the standard JPA query language.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// filter and sort&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"from Student s where s.marks &amp;gt;= :min order by s.marks desc"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"min"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResultList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// a single value&lt;/span&gt;
&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"select count(s) from Student s"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSingleResult&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// pagination: rows 0 to 9&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;firstPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"from Student order by id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setFirstResult&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMaxResults&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResultList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// bulk update (runs directly in the database)&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;changed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createMutationQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"update Student set marks = marks + 5 where marks &amp;lt; 40"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always use &lt;strong&gt;named parameters&lt;/strong&gt; (&lt;code&gt;:min&lt;/code&gt;) and &lt;code&gt;setParameter&lt;/code&gt;. Never join user input into the query string.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;bulk update&lt;/strong&gt; goes straight to the database and skips the persistence context, so objects already loaded in the session don't see the change.&lt;/li&gt;
&lt;li&gt;For plain SQL, use &lt;code&gt;createNativeQuery&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createNativeQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"select * from student where marks &amp;gt; ?1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResultList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;There's also the &lt;strong&gt;Criteria API&lt;/strong&gt;, which builds queries with Java objects instead of strings. It's more verbose, but checked by the compiler.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Managing the persistence context
&lt;/h3&gt;

&lt;p&gt;Remember that each session keeps a cache of the objects it loaded. This means asking for the same row twice gives you the same object, with only one SQL query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tools to control this cache:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;flush()&lt;/code&gt;&lt;/strong&gt; sends pending changes to the database immediately (they're still inside the transaction and can be rolled back).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;clear()&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;detach(entity)&lt;/code&gt;&lt;/strong&gt; stop tracking objects. Useful in long loops, so the session doesn't grow too large.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;refresh(entity)&lt;/code&gt;&lt;/strong&gt; reloads the object from the database, discarding unflushed changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;contains(entity)&lt;/code&gt;&lt;/strong&gt; tells you whether an object is managed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Transactions and the safe pattern
&lt;/h3&gt;

&lt;p&gt;All changes to the database must happen inside a transaction. Use this pattern, so a failure rolls everything back and the session is always closed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openSession&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Transaction&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;beginTransaction&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Meera"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;95&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RuntimeException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rollback&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jakarta Persistence 3.2 also added shortcuts to the factory that do all of this for you (begin, commit, rollback on failure and close):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;runInTransaction&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;em&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;callInTransaction&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;em&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"select count(s) from Student s"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getSingleResult&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;runInTransaction&lt;/code&gt; runs code that returns nothing, and &lt;code&gt;callInTransaction&lt;/code&gt; returns a value. If you use Spring, &lt;code&gt;@Transactional&lt;/code&gt; does the same job (we'll see it soon).&lt;/p&gt;

&lt;h3&gt;
  
  
  Methods from older Hibernate versions
&lt;/h3&gt;

&lt;p&gt;Many tutorials online use older methods. Hibernate 7 &lt;strong&gt;removed&lt;/strong&gt; a number of them, so such code won't compile. Here's the mapping:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   OLD (Hibernate 5 and 6)             NEW (Hibernate 7)
   session.save(x)                     session.persist(x)
   session.update(x)                   x = session.merge(x)
   session.saveOrUpdate(x)             persist() for a new entity, merge() for a detached one
   session.delete(x)                   session.remove(x)
   session.load(Class, id)             session.getReference(Class, id)
   session.get(Class, id)              session.find(Class, id)       (get is deprecated)
   CascadeType.SAVE_UPDATE             CascadeType.PERSIST and CascadeType.MERGE
   javax.persistence.*                 jakarta.persistence.*          (since Hibernate 6)
   org.hibernate:hibernate-core        org.hibernate.orm:hibernate-core   (groupId changed in 6)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you maintain old code, Hibernate 6.x still has most of the old methods marked as deprecated, which gives you time to migrate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mapping relationships and loading data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  One-to-many and many-to-one
&lt;/h3&gt;

&lt;p&gt;Real data has relationships. Let's say many students belong to one course:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   course                     student
   +----+----------+         +----+-------+-------+-----------+
   | id | title    |         | id | name  | marks | course_id |  &amp;lt;- foreign key
   +----+----------+         +----+-------+-------+-----------+
   | 1  | Java 101 |&amp;lt;--------| 1  | Asha  | 88    | 1         |
   +----+----------+&amp;lt;--------| 2  | Ravi  | 72    | 1         |
                             +----+-------+-------+-----------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Java, you map both sides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Entity&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Course&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Id&lt;/span&gt;
    &lt;span class="nd"&gt;@GeneratedValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GenerationType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;IDENTITY&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@OneToMany&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mappedBy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"course"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cascade&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CascadeType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ALL&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orphanRemoval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setCourse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// keep both sides in sync&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in &lt;code&gt;Student&lt;/code&gt;, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ManyToOne&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FetchType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LAZY&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@JoinColumn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"course_id"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Course&lt;/span&gt; &lt;span class="n"&gt;course&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How to read this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@ManyToOne&lt;/code&gt;&lt;/strong&gt; (in &lt;code&gt;Student&lt;/code&gt;) is the &lt;strong&gt;owning side&lt;/strong&gt;: it has the foreign key column &lt;code&gt;course_id&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@OneToMany(mappedBy = "course")&lt;/code&gt;&lt;/strong&gt; (in &lt;code&gt;Course&lt;/code&gt;) is the &lt;strong&gt;inverse side&lt;/strong&gt;. &lt;code&gt;mappedBy&lt;/code&gt; says "the foreign key is managed by the &lt;code&gt;course&lt;/code&gt; field over there."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;cascade = ALL&lt;/code&gt;&lt;/strong&gt; passes operations like &lt;code&gt;persist&lt;/code&gt; and &lt;code&gt;remove&lt;/code&gt; from a course to its students.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;orphanRemoval = true&lt;/code&gt;&lt;/strong&gt; deletes a student that you remove from the list.&lt;/li&gt;
&lt;li&gt;Always update &lt;strong&gt;both sides&lt;/strong&gt; of the relationship, as &lt;code&gt;addStudent&lt;/code&gt; does.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are also &lt;code&gt;@OneToOne&lt;/code&gt; and &lt;code&gt;@ManyToMany&lt;/code&gt; (which uses a join table).&lt;/p&gt;

&lt;h3&gt;
  
  
  Lazy loading and the N+1 problem
&lt;/h3&gt;

&lt;p&gt;When you load a &lt;code&gt;Course&lt;/code&gt;, should Hibernate also load all its students right away? That choice is the &lt;strong&gt;fetch type&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;LAZY&lt;/code&gt;:&lt;/strong&gt; load the related data only when you first use it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;EAGER&lt;/code&gt;:&lt;/strong&gt; load it immediately with the main object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The defaults are: &lt;code&gt;@OneToMany&lt;/code&gt; and &lt;code&gt;@ManyToMany&lt;/code&gt; are &lt;strong&gt;lazy&lt;/strong&gt;, while &lt;code&gt;@ManyToOne&lt;/code&gt; and &lt;code&gt;@OneToOne&lt;/code&gt; are &lt;strong&gt;eager&lt;/strong&gt;. A good habit is to make everything &lt;code&gt;LAZY&lt;/code&gt; explicitly and fetch what you need on purpose.&lt;/p&gt;

&lt;p&gt;Laziness is powerful, but it has two classic traps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trap 1: &lt;code&gt;LazyInitializationException&lt;/code&gt;.&lt;/strong&gt; A lazy collection can only be loaded while its session is open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Course&lt;/span&gt; &lt;span class="n"&gt;course&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openSession&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;course&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Course&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;                                                  &lt;span class="c1"&gt;// session closed&lt;/span&gt;

&lt;span class="n"&gt;course&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStudents&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;                       &lt;span class="c1"&gt;// LazyInitializationException&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Trap 2: the N+1 problem.&lt;/strong&gt; Suppose you list every course with its number of students:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Course&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"from Course"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Course&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getResultList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// 1 query&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Course&lt;/span&gt; &lt;span class="n"&gt;course&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;course&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTitle&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;": "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;course&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStudents&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;          &lt;span class="c1"&gt;// +1 query EACH&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   1 query to load the courses
   + 1 query for the students of course 1
   + 1 query for the students of course 2
   + ...
   = N + 1 queries      (100 courses means 101 queries!)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code looks innocent, but it hits the database a hundred times. The most common fix is to tell Hibernate to load them together with a &lt;strong&gt;join fetch&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Course&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"from Course c left join fetch c.students"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Course&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getResultList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// 1 query&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other fixes include &lt;code&gt;@BatchSize&lt;/code&gt; (load collections in groups) and entity graphs. Since Hibernate 6, duplicate root entities caused by the join are removed for you. Watching the SQL log (covered later) is the best way to catch N+1 early.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hibernate vs Jakarta Persistence
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What each one is
&lt;/h3&gt;

&lt;p&gt;This confuses almost everyone at first, so here's the key: &lt;strong&gt;Jakarta Persistence is a specification (a standard). Hibernate is an implementation of it.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JPA&lt;/strong&gt; (Java Persistence API, now called &lt;strong&gt;Jakarta Persistence&lt;/strong&gt;) defines the interfaces and annotations: &lt;code&gt;EntityManager&lt;/code&gt;, &lt;code&gt;EntityManagerFactory&lt;/code&gt;, &lt;code&gt;@Entity&lt;/code&gt;, &lt;code&gt;@Id&lt;/code&gt;, JPQL and the rules for how they behave. It contains no real working code for talking to a database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hibernate&lt;/strong&gt; provides the working code behind those interfaces, plus many extra features of its own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's like the relationship between JDBC and a driver: the standard is the contract, and the library does the work. The names changed over time: JPA started in 2006 as part of Java EE, and when Java EE moved to the Eclipse Foundation it became Jakarta EE. That's why the packages changed from &lt;code&gt;javax.persistence&lt;/code&gt; to &lt;code&gt;jakarta.persistence&lt;/code&gt;. Hibernate 7 implements version 3.2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   YOUR CODE  (uses the standard JPA API: EntityManager, @Entity ...)
        |
        v
   JAKARTA PERSISTENCE   (the specification: interfaces and annotations)
        |   implemented by a "persistence provider":
        |
        +-- Hibernate ORM      (the most popular)
        +-- EclipseLink        (the reference implementation)
        +-- others (OpenJPA, DataNucleus ...)
        |
        v
      JDBC  --&amp;gt;  database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hibernate's classes &lt;strong&gt;extend&lt;/strong&gt; the standard ones, so you can use both in the same program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   JAKARTA PERSISTENCE (standard)        HIBERNATE (adds more)
   EntityManagerFactory                  SessionFactory      (extends it)
   EntityManager                         Session             (extends it)
   EntityTransaction                     Transaction         (extends it)
   JPQL                                  HQL                 (a superset of JPQL)
   persistence.xml                       hibernate.properties / hibernate.cfg.xml / code
   @Entity, @Id, @Column ...             plus @NaturalId, @BatchSize, @Formula, @SoftDelete ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some things you get only with Hibernate: &lt;code&gt;StatelessSession&lt;/code&gt; (no persistence context, great for bulk work), &lt;code&gt;@NaturalId&lt;/code&gt;, &lt;code&gt;@BatchSize&lt;/code&gt;, filters, soft-delete support and many performance and mapping options.&lt;/p&gt;

&lt;h3&gt;
  
  
  The same code in both styles
&lt;/h3&gt;

&lt;p&gt;Saving a student with the standard JPA API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;EntityManager&lt;/span&gt; &lt;span class="n"&gt;em&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entityManagerFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createEntityManager&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTransaction&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;begin&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTransaction&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;em&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And with Hibernate's own API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sessionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openSession&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Transaction&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;beginTransaction&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They're nearly identical, because &lt;code&gt;Session&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; an &lt;code&gt;EntityManager&lt;/code&gt;. With the standard setup, you create the factory with &lt;code&gt;Persistence.createEntityManagerFactory("school")&lt;/code&gt;, which reads a &lt;code&gt;META-INF/persistence.xml&lt;/code&gt; file. You can switch from the standard API to Hibernate's features at any time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entityManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unwrap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;SessionFactory&lt;/span&gt; &lt;span class="n"&gt;sessionFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entityManagerFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unwrap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SessionFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Which one to code against
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Default to the standard JPA API&lt;/strong&gt; (&lt;code&gt;EntityManager&lt;/code&gt;, JPQL, &lt;code&gt;jakarta.persistence&lt;/code&gt; annotations). Your code stays portable, and tools like Spring work with it directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reach for Hibernate-specific features&lt;/strong&gt; (&lt;code&gt;Session&lt;/code&gt;, HQL features, &lt;code&gt;StatelessSession&lt;/code&gt;, Hibernate annotations) only when you need what the standard doesn't offer.&lt;/li&gt;
&lt;li&gt;In practice, almost everyone runs JPA &lt;strong&gt;on Hibernate&lt;/strong&gt;, so "Hibernate vs JPA" is really "standard API vs extra features."&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hibernate in the Spring Framework
&lt;/h2&gt;

&lt;p&gt;Using Hibernate on its own, &lt;strong&gt;you&lt;/strong&gt; build the &lt;code&gt;SessionFactory&lt;/code&gt;, open sessions, begin and commit transactions and close everything. The &lt;strong&gt;Spring Framework&lt;/strong&gt; takes over all of that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It &lt;strong&gt;creates and manages&lt;/strong&gt; the connection pool and the &lt;code&gt;EntityManagerFactory&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It provides &lt;strong&gt;declarative transactions&lt;/strong&gt; with &lt;code&gt;@Transactional&lt;/code&gt;: you don't write &lt;code&gt;begin&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt; or &lt;code&gt;rollback&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;injects&lt;/strong&gt; the &lt;code&gt;EntityManager&lt;/code&gt; where you need it.&lt;/li&gt;
&lt;li&gt;It can translate JPA and database exceptions into its own consistent exception types.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll build a small application with &lt;strong&gt;Spring Framework 7&lt;/strong&gt; (plain Spring, not Spring Boot), using the standard JPA &lt;code&gt;EntityManager&lt;/code&gt; with Hibernate underneath. Spring 7 needs Java 17+, and its &lt;code&gt;HibernateJpaVendorAdapter&lt;/code&gt; needs Hibernate ORM 7. (For Spring Framework 6.2, use a Hibernate 6.x version instead.)&lt;/p&gt;

&lt;p&gt;Here's the project layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   spring-hibernate-demo/
   |-- pom.xml
   +-- src/main/java/com/example/
        |-- Student.java              &amp;lt;- the entity (same as before)
        |-- StudentRepository.java    &amp;lt;- talks to the database through the EntityManager
        |-- StudentService.java       &amp;lt;- business logic; owns the transactions
        |-- AppConfig.java            &amp;lt;- Spring configuration
        +-- App.java                  &amp;lt;- main method
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1: Add the dependencies
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;pom.xml&lt;/code&gt;, import the Spring BOM (so all Spring modules share one version) and add the libraries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;maven.compiler.release&amp;gt;&lt;/span&gt;17&lt;span class="nt"&gt;&amp;lt;/maven.compiler.release&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependencyManagement&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-framework-bom&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;7.0.10&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;type&amp;gt;&lt;/span&gt;pom&lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;import&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencyManagement&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-context&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-orm&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.hibernate.orm&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;hibernate-core&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;7.4.13.Final&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.zaxxer&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;HikariCP&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;7.1.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.postgresql&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;postgresql&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;42.7.13&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What each one is for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;spring-context&lt;/code&gt;&lt;/strong&gt;: the core container and annotations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;spring-orm&lt;/code&gt;&lt;/strong&gt;: Spring's JPA and Hibernate integration (it also brings &lt;code&gt;spring-jdbc&lt;/code&gt; and &lt;code&gt;spring-tx&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;hibernate-core&lt;/code&gt;&lt;/strong&gt;: Hibernate itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;HikariCP&lt;/code&gt;&lt;/strong&gt;: the connection pool, as we discussed in the JDBC post.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;postgresql&lt;/code&gt;&lt;/strong&gt;: the driver.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use the newest versions available when you read this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create the entity
&lt;/h3&gt;

&lt;p&gt;Use the &lt;strong&gt;same &lt;code&gt;Student&lt;/code&gt; class&lt;/strong&gt; from earlier, in the package &lt;code&gt;com.example&lt;/code&gt;. Nothing changes. It's plain JPA, so Spring and Hibernate both understand it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Create the repository
&lt;/h3&gt;

&lt;p&gt;The repository is the class that talks to the database. It uses the standard &lt;code&gt;EntityManager&lt;/code&gt;, which Spring injects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.EntityManager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.PersistenceContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Repository&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StudentRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@PersistenceContext&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;EntityManager&lt;/span&gt; &lt;span class="n"&gt;entityManager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;entityManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;entityManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByMinMarks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;minMarks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;entityManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                        &lt;span class="s"&gt;"from Student s where s.marks &amp;gt;= :min order by s.marks desc"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                        &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"min"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minMarks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResultList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;entityManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Repository&lt;/code&gt;&lt;/strong&gt; marks this class as the data-access layer. Spring registers it as a bean (and, if you add the right post-processor, translates persistence exceptions into Spring's &lt;code&gt;DataAccessException&lt;/code&gt; types).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@PersistenceContext&lt;/code&gt;&lt;/strong&gt; asks Spring to inject an &lt;code&gt;EntityManager&lt;/code&gt;. Notice there's no code that opens or closes it, and no transaction code. Spring handles those.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Create the service
&lt;/h3&gt;

&lt;p&gt;The service holds the business logic, and &lt;strong&gt;this is where transactions belong&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Service&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.transaction.annotation.Transactional&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Service&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StudentService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;StudentRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;StudentService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StudentRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;repository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Transactional&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="nf"&gt;addStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Transactional&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;readOnly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="nf"&gt;getStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Transactional&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;changeMarks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="n"&gt;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMarks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;                 &lt;span class="c1"&gt;// dirty checking: UPDATE at commit&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Transactional&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;readOnly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;topStudents&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;minMarks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByMinMarks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minMarks&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Transactional&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;removeStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Transactional&lt;/code&gt;&lt;/strong&gt; on a method means: "start a transaction before this method, commit when it ends normally, roll back if a runtime exception escapes."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;readOnly = true&lt;/code&gt;&lt;/strong&gt; is a hint that this method only reads, which allows some optimizations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constructor injection&lt;/strong&gt; gives us the repository.&lt;/li&gt;
&lt;li&gt;Look at &lt;code&gt;changeMarks&lt;/code&gt;: it changes a field and never calls "save". Because the student is managed inside the transaction, Hibernate notices the change and writes the &lt;code&gt;UPDATE&lt;/code&gt; at commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5: Configure Spring
&lt;/h3&gt;

&lt;p&gt;Now we tell Spring how to build the database pieces. We use &lt;strong&gt;Java configuration&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Properties&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.sql.DataSource&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.zaxxer.hikari.HikariConfig&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.zaxxer.hikari.HikariDataSource&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.EntityManagerFactory&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Bean&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.ComponentScan&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.Configuration&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.orm.jpa.JpaTransactionManager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.transaction.PlatformTransactionManager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.transaction.annotation.EnableTransactionManagement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="nd"&gt;@ComponentScan&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.example"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@EnableTransactionManagement&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;DataSource&lt;/span&gt; &lt;span class="nf"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;HikariConfig&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HikariConfig&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setJdbcUrl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"jdbc:postgresql://localhost:5432/school"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUsername&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"postgres"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPassword&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getOrDefault&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DB_PASSWORD"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"secret"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMaximumPoolSize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HikariDataSource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;LocalContainerEntityManagerFactoryBean&lt;/span&gt; &lt;span class="nf"&gt;entityManagerFactory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DataSource&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;LocalContainerEntityManagerFactoryBean&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LocalContainerEntityManagerFactoryBean&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDataSource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPackagesToScan&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.example"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;              &lt;span class="c1"&gt;// find the @Entity classes&lt;/span&gt;
        &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setJpaVendorAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HibernateJpaVendorAdapter&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="nc"&gt;Properties&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Properties&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hibernate.hbm2ddl.auto"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"update"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hibernate.show_sql"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setJpaProperties&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;PlatformTransactionManager&lt;/span&gt; &lt;span class="nf"&gt;transactionManager&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EntityManagerFactory&lt;/span&gt; &lt;span class="n"&gt;entityManagerFactory&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;JpaTransactionManager&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entityManagerFactory&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Piece by piece:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Configuration&lt;/code&gt;&lt;/strong&gt; marks a class that defines beans. &lt;strong&gt;&lt;code&gt;@ComponentScan&lt;/code&gt;&lt;/strong&gt; finds our &lt;code&gt;@Repository&lt;/code&gt; and &lt;code&gt;@Service&lt;/code&gt; classes. &lt;strong&gt;&lt;code&gt;@EnableTransactionManagement&lt;/code&gt;&lt;/strong&gt; turns on &lt;code&gt;@Transactional&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;dataSource()&lt;/code&gt;&lt;/strong&gt; builds the HikariCP connection pool. The password comes from an environment variable, with &lt;code&gt;secret&lt;/code&gt; as a local fallback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;LocalContainerEntityManagerFactoryBean&lt;/code&gt;&lt;/strong&gt; is Spring's way of building the JPA &lt;code&gt;EntityManagerFactory&lt;/code&gt;. &lt;code&gt;setPackagesToScan&lt;/code&gt; finds the &lt;code&gt;@Entity&lt;/code&gt; classes, so there's no &lt;code&gt;persistence.xml&lt;/code&gt;. &lt;strong&gt;&lt;code&gt;HibernateJpaVendorAdapter&lt;/code&gt;&lt;/strong&gt; tells Spring that Hibernate is our JPA provider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;jpaProperties&lt;/code&gt;&lt;/strong&gt; passes normal Hibernate settings. Here, &lt;code&gt;update&lt;/code&gt; creates the table and &lt;code&gt;show_sql&lt;/code&gt; prints the SQL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;JpaTransactionManager&lt;/code&gt;&lt;/strong&gt; is the object that actually starts and commits transactions for &lt;code&gt;@Transactional&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 6: Run the application
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.annotation.AnnotationConfigApplicationContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AnnotationConfigApplicationContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
                     &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;AnnotationConfigApplicationContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;AppConfig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

            &lt;span class="nc"&gt;StudentService&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StudentService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saved with id "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Found: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

            &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;changeMarks&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;95&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"After update: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Top students: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;topStudents&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

            &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;removeStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Deleted. Remaining: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;topStudents&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn compile &lt;span class="nb"&gt;exec&lt;/span&gt;:java &lt;span class="nt"&gt;-Dexec&lt;/span&gt;.mainClass&lt;span class="o"&gt;=&lt;/span&gt;com.example.App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output (mixed with the SQL lines that &lt;code&gt;show_sql&lt;/code&gt; prints, and some start-up logging):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Saved with id 1
Found: Student{id=1, name='Asha', marks=88}
After update: Student{id=1, name='Asha', marks=95}
Top students: [Student{id=1, name='Asha', marks=95}]
Deleted. Remaining: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see a message about SLF4J finding no logging provider, that's harmless. Add an SLF4J binding (such as &lt;code&gt;slf4j-simple&lt;/code&gt;) if you want to see the pool's logs.&lt;/p&gt;

&lt;p&gt;Notice what's missing compared to the plain Hibernate program: no &lt;code&gt;SessionFactory&lt;/code&gt; code, no &lt;code&gt;openSession&lt;/code&gt;, no &lt;code&gt;beginTransaction&lt;/code&gt;, no &lt;code&gt;commit&lt;/code&gt;, no &lt;code&gt;try/finally&lt;/code&gt;. Spring did all of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Spring and Hibernate work together
&lt;/h3&gt;

&lt;p&gt;The magic is a &lt;strong&gt;proxy&lt;/strong&gt;. When you call a &lt;code&gt;@Transactional&lt;/code&gt; method, you don't call the real object directly. You call a proxy that Spring wraps around it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   App code calls:  service.changeMarks(1, 95)
        |
        v
   SPRING PROXY around StudentService
     1. JpaTransactionManager starts a transaction
        (opens an EntityManager and ties it to the current thread)
        |
        v
   StudentService.changeMarks(...)  --&amp;gt;  StudentRepository  --&amp;gt;  the injected EntityManager
        |                                    (it's a shared proxy that forwards to
        |                                     the EntityManager of the current transaction)
        v
   SPRING PROXY again
     2. method finished normally?   YES: commit  (Hibernate flushes: UPDATE student ...)
                                    NO, a RuntimeException:  rollback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few rules worth remembering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;By default, Spring rolls back only for &lt;strong&gt;unchecked exceptions&lt;/strong&gt; (&lt;code&gt;RuntimeException&lt;/code&gt; and errors). A checked exception does &lt;em&gt;not&lt;/em&gt; roll back, unless you add &lt;code&gt;@Transactional(rollbackFor = Exception.class)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Calling a &lt;code&gt;@Transactional&lt;/code&gt; method &lt;strong&gt;from another method in the same class&lt;/strong&gt; skips the proxy, so no transaction starts. Call it from another bean instead.&lt;/li&gt;
&lt;li&gt;Put &lt;code&gt;@Transactional&lt;/code&gt; on &lt;strong&gt;public&lt;/strong&gt; methods of your service layer, not on private methods or in the repository.&lt;/li&gt;
&lt;li&gt;Entities you return from a service are &lt;strong&gt;detached&lt;/strong&gt; after the method ends, so lazy relationships you didn't load can't be read later.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The shortcut: Spring Boot and Spring Data JPA
&lt;/h3&gt;

&lt;p&gt;Writing &lt;code&gt;AppConfig&lt;/code&gt; by hand teaches you what's going on. In everyday projects, &lt;strong&gt;Spring Boot&lt;/strong&gt; does all of it automatically, and &lt;strong&gt;Spring Data JPA&lt;/strong&gt; writes the repository for you. Generate a project at &lt;code&gt;start.spring.io&lt;/code&gt; with the &lt;strong&gt;Spring Data JPA&lt;/strong&gt; and &lt;strong&gt;PostgreSQL Driver&lt;/strong&gt; dependencies (it picks matching versions). Then your configuration is a few lines in &lt;code&gt;application.properties&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;spring.datasource.url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;jdbc:postgresql://localhost:5432/school&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.username&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;span class="py"&gt;spring.datasource.password&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;secret&lt;/span&gt;
&lt;span class="py"&gt;spring.jpa.hibernate.ddl-auto&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;update&lt;/span&gt;
&lt;span class="py"&gt;spring.jpa.show-sql&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the repository becomes an interface, with no implementation at all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;StudentRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByMarksGreaterThanEqual&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spring Data creates the implementation, including the query from the method name. Using it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@SpringBootApplication&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DemoApplication&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;SpringApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DemoApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="nc"&gt;CommandLineRunner&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StudentRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
            &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByMarksGreaterThanEqual&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;};&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Student{id=1, name='Asha', marks=88}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boot auto-configures the connection pool, Hibernate, the transaction manager and the entity scanning. Underneath, it's the same pieces you just built by hand, which is why learning the manual version first makes Boot much easier to understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other things worth knowing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Configuration settings
&lt;/h3&gt;

&lt;p&gt;Hibernate is configured with properties. The ones you'll meet first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;jakarta.persistence.jdbc.url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;jdbc:postgresql://localhost:5432/school&lt;/span&gt;
&lt;span class="py"&gt;jakarta.persistence.jdbc.user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;span class="py"&gt;jakarta.persistence.jdbc.password&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;secret&lt;/span&gt;
&lt;span class="py"&gt;hibernate.hbm2ddl.auto&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;update&lt;/span&gt;
&lt;span class="py"&gt;hibernate.show_sql&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;hibernate.format_sql&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can provide them in several ways, and the more specific one wins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In code&lt;/strong&gt;, as we did with &lt;code&gt;HibernatePersistenceConfiguration&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In a &lt;strong&gt;&lt;code&gt;hibernate.properties&lt;/code&gt;&lt;/strong&gt; file on the classpath.&lt;/li&gt;
&lt;li&gt;In a &lt;strong&gt;&lt;code&gt;hibernate.cfg.xml&lt;/code&gt;&lt;/strong&gt; file (read when you call &lt;code&gt;new Configuration().configure()&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;In a standard JPA &lt;strong&gt;&lt;code&gt;persistence.xml&lt;/code&gt;&lt;/strong&gt; file (used with &lt;code&gt;Persistence.createEntityManagerFactory(...)&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;In &lt;strong&gt;Spring&lt;/strong&gt;, through &lt;code&gt;jpaProperties&lt;/code&gt; or Spring Boot's &lt;code&gt;application.properties&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;hibernate.hbm2ddl.auto&lt;/code&gt; values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;none&lt;/code&gt;: do nothing with the schema.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;validate&lt;/code&gt;: check that the tables match the entities, and fail if they don't.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;update&lt;/code&gt;: add missing tables and columns.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create&lt;/code&gt;: drop and recreate the tables at start-up.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create-drop&lt;/code&gt;: like &lt;code&gt;create&lt;/code&gt;, and drop them again when the factory closes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Caching
&lt;/h3&gt;

&lt;p&gt;Hibernate has two levels of cache:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First-level cache:&lt;/strong&gt; always on. It lives in each session (the persistence context). That's why asking for the same row twice gave us the same object.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Second-level cache:&lt;/strong&gt; optional. It's shared by all sessions, and needs a cache provider (for example JCache). You turn it on with &lt;code&gt;hibernate.cache.use_second_level_cache=true&lt;/code&gt; and mark entities as cacheable. It can reduce database load for data that's read often and changes rarely, but cached data can become stale, so use it carefully.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Optimistic locking with &lt;a class="mentioned-user" href="https://dev.to/version"&gt;@version&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;What if two users edit the same row at the same time? Hibernate can detect it with a &lt;strong&gt;version column&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Version&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hibernate adds the version to every update:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   update student set marks = ?, version = 2 where id = ? and version = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If someone else already changed the row (so its version is no longer 1), no row matches, and Hibernate throws an &lt;code&gt;OptimisticLockException&lt;/code&gt; instead of silently overwriting their work. You catch it and ask the user to reload and try again. It's called &lt;em&gt;optimistic&lt;/em&gt; because it assumes conflicts are rare and doesn't lock rows in the database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Managing the schema in real projects
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;hbm2ddl.auto=update&lt;/code&gt; is convenient for learning and prototypes, but it's risky for real databases: it can't safely rename or remove columns, and &lt;code&gt;create&lt;/code&gt; and &lt;code&gt;create-drop&lt;/code&gt; &lt;strong&gt;delete your data&lt;/strong&gt;. In real projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manage the schema with a migration tool such as &lt;strong&gt;Flyway&lt;/strong&gt; or &lt;strong&gt;Liquibase&lt;/strong&gt;, which applies versioned SQL scripts.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;hibernate.hbm2ddl.auto&lt;/code&gt; to &lt;code&gt;validate&lt;/code&gt; (or &lt;code&gt;none&lt;/code&gt;), so Hibernate only checks that your entities match the schema.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Logging the SQL
&lt;/h3&gt;

&lt;p&gt;Seeing the SQL is the best way to learn what Hibernate does, and to catch problems like N+1. The simplest switches are &lt;code&gt;hibernate.show_sql&lt;/code&gt; and &lt;code&gt;hibernate.format_sql&lt;/code&gt;. In code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;showSql&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;// show SQL, format it, don't use color&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typical output (the exact text depends on your version and database):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;insert into student (marks,name) values (?,?)
select s1_0.id,s1_0.marks,s1_0.name from student s1_0 where s1_0.id=?
update student set marks=?,name=? where id=?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more control, use your logging framework: set the logger &lt;code&gt;org.hibernate.SQL&lt;/code&gt; to &lt;code&gt;DEBUG&lt;/code&gt; to log statements, and &lt;code&gt;org.hibernate.orm.jdbc.bind&lt;/code&gt; to &lt;code&gt;TRACE&lt;/code&gt; to also see the values bound to the &lt;code&gt;?&lt;/code&gt; parameters (in Hibernate 6 and newer).&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code against the standard JPA API&lt;/strong&gt; unless you need a Hibernate feature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make associations lazy&lt;/strong&gt; (&lt;code&gt;fetch = FetchType.LAZY&lt;/code&gt;), and load related data on purpose with &lt;code&gt;join fetch&lt;/code&gt;, &lt;code&gt;@BatchSize&lt;/code&gt; or entity graphs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch for N+1&lt;/strong&gt; by checking the SQL log during development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep transactions short&lt;/strong&gt; and put them in the service layer, not the controller or repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;readOnly = true&lt;/code&gt;&lt;/strong&gt; for methods that only read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a connection pool&lt;/strong&gt; such as HikariCP (Spring Boot does this by default).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never build queries by joining strings.&lt;/strong&gt; Use named parameters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't expose entities directly&lt;/strong&gt; in web APIs. Use separate data-transfer objects (DTOs), so lazy fields and internal details don't leak.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use projections or DTO queries&lt;/strong&gt; for read-heavy screens, so you don't load full entities you don't need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be careful with &lt;code&gt;equals&lt;/code&gt; and &lt;code&gt;hashCode&lt;/code&gt;&lt;/strong&gt; on entities. Base them on a business key, or handle the generated id carefully.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't use &lt;code&gt;CascadeType.ALL&lt;/code&gt; everywhere.&lt;/strong&gt; Cascade only where a child truly belongs to its parent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;@Version&lt;/code&gt;&lt;/strong&gt; for entities that several users can edit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manage the schema with Flyway or Liquibase&lt;/strong&gt; in real projects, and keep &lt;code&gt;hbm2ddl.auto&lt;/code&gt; at &lt;code&gt;validate&lt;/code&gt; or &lt;code&gt;none&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test against a real database&lt;/strong&gt; (for example with Testcontainers) as well as an in-memory one, since SQL dialects differ.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read the SQL&lt;/strong&gt;, and use plain SQL (native queries, JDBC or jOOQ) for heavy reports and bulk jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JDBC or an ORM?&lt;/strong&gt; Use an ORM for applications with many entities, relationships and CRUD screens. Use plain JDBC (or &lt;code&gt;JdbcTemplate&lt;/code&gt;, jOOQ or MyBatis) for simple scripts, heavy reporting and performance-critical SQL. Many projects mix both.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Hibernate &lt;code&gt;Session&lt;/code&gt; or the JPA &lt;code&gt;EntityManager&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;EntityManager&lt;/code&gt; by default. &lt;code&gt;Session&lt;/code&gt; when you need Hibernate-only features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plain Hibernate, Spring Framework or Spring Boot?&lt;/strong&gt; Plain Hibernate to learn the basics or for small tools. Spring Framework when you want to wire everything yourself. Spring Boot with Spring Data JPA for most new applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;persist&lt;/code&gt; or &lt;code&gt;merge&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;persist&lt;/code&gt; for new objects, &lt;code&gt;merge&lt;/code&gt; for detached ones (and use the returned object).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;find&lt;/code&gt; or &lt;code&gt;getReference&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;find&lt;/code&gt; when you need the data. &lt;code&gt;getReference&lt;/code&gt; when you only need a handle, such as to set a foreign key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;IDENTITY&lt;/code&gt; or &lt;code&gt;SEQUENCE&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;IDENTITY&lt;/code&gt; is simple. &lt;code&gt;SEQUENCE&lt;/code&gt; allows Hibernate to batch inserts better, and is usually the better choice for write-heavy tables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;LAZY&lt;/code&gt; or &lt;code&gt;EAGER&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;LAZY&lt;/code&gt; almost always. Fetch what you need explicitly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HQL, native SQL or Criteria?&lt;/strong&gt; HQL for most queries, native SQL for database-specific or very complex queries, and Criteria when you must build queries dynamically in a type-safe way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which &lt;code&gt;hbm2ddl.auto&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;update&lt;/code&gt; for learning, &lt;code&gt;validate&lt;/code&gt; or &lt;code&gt;none&lt;/code&gt; for real environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration in code, properties or XML?&lt;/strong&gt; Code or properties for simplicity. &lt;code&gt;persistence.xml&lt;/code&gt; if you need a standard JPA setup. In Spring, use Spring's configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The N+1 problem and lazy-loading errors.&lt;/strong&gt; Looping over a lazy collection fires one query per item, and reading one after the session closed gives a &lt;code&gt;LazyInitializationException&lt;/code&gt;. Fetch what you need up front, and read lazy data inside the transaction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using &lt;code&gt;create&lt;/code&gt; or &lt;code&gt;create-drop&lt;/code&gt; on real data.&lt;/strong&gt; These settings drop your tables at start-up. Use &lt;code&gt;validate&lt;/code&gt; or a migration tool outside of local experiments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forgetting the transaction.&lt;/strong&gt; Changes made without a transaction (or without &lt;code&gt;commit&lt;/code&gt;) are not saved. In Spring, a missing &lt;code&gt;@Transactional&lt;/code&gt; has the same effect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Following old tutorials.&lt;/strong&gt; &lt;code&gt;session.save&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, &lt;code&gt;saveOrUpdate&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt; and &lt;code&gt;load&lt;/code&gt;, and &lt;code&gt;javax.persistence&lt;/code&gt; imports, don't work in Hibernate 7. Use &lt;code&gt;persist&lt;/code&gt;, &lt;code&gt;merge&lt;/code&gt;, &lt;code&gt;remove&lt;/code&gt;, &lt;code&gt;getReference&lt;/code&gt; and &lt;code&gt;jakarta.persistence&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mixing up &lt;code&gt;persist&lt;/code&gt; and &lt;code&gt;merge&lt;/code&gt;.&lt;/strong&gt; Calling &lt;code&gt;persist&lt;/code&gt; on a detached entity fails with a "detached entity passed to persist" error. And after &lt;code&gt;merge&lt;/code&gt;, forgetting to use the &lt;strong&gt;returned&lt;/strong&gt; object means your later changes aren't tracked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entity rules and relationship bugs.&lt;/strong&gt; A missing no-arg constructor, a &lt;code&gt;final&lt;/code&gt; entity class or a missing &lt;code&gt;@Id&lt;/code&gt; stops Hibernate from starting. And forgetting to set both sides of a bidirectional relationship leaves the foreign key &lt;code&gt;null&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ORM&lt;/strong&gt; maps classes to tables, objects to rows and fields to columns. It solves the &lt;strong&gt;object-relational impedance mismatch&lt;/strong&gt; and removes JDBC boilerplate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pros:&lt;/strong&gt; less code, object-oriented thinking, relationships, portability, caching and change tracking. &lt;strong&gt;Cons:&lt;/strong&gt; a learning curve, hidden SQL, performance traps like N+1, and it's not ideal for bulk or complex reporting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hibernate&lt;/strong&gt; sits on top of JDBC. Its core pieces are the &lt;code&gt;SessionFactory&lt;/code&gt; (one per app), the &lt;code&gt;Session&lt;/code&gt; (one per unit of work, with a persistence context) and the &lt;code&gt;Transaction&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;An entity is &lt;strong&gt;transient, persistent, detached or removed&lt;/strong&gt;. Hibernate saves changes to persistent entities automatically (&lt;strong&gt;dirty checking&lt;/strong&gt;) at flush or commit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Without Maven&lt;/strong&gt;, you collect the jars yourself, compile with &lt;code&gt;javac -cp "lib/*"&lt;/code&gt; and run with &lt;code&gt;java -cp&lt;/code&gt;. &lt;strong&gt;With Maven&lt;/strong&gt;, you declare &lt;code&gt;hibernate-core&lt;/code&gt; and the PostgreSQL driver, and Maven does the rest.&lt;/li&gt;
&lt;li&gt;Key methods: &lt;code&gt;persist&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;getReference&lt;/code&gt;, &lt;code&gt;merge&lt;/code&gt;, &lt;code&gt;remove&lt;/code&gt;, &lt;code&gt;refresh&lt;/code&gt;, &lt;code&gt;flush&lt;/code&gt;, &lt;code&gt;clear&lt;/code&gt;, &lt;code&gt;createQuery&lt;/code&gt; and HQL. Hibernate 7 removed &lt;code&gt;save&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, &lt;code&gt;saveOrUpdate&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt; and &lt;code&gt;load&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jakarta Persistence is the specification, and Hibernate is the implementation.&lt;/strong&gt; &lt;code&gt;Session&lt;/code&gt; extends &lt;code&gt;EntityManager&lt;/code&gt;. Code against JPA by default.&lt;/li&gt;
&lt;li&gt;In &lt;strong&gt;Spring&lt;/strong&gt;, you configure a &lt;code&gt;DataSource&lt;/code&gt;, a &lt;code&gt;LocalContainerEntityManagerFactoryBean&lt;/code&gt; with &lt;code&gt;HibernateJpaVendorAdapter&lt;/code&gt;, and a &lt;code&gt;JpaTransactionManager&lt;/code&gt;. Then &lt;code&gt;@Transactional&lt;/code&gt; services and &lt;code&gt;@PersistenceContext&lt;/code&gt; repositories do the rest. Spring Boot with Spring Data JPA automates it all.&lt;/li&gt;
&lt;li&gt;Also remember: lazy loading and N+1, caching, &lt;code&gt;@Version&lt;/code&gt;, schema migrations and reading the SQL log.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: start PostgreSQL with Docker, then run the plain Hibernate program from this post, first with the jar folder approach and then with Maven. Add a &lt;code&gt;Course&lt;/code&gt; entity with a one-to-many relationship to &lt;code&gt;Student&lt;/code&gt;, save a course with three students and print them. Then turn on SQL logging, write a loop that reproduces the N+1 problem, count the queries, and fix it with &lt;code&gt;join fetch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, rebuild the same application in the Spring Framework, and watch each &lt;code&gt;@Transactional&lt;/code&gt; method produce its SQL. Then replace the repository with a Spring Data JPA interface, and see how much code disappears. Finally, add &lt;code&gt;@Version&lt;/code&gt; to &lt;code&gt;Student&lt;/code&gt;, open two sessions that edit the same row, and trigger an &lt;code&gt;OptimisticLockException&lt;/code&gt; on purpose.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

</description>
      <category>java</category>
      <category>hibernate</category>
      <category>orm</category>
      <category>beginners</category>
    </item>
    <item>
      <title>JDBC Explained: Drivers, Statements and Best Practices</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Sat, 24 Oct 2026 04:43:43 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/jdbc-explained-drivers-statements-and-best-practices-3hbh</link>
      <guid>https://dev.to/mayur_bodhare/jdbc-explained-drivers-statements-and-best-practices-3hbh</guid>
      <description>&lt;p&gt;The first time I had to save data from a Java program into a database, I was sure there would be a different library for every database. One for MySQL, one for Oracle, one for PostgreSQL, each with its own commands to learn.&lt;/p&gt;

&lt;p&gt;It turns out Java solved this problem a long time ago, with one standard called &lt;strong&gt;JDBC&lt;/strong&gt;. You learn it once, and the same code works with almost any relational database. You mostly just swap one small jar file and one line of text.&lt;/p&gt;

&lt;p&gt;In this post, we'll learn what JDBC is, what a JDBC driver does (and which one to use for each database), the steps of every JDBC program, a complete working example with an explanation of each line, the different &lt;code&gt;execute&lt;/code&gt; methods, the three kinds of statements and when to use each, and the best practices that keep your code safe and fast. The example uses an in-memory database called H2, so you don't need to install anything to try it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
What is JDBC?

&lt;ul&gt;
&lt;li&gt;The problem JDBC solves&lt;/li&gt;
&lt;li&gt;The main pieces of JDBC&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
JDBC drivers

&lt;ul&gt;
&lt;li&gt;The four driver types&lt;/li&gt;
&lt;li&gt;Drivers for popular databases&lt;/li&gt;
&lt;li&gt;Adding a driver with Maven&lt;/li&gt;
&lt;li&gt;Anatomy of a JDBC URL&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Steps for working with JDBC&lt;/li&gt;
&lt;li&gt;
Your first JDBC program

&lt;ul&gt;
&lt;li&gt;The complete code&lt;/li&gt;
&lt;li&gt;Explaining the code&lt;/li&gt;
&lt;li&gt;What happens behind the scenes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Types of execute methods

&lt;ul&gt;
&lt;li&gt;executeQuery&lt;/li&gt;
&lt;li&gt;executeUpdate&lt;/li&gt;
&lt;li&gt;execute&lt;/li&gt;
&lt;li&gt;executeBatch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Types of statements

&lt;ul&gt;
&lt;li&gt;Statement&lt;/li&gt;
&lt;li&gt;PreparedStatement&lt;/li&gt;
&lt;li&gt;CallableStatement&lt;/li&gt;
&lt;li&gt;SQL injection and why it matters&lt;/li&gt;
&lt;li&gt;Choosing the right statement&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Working with ResultSet&lt;/li&gt;
&lt;li&gt;Transactions&lt;/li&gt;
&lt;li&gt;
Best practices

&lt;ul&gt;
&lt;li&gt;Close resources with try-with-resources&lt;/li&gt;
&lt;li&gt;Use PreparedStatement for every query with input&lt;/li&gt;
&lt;li&gt;Use a connection pool&lt;/li&gt;
&lt;li&gt;Handle SQLException properly&lt;/li&gt;
&lt;li&gt;Keep credentials out of your code&lt;/li&gt;
&lt;li&gt;Other good habits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Which one should I use?&lt;/li&gt;
&lt;li&gt;Common mistakes&lt;/li&gt;
&lt;li&gt;Quick recap&lt;/li&gt;
&lt;li&gt;Try it yourself&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is JDBC?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;JDBC&lt;/strong&gt; stands for &lt;strong&gt;Java Database Connectivity&lt;/strong&gt;. It's a standard &lt;strong&gt;API&lt;/strong&gt; (a set of classes and interfaces) that lets a Java program connect to a relational database, send SQL commands and read the results. It's part of Java itself, in the packages &lt;code&gt;java.sql&lt;/code&gt; and &lt;code&gt;javax.sql&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The problem JDBC solves
&lt;/h3&gt;

&lt;p&gt;Every database has its own way of talking over the network. MySQL speaks one protocol, Oracle another, PostgreSQL a third. Without a standard, you'd have to learn each one and rewrite your code to switch databases.&lt;/p&gt;

&lt;p&gt;JDBC fixes this with a &lt;strong&gt;middle layer&lt;/strong&gt;. Your code talks only to JDBC's standard interfaces. A small library from the database vendor, called a &lt;strong&gt;driver&lt;/strong&gt;, translates those calls into the database's own language.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   YOUR JAVA CODE
        |   uses standard interfaces: Connection, Statement, ResultSet
        v
   JDBC API   (java.sql and javax.sql, part of Java SE)
        |
        v
   JDBC DRIVER   (a jar file from the database vendor)
        |   speaks the database's own protocol over the network
        v
   DATABASE   (MySQL, PostgreSQL, Oracle, SQL Server, H2 ...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because your code depends only on the standard interfaces, switching databases usually means changing the driver jar and the connection URL. (Your SQL itself may still need small changes, since each database has its own dialect for some features.)&lt;/p&gt;

&lt;h3&gt;
  
  
  The main pieces of JDBC
&lt;/h3&gt;

&lt;p&gt;You'll meet these names again and again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;DriverManager&lt;/code&gt;&lt;/strong&gt;: finds the right driver for a URL and opens a connection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;DataSource&lt;/code&gt;&lt;/strong&gt;: a more modern way to get connections. It's what connection pools implement, and it's preferred in real applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Connection&lt;/code&gt;&lt;/strong&gt;: your session with the database. You use it to create statements and to control transactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Statement&lt;/code&gt;, &lt;code&gt;PreparedStatement&lt;/code&gt;, &lt;code&gt;CallableStatement&lt;/code&gt;&lt;/strong&gt;: objects that send SQL to the database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ResultSet&lt;/code&gt;&lt;/strong&gt;: the rows that come back from a query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;SQLException&lt;/code&gt;&lt;/strong&gt;: the exception thrown when anything goes wrong with the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these (except the driver itself) are interfaces. The driver provides the real classes behind them.&lt;/p&gt;

&lt;h2&gt;
  
  
  JDBC drivers
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;JDBC driver&lt;/strong&gt; is a library that implements the JDBC interfaces for one specific database. It knows how to open a network connection to that database, log in, send SQL and read the results. You add it to your project like any other library.&lt;/p&gt;

&lt;h3&gt;
  
  
  The four driver types
&lt;/h3&gt;

&lt;p&gt;JDBC drivers are traditionally grouped into four types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type 1, JDBC-ODBC bridge:&lt;/strong&gt; used the old ODBC standard on your computer to reach a database. It was &lt;strong&gt;removed from Java in version 8&lt;/strong&gt;, so you won't use it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type 2, native-API driver:&lt;/strong&gt; partly Java and partly native code, and it needs the database's client software installed on the machine. It's used in a few special cases (for example, Oracle's OCI driver).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type 3, network-protocol driver:&lt;/strong&gt; talks to a middleware server, which then talks to the database. It's rare today.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type 4, thin driver (pure Java):&lt;/strong&gt; written entirely in Java and talks to the database directly over the network. &lt;strong&gt;No extra software to install.&lt;/strong&gt; This is the type you'll use almost every time, and all the drivers in the next section are Type 4.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Drivers for popular databases
&lt;/h3&gt;

&lt;p&gt;Here are the common ones, with the Maven dependency (&lt;code&gt;groupId:artifactId&lt;/code&gt;), the driver class name and an example URL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MySQL&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Dependency: &lt;code&gt;com.mysql:mysql-connector-j&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Driver class: &lt;code&gt;com.mysql.cj.jdbc.Driver&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;URL: &lt;code&gt;jdbc:mysql://localhost:3306/school&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MariaDB&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Dependency: &lt;code&gt;org.mariadb.jdbc:mariadb-java-client&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Driver class: &lt;code&gt;org.mariadb.jdbc.Driver&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;URL: &lt;code&gt;jdbc:mariadb://localhost:3306/school&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Dependency: &lt;code&gt;org.postgresql:postgresql&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Driver class: &lt;code&gt;org.postgresql.Driver&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;URL: &lt;code&gt;jdbc:postgresql://localhost:5432/school&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Oracle&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Dependency: &lt;code&gt;com.oracle.database.jdbc:ojdbc11&lt;/code&gt; (use &lt;code&gt;ojdbc8&lt;/code&gt; for Java 8)&lt;/li&gt;
&lt;li&gt;Driver class: &lt;code&gt;oracle.jdbc.OracleDriver&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;URL: &lt;code&gt;jdbc:oracle:thin:@//localhost:1521/XEPDB1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQL Server&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Dependency: &lt;code&gt;com.microsoft.sqlserver:mssql-jdbc&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Driver class: &lt;code&gt;com.microsoft.sqlserver.jdbc.SQLServerDriver&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;URL: &lt;code&gt;jdbc:sqlserver://localhost:1433;databaseName=school&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;H2&lt;/strong&gt; (a small, pure-Java database, great for learning and tests)

&lt;ul&gt;
&lt;li&gt;Dependency: &lt;code&gt;com.h2database:h2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Driver class: &lt;code&gt;org.h2.Driver&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;URL: &lt;code&gt;jdbc:h2:mem:testdb&lt;/code&gt; (in memory) or &lt;code&gt;jdbc:h2:~/school&lt;/code&gt; (a file)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQLite&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Dependency: &lt;code&gt;org.xerial:sqlite-jdbc&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Driver class: &lt;code&gt;org.sqlite.JDBC&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;URL: &lt;code&gt;jdbc:sqlite:school.db&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A few notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The driver class names are only needed in old-style code (we'll see why in a moment). It's still useful to recognize them in error messages.&lt;/li&gt;
&lt;li&gt;Always check the vendor's documentation for the current version and options. For example, newer SQL Server drivers encrypt the connection by default, so local development often needs extra URL settings such as &lt;code&gt;trustServerCertificate=true&lt;/code&gt; (use that only for development, never in production).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Adding a driver with Maven
&lt;/h3&gt;

&lt;p&gt;If you use Maven (see my Maven post), add the dependency in your &lt;code&gt;pom.xml&lt;/code&gt;. We'll use H2 for this post's examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.h2database&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;h2&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.4.240&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;runtime&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two things to notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the newest version you can find on Maven Central. &lt;code&gt;2.4.240&lt;/code&gt; is just the version I used.&lt;/li&gt;
&lt;li&gt;The scope is &lt;strong&gt;&lt;code&gt;runtime&lt;/code&gt;&lt;/strong&gt;, because your code uses only the standard &lt;code&gt;java.sql&lt;/code&gt; interfaces. The driver is needed to run the program, but not to compile it. That's the kind of "runtime" scope we saw in the Maven post.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For another database, swap in its dependency from the list above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Anatomy of a JDBC URL
&lt;/h3&gt;

&lt;p&gt;A JDBC URL tells &lt;code&gt;DriverManager&lt;/code&gt; which database to reach and where it lives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   jdbc:mysql://localhost:3306/school?useSSL=true
    |     |        |        |     |        |
    |     |        |        |     |        +-- optional settings (key=value)
    |     |        |        |     +----------- database (schema) name
    |     |        |        +----------------- port
    |     |        +-------------------------- host (the machine running the database)
    |     +----------------------------------- sub-protocol: which database/driver
    +----------------------------------------- always "jdbc"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact format changes slightly from database to database (see the list above), but the idea is always &lt;code&gt;jdbc:&lt;/code&gt; + the database type + the location.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps for working with JDBC
&lt;/h2&gt;

&lt;p&gt;Every JDBC program follows the same steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   1. Add the driver          put the driver jar on the classpath (Maven dependency)
          |
          v
   2. Register the driver     happens automatically in modern JDBC
          |
          v
   3. Open a Connection       DriverManager.getConnection(url, user, password)
          |
          v
   4. Create a statement      createStatement() or prepareStatement(sql)
          |
          v
   5. Execute the SQL         executeQuery(), executeUpdate() or execute()
          |
          v
   6. Process the results     loop over the ResultSet, or read the update count
          |
          v
   7. Handle exceptions       catch SQLException
          |
          v
   8. Close everything        ResultSet, then Statement, then Connection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A quick note on step 2. In older tutorials, you'll see this line before connecting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.mysql.cj.jdbc.Driver"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;You don't need it anymore.&lt;/strong&gt; Since JDBC 4.0 (Java 6), every driver jar announces itself in a file, and Java finds and registers it automatically as soon as it's on the classpath. Just add the jar, and &lt;code&gt;DriverManager&lt;/code&gt; will find it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your first JDBC program
&lt;/h2&gt;

&lt;p&gt;We'll build a program that connects to an in-memory H2 database, creates a table, inserts two rows and reads them back. You need nothing installed except the H2 dependency above.&lt;/p&gt;

&lt;h3&gt;
  
  
  The complete code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.sql.Connection&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.sql.DriverManager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.sql.PreparedStatement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.sql.ResultSet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.sql.SQLException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.sql.Statement&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JdbcDemo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"jdbc:h2:mem:testdb"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;USER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"sa"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;PASSWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DriverManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConnection&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;USER&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;PASSWORD&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

            &lt;span class="n"&gt;createTable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;insertStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;insertStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;printStudents&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Database error: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;createTable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"CREATE TABLE student (id INT PRIMARY KEY, name VARCHAR(50), marks INT)"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;insertStudent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"INSERT INTO student (id, name, marks) VALUES (?, ?, ?)"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Inserted "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" row(s): "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;printStudents&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SELECT id, name, marks FROM student ORDER BY id"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
             &lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"marks"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" | "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" | "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inserted 1 row(s): Asha
Inserted 1 row(s): Ravi
1 | Asha | 88
2 | Ravi | 72
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explaining the code
&lt;/h3&gt;

&lt;p&gt;Let's go through it piece by piece.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The three constants.&lt;/strong&gt; &lt;code&gt;URL&lt;/code&gt;, &lt;code&gt;USER&lt;/code&gt; and &lt;code&gt;PASSWORD&lt;/code&gt; describe where the database is and how to log in. &lt;code&gt;jdbc:h2:mem:testdb&lt;/code&gt; means "an H2 database that lives in memory, named testdb." &lt;code&gt;sa&lt;/code&gt; is H2's default user, with an empty password. (For a real database, you'd never write the password in your code. More on that in the best practices.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;DriverManager.getConnection(URL, USER, PASSWORD)&lt;/code&gt;.&lt;/strong&gt; This asks Java to find a driver that understands the URL, then opens a connection to the database. It returns a &lt;code&gt;Connection&lt;/code&gt;, your session with the database. It throws &lt;code&gt;SQLException&lt;/code&gt; if the database can't be reached, the login fails or no driver matches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;try (Connection conn = ...)&lt;/code&gt;.&lt;/strong&gt; This is &lt;strong&gt;try-with-resources&lt;/strong&gt;. Anything declared in the parentheses is closed &lt;strong&gt;automatically&lt;/strong&gt; when the block ends, even if an exception happens. So we never need to write &lt;code&gt;conn.close()&lt;/code&gt; ourselves. (An in-memory H2 database disappears when its last connection closes. Since we use one connection for the whole program, our data stays.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;conn.createStatement()&lt;/code&gt;.&lt;/strong&gt; This creates a &lt;code&gt;Statement&lt;/code&gt; object, a messenger that carries plain SQL text to the database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;stmt.executeUpdate(sql)&lt;/code&gt;.&lt;/strong&gt; This sends SQL that &lt;strong&gt;changes&lt;/strong&gt; something (here, a &lt;code&gt;CREATE TABLE&lt;/code&gt;). It returns the number of rows affected, which is 0 for this kind of command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;conn.prepareStatement(sql)&lt;/code&gt;&lt;/strong&gt; with the &lt;code&gt;?&lt;/code&gt; marks. This creates a &lt;code&gt;PreparedStatement&lt;/code&gt;. The &lt;code&gt;?&lt;/code&gt; characters are &lt;strong&gt;placeholders&lt;/strong&gt; for values we'll supply later. Then we fill them in with &lt;code&gt;setInt&lt;/code&gt; and &lt;code&gt;setString&lt;/code&gt;. &lt;strong&gt;The numbers start at 1&lt;/strong&gt;, not 0: &lt;code&gt;1&lt;/code&gt; is the first &lt;code&gt;?&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt; is the second, and so on. &lt;code&gt;executeUpdate()&lt;/code&gt; sends the command and returns how many rows were inserted (1).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;stmt.executeQuery(sql)&lt;/code&gt; and &lt;code&gt;ResultSet&lt;/code&gt;.&lt;/strong&gt; This sends a &lt;code&gt;SELECT&lt;/code&gt; and returns a &lt;code&gt;ResultSet&lt;/code&gt;, the rows that came back. The loop &lt;code&gt;while (rs.next())&lt;/code&gt; moves to the next row each time, and returns &lt;code&gt;false&lt;/code&gt; when there are no more rows. Inside the loop, &lt;code&gt;rs.getInt("id")&lt;/code&gt; and &lt;code&gt;rs.getString("name")&lt;/code&gt; read the columns of the current row by name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;catch (SQLException e)&lt;/code&gt;.&lt;/strong&gt; Almost every JDBC call can throw this checked exception, so the compiler makes us deal with it. Here we simply print the message.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The small helper methods.&lt;/strong&gt; Putting each job in its own method keeps &lt;code&gt;main&lt;/code&gt; short and makes each step easy to read and reuse.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens behind the scenes
&lt;/h3&gt;

&lt;p&gt;When you call &lt;code&gt;DriverManager.getConnection(...)&lt;/code&gt;, a lot happens in a few milliseconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   getConnection("jdbc:h2:mem:testdb", "sa", "")
        |
        v
   DriverManager asks each registered driver: "Do you accept this URL?"
        |        (drivers register themselves when their jar is on the classpath)
        v
   The matching driver opens a network connection (TCP) to the database,
   sends the user name and password, and waits for the database to accept them
        |
        v
   You get back a Connection object  (a real class from the driver,
   used through the standard java.sql.Connection interface)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, when you run a query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   stmt.executeQuery("SELECT ...")
        |  the driver sends the SQL text over the network
        v
   DATABASE: parses the SQL, plans how to run it, runs it
        |  sends the rows back (often in chunks)
        v
   ResultSet: a cursor that points at one row at a time; rs.next() moves it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Opening a connection is expensive: it needs a network round trip, a login and some setup. Sending SQL is much cheaper. That's why connection pools (covered in the best practices) are so important.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of execute methods
&lt;/h2&gt;

&lt;p&gt;A statement can send its SQL in four main ways. The right one depends on what kind of SQL you're sending:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   METHOD           USE IT FOR                          RETURNS
   executeQuery     SELECT                              ResultSet
   executeUpdate    INSERT, UPDATE, DELETE, and DDL     int (rows affected)
   execute          unknown SQL, or several results     boolean (true = a ResultSet)
   executeBatch     many statements at once             int[] (one count for each)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(DDL means commands that change the structure, like &lt;code&gt;CREATE TABLE&lt;/code&gt;.)&lt;/p&gt;

&lt;h3&gt;
  
  
  executeQuery
&lt;/h3&gt;

&lt;p&gt;Use it for a &lt;strong&gt;&lt;code&gt;SELECT&lt;/code&gt;&lt;/strong&gt;. It returns a &lt;code&gt;ResultSet&lt;/code&gt; and can never return an update count.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
     &lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT name FROM student ORDER BY id"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Asha
Ravi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you pass something that isn't a query (like an &lt;code&gt;INSERT&lt;/code&gt;) to &lt;code&gt;executeQuery&lt;/code&gt;, you get an &lt;code&gt;SQLException&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  executeUpdate
&lt;/h3&gt;

&lt;p&gt;Use it for &lt;strong&gt;&lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;&lt;/strong&gt;, and for DDL commands like &lt;code&gt;CREATE TABLE&lt;/code&gt;. It returns an &lt;code&gt;int&lt;/code&gt;: the number of rows affected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UPDATE student SET marks = marks + 5 WHERE marks &amp;lt; 80"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Rows updated: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rows updated: 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only Ravi (72) matched, so one row changed. For DDL, it returns 0. If you ever expect more than about two billion affected rows, there's also &lt;code&gt;executeLargeUpdate&lt;/code&gt;, which returns a &lt;code&gt;long&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  execute
&lt;/h3&gt;

&lt;p&gt;Use it when you &lt;strong&gt;don't know in advance&lt;/strong&gt; what the SQL does, or when it might produce &lt;strong&gt;several results&lt;/strong&gt; (some stored procedures do). It returns a &lt;code&gt;boolean&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;true&lt;/code&gt; means the first result is a &lt;code&gt;ResultSet&lt;/code&gt;. Get it with &lt;code&gt;getResultSet()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;false&lt;/code&gt; means the first result is an update count. Get it with &lt;code&gt;getUpdateCount()&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;hasResultSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hasResultSet&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResultSet&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Query returned "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" row(s)"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Update count: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUpdateCount&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"SELECT * FROM student"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DELETE FROM student WHERE id = 99"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query returned 2 row(s)
Update count: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same method handled both a query and an update, because &lt;code&gt;execute&lt;/code&gt; told us which kind of result we got. In everyday code, &lt;code&gt;executeQuery&lt;/code&gt; and &lt;code&gt;executeUpdate&lt;/code&gt; are clearer, so reach for &lt;code&gt;execute&lt;/code&gt; only when you need its flexibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  executeBatch
&lt;/h3&gt;

&lt;p&gt;Use it to send &lt;strong&gt;many statements in one trip&lt;/strong&gt; to the database. Sending 1000 inserts one by one means 1000 network round trips. A batch sends them together, which is much faster. You add statements with &lt;code&gt;addBatch()&lt;/code&gt;, then send them all with &lt;code&gt;executeBatch()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"INSERT INTO student (id, name, marks) VALUES (?, ?, ?)"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Meera"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;95&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBatch&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Kabir"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBatch&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Zoya"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;81&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBatch&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeBatch&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 1, 1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(This needs &lt;code&gt;import java.util.Arrays;&lt;/code&gt;.) The returned array holds one count for each statement. Some drivers return the special value &lt;code&gt;Statement.SUCCESS_NO_INFO&lt;/code&gt; (which is -2) instead, meaning "it worked, but I can't tell you how many rows." For very big batches, send them in chunks of a few hundred or thousand rows.&lt;/p&gt;

&lt;p&gt;From here on, our table has five students: Asha, Ravi, Meera, Kabir and Zoya.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of statements
&lt;/h2&gt;

&lt;p&gt;JDBC has three kinds of statement objects. They differ in &lt;strong&gt;how they build and send SQL&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Statement            plain SQL text, no parameters
        ^
        |  extends
   PreparedStatement    SQL with ? placeholders, precompiled, safe with user input
        ^
        |  extends
   CallableStatement    calls stored procedures and functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Statement
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;&lt;code&gt;Statement&lt;/code&gt;&lt;/strong&gt; sends a complete SQL string exactly as you wrote it. It has no placeholders.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CREATE TABLE course (id INT PRIMARY KEY, title VARCHAR(50))"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Good for:&lt;/strong&gt; fixed SQL that has &lt;strong&gt;no input from users&lt;/strong&gt;, like creating tables, running a fixed report or a one-off admin command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch out:&lt;/strong&gt; every time you run it, the database has to read and plan the SQL again. And if you build the SQL by joining in user input, you open the door to &lt;strong&gt;SQL injection&lt;/strong&gt; (next).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  PreparedStatement
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;&lt;code&gt;PreparedStatement&lt;/code&gt;&lt;/strong&gt; takes SQL with &lt;code&gt;?&lt;/code&gt; placeholders. The database &lt;strong&gt;compiles it once&lt;/strong&gt;, and you supply the values separately with &lt;code&gt;setInt&lt;/code&gt;, &lt;code&gt;setString&lt;/code&gt;, &lt;code&gt;setObject&lt;/code&gt; and similar methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SELECT name, marks FROM student WHERE marks &amp;gt;= ?"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"marks"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Asha 88
Meera 95
Zoya 81
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Ravi is at 77 after our earlier update, and Kabir at 64, so neither matches.)&lt;/p&gt;

&lt;p&gt;Why it's better for most work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Safe from SQL injection&lt;/strong&gt;, because values are never mixed into the SQL text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster when repeated&lt;/strong&gt;, since the database (or driver) can reuse the prepared plan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handles types and special characters for you.&lt;/strong&gt; A name like &lt;code&gt;O'Brien&lt;/code&gt; just works, with no manual escaping.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supports batches&lt;/strong&gt; easily, as we saw.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One limit: placeholders can only stand for &lt;strong&gt;values&lt;/strong&gt;. You can't use &lt;code&gt;?&lt;/code&gt; for a table name, a column name or an SQL keyword.&lt;/p&gt;

&lt;h3&gt;
  
  
  CallableStatement
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;&lt;code&gt;CallableStatement&lt;/code&gt;&lt;/strong&gt; calls a &lt;strong&gt;stored procedure&lt;/strong&gt; or &lt;strong&gt;function&lt;/strong&gt;, which is a piece of code saved inside the database itself. It uses a special call syntax that JDBC translates for each database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CallableStatement&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareCall&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{call get_student_count(?)}"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerOutParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;INTEGER&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Students: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This assumes your database already has a procedure named &lt;code&gt;get_student_count&lt;/code&gt; with one output parameter. Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;registerOutParameter&lt;/code&gt; declares a parameter that the procedure &lt;strong&gt;fills in&lt;/strong&gt; (an OUT parameter). Parameters you send in are IN parameters, set with &lt;code&gt;setXxx&lt;/code&gt; as usual. A parameter can also be both (INOUT).&lt;/li&gt;
&lt;li&gt;For a function that returns a value, the syntax is &lt;code&gt;{? = call my_function(?)}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CallableStatement&lt;/code&gt; extends &lt;code&gt;PreparedStatement&lt;/code&gt;, so everything you know about placeholders still applies.&lt;/li&gt;
&lt;li&gt;How you write procedures differs a lot between databases, but the Java side stays the same.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SQL injection and why it matters
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;SQL injection&lt;/strong&gt; happens when user input becomes part of the SQL itself. Watch what happens with a nasty input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;userInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"x' OR '1'='1"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// UNSAFE: Statement with the input joined into the SQL&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;unsafeSql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SELECT * FROM student WHERE name = '"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;userInput&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unsafeSql&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
     &lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unsafeSql&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Statement returned "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" row(s)"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// SAFE: PreparedStatement with a placeholder&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT * FROM student WHERE name = ?"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userInput&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PreparedStatement returned "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" row(s)"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM student WHERE name = 'x' OR '1'='1'
Statement returned 5 row(s)
PreparedStatement returned 0 row(s)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The input was meant to be a name. But with the plain &lt;code&gt;Statement&lt;/code&gt;, the quote characters &lt;strong&gt;changed the meaning of the SQL&lt;/strong&gt;. &lt;code&gt;'1'='1'&lt;/code&gt; is always true, so the query returned &lt;strong&gt;every row&lt;/strong&gt;. In a login form, the same trick lets someone in without a password. With the &lt;code&gt;PreparedStatement&lt;/code&gt;, the whole input is treated as one plain value to compare to a name, so nothing matched.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Statement (joined text):      [ SQL + user input ]  ----&amp;gt;  database parses it ALL as SQL
   PreparedStatement:            [ SQL with ? ]  ----&amp;gt;  database parses and plans it
                                 [ value ]       ----&amp;gt;  value is handled as DATA only
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many drivers don't allow several commands in one string by default, so the &lt;code&gt;; DROP TABLE&lt;/code&gt; trick is often blocked. But data leaks and login bypasses still work, so don't count on that. The rule is simple: &lt;strong&gt;never build SQL by joining in user input.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing the right statement
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Statement&lt;/code&gt;:&lt;/strong&gt; fixed SQL with no outside input (DDL, a fixed report, quick scripts).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PreparedStatement&lt;/code&gt;:&lt;/strong&gt; &lt;strong&gt;the default choice.&lt;/strong&gt; Use it for any SQL that has values, anything with user input, anything you run repeatedly and any batch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;CallableStatement&lt;/code&gt;:&lt;/strong&gt; when you need to call a stored procedure or function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're ever unsure, use &lt;code&gt;PreparedStatement&lt;/code&gt;. It's almost never the wrong answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with ResultSet
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;ResultSet&lt;/code&gt; is like a &lt;strong&gt;cursor&lt;/strong&gt; that starts &lt;em&gt;before&lt;/em&gt; the first row. Each call to &lt;code&gt;next()&lt;/code&gt; moves it down one row and returns &lt;code&gt;true&lt;/code&gt;, or &lt;code&gt;false&lt;/code&gt; when you run out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   before first row
        |
        v   rs.next()  --&amp;gt;  row 1     (true)
        |   rs.next()  --&amp;gt;  row 2     (true)
        |   rs.next()  --&amp;gt;  row 3     (true)
        v   rs.next()  --&amp;gt;  after last (false)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So you must call &lt;code&gt;next()&lt;/code&gt; &lt;strong&gt;before&lt;/strong&gt; you read anything. If you skip it, you'll get an error like "before start of result set."&lt;/p&gt;

&lt;p&gt;Reading columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;By &lt;strong&gt;name&lt;/strong&gt;: &lt;code&gt;rs.getString("name")&lt;/code&gt;. This is clearer and survives column reordering.&lt;/li&gt;
&lt;li&gt;By &lt;strong&gt;position&lt;/strong&gt;: &lt;code&gt;rs.getString(2)&lt;/code&gt;. &lt;strong&gt;Column numbers start at 1.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Pick the getter that matches the column: &lt;code&gt;getInt&lt;/code&gt;, &lt;code&gt;getLong&lt;/code&gt;, &lt;code&gt;getDouble&lt;/code&gt;, &lt;code&gt;getString&lt;/code&gt;, &lt;code&gt;getBoolean&lt;/code&gt;, &lt;code&gt;getBigDecimal&lt;/code&gt; (best for money), and so on.&lt;/li&gt;
&lt;li&gt;For dates and times, use the modern &lt;code&gt;java.time&lt;/code&gt; types: &lt;code&gt;rs.getObject("birth_date", LocalDate.class)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A subtle trap is &lt;strong&gt;NULL&lt;/strong&gt;. &lt;code&gt;getInt&lt;/code&gt; returns &lt;code&gt;0&lt;/code&gt; for a NULL column, which is indistinguishable from a real zero. To keep a NULL as a NULL, read it as an object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"marks"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// stays null if the column is NULL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or call &lt;code&gt;rs.wasNull()&lt;/code&gt; right after reading.&lt;/p&gt;

&lt;p&gt;You can also inspect the shape of a result with metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
     &lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SELECT id, name, marks FROM student"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ResultSetMetaData&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMetaData&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getColumnCount&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getColumnName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" : "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getColumnTypeName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ID : INTEGER
NAME : CHARACTER VARYING
MARKS : INTEGER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The type names depend on the database. H2 also shows column names in uppercase.)&lt;/p&gt;

&lt;p&gt;By default, a &lt;code&gt;ResultSet&lt;/code&gt; is &lt;strong&gt;forward-only and read-only&lt;/strong&gt;: you move down once, and you can't edit rows through it. You can ask for scrollable or updatable result sets with &lt;code&gt;createStatement(type, concurrency)&lt;/code&gt;, but that's rarely needed. A &lt;code&gt;ResultSet&lt;/code&gt; is also tied to its statement: closing the statement closes the result set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transactions
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;transaction&lt;/strong&gt; is a group of SQL commands that must succeed &lt;strong&gt;together or not at all&lt;/strong&gt;. The classic example is moving money: subtract from one account, add to another. If the first step works and the second fails, you must undo the first.&lt;/p&gt;

&lt;p&gt;By default, JDBC runs in &lt;strong&gt;auto-commit mode&lt;/strong&gt;: every statement is committed (made permanent) the moment it runs. For a multi-step job, turn it off and commit yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAutoCommit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;debit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// UPDATE account SET balance = balance - 500 WHERE id = 1&lt;/span&gt;
    &lt;span class="n"&gt;credit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// UPDATE account SET balance = balance + 500 WHERE id = 2&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;           &lt;span class="c1"&gt;// both changes become permanent together&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rollback&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;         &lt;span class="c1"&gt;// undo everything since the last commit&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAutoCommit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   setAutoCommit(false)
          |
     step 1 ---- step 2 ---- step 3
          |                    |
       all OK?              something failed?
          |                    |
       commit()            rollback()
     (permanent)         (as if nothing happened)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Transactions give you the &lt;strong&gt;ACID&lt;/strong&gt; guarantees: &lt;strong&gt;A&lt;/strong&gt;tomic (all or nothing), &lt;strong&gt;C&lt;/strong&gt;onsistent (rules stay true), &lt;strong&gt;I&lt;/strong&gt;solated (other users don't see half-finished work) and &lt;strong&gt;D&lt;/strong&gt;urable (committed data survives a crash). If you forget &lt;code&gt;commit()&lt;/code&gt; after turning off auto-commit, your changes are lost when the connection closes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Close resources with try-with-resources
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Connection&lt;/code&gt;, &lt;code&gt;Statement&lt;/code&gt; and &lt;code&gt;ResultSet&lt;/code&gt; all hold real resources (network sockets, memory on the database server). If you forget to close them, they leak, and eventually the database runs out of connections. Always use &lt;strong&gt;try-with-resources&lt;/strong&gt;, which closes everything for you in reverse order, even when exceptions happen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConnection&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
     &lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
     &lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// use rs&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;   &lt;span class="c1"&gt;// closed automatically: rs, then ps, then conn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avoid the old style with &lt;code&gt;finally&lt;/code&gt; blocks, null checks and nested try/catch. It's long and easy to get wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use PreparedStatement for every query with input
&lt;/h3&gt;

&lt;p&gt;Never build SQL by joining text with user input. Always use &lt;code&gt;?&lt;/code&gt; placeholders, and set the values with the right &lt;code&gt;setXxx&lt;/code&gt; method. We saw why in the SQL injection section. It also gives you speed and correct handling of quotes and types for free.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use a connection pool
&lt;/h3&gt;

&lt;p&gt;Opening a new connection for every request is slow. A &lt;strong&gt;connection pool&lt;/strong&gt; opens a fixed set of connections once and &lt;strong&gt;lends them out&lt;/strong&gt;. When you call &lt;code&gt;close()&lt;/code&gt; on a pooled connection, it isn't really closed. It goes back to the pool for the next user.&lt;/p&gt;

&lt;p&gt;Popular pools include &lt;strong&gt;HikariCP&lt;/strong&gt;. You create the pool &lt;strong&gt;once&lt;/strong&gt;, when the application starts, and share it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;HikariConfig&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HikariConfig&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setJdbcUrl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DB_URL"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUsername&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DB_USER"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPassword&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DB_PASSWORD"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMaximumPoolSize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;DataSource&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HikariDataSource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// create once, reuse everywhere&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConnection&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;    &lt;span class="c1"&gt;// borrowed from the pool&lt;/span&gt;
    &lt;span class="c1"&gt;// use conn&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;                                                        &lt;span class="c1"&gt;// returned to the pool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the code uses the standard &lt;code&gt;DataSource&lt;/code&gt; interface. That's why frameworks and servers prefer it to &lt;code&gt;DriverManager&lt;/code&gt;: you can swap in a pool without changing your database code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Handle SQLException properly
&lt;/h3&gt;

&lt;p&gt;Don't swallow it with an empty &lt;code&gt;catch&lt;/code&gt;. &lt;code&gt;SQLException&lt;/code&gt; carries more than a message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"INSERT INTO student VALUES (?, ?, ?)"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;                  &lt;span class="c1"&gt;// id 1 already exists&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Duplicate"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message : "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SQLState: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSQLState&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Code    : "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getErrorCode&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Message : Unique index or primary key violation: ...
SQLState: 23505
Code    : 23505
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(H2 shown. Other databases word the message differently.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;getSQLState()&lt;/code&gt;&lt;/strong&gt; is a standard 5-character code. &lt;code&gt;23505&lt;/code&gt; means a duplicate key, and the first two digits show the category (&lt;code&gt;23&lt;/code&gt; is "integrity constraint violation"). This is the safest value to write logic against.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;getErrorCode()&lt;/code&gt;&lt;/strong&gt; is a number specific to the database vendor.&lt;/li&gt;
&lt;li&gt;Log the full exception for developers, but show users a &lt;strong&gt;friendly message&lt;/strong&gt;. Raw database errors can reveal table names and other details an attacker could use.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Keep credentials out of your code
&lt;/h3&gt;

&lt;p&gt;Never hard-code passwords in source files, and never commit them to Git. Read them from &lt;strong&gt;environment variables&lt;/strong&gt;, a config file outside the repository or a secrets manager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DB_URL"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DB_USER"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DB_PASSWORD"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also give the application's database user &lt;strong&gt;only the permissions it needs&lt;/strong&gt; (for example, no permission to drop tables), and use an &lt;strong&gt;encrypted connection&lt;/strong&gt; (TLS) when the database is on another machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other good habits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Select only what you need.&lt;/strong&gt; Name the columns instead of &lt;code&gt;SELECT *&lt;/code&gt;, and add &lt;code&gt;WHERE&lt;/code&gt; and limits, so you don't pull huge amounts of data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use batches&lt;/strong&gt; for bulk inserts and updates, in chunks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use transactions&lt;/strong&gt; for anything that must succeed as a unit, and keep them short.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;java.time&lt;/code&gt; types&lt;/strong&gt; (&lt;code&gt;LocalDate&lt;/code&gt;, &lt;code&gt;LocalDateTime&lt;/code&gt;) with &lt;code&gt;setObject&lt;/code&gt; and &lt;code&gt;getObject&lt;/code&gt;, instead of the older &lt;code&gt;java.util.Date&lt;/code&gt; and &lt;code&gt;java.sql.Date&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate database code from business logic.&lt;/strong&gt; Put SQL in its own classes (often called DAOs or repositories), so the rest of the program doesn't depend on JDBC details.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set timeouts.&lt;/strong&gt; &lt;code&gt;stmt.setQueryTimeout(30)&lt;/code&gt; stops a stuck query from hanging forever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't use &lt;code&gt;Class.forName&lt;/code&gt;&lt;/strong&gt; for modern drivers. Just keep the driver jar on the classpath.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use column names&lt;/strong&gt; in &lt;code&gt;ResultSet&lt;/code&gt; reads for clarity, unless performance on huge result sets proves otherwise.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Statement&lt;/code&gt; or &lt;code&gt;PreparedStatement&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;PreparedStatement&lt;/code&gt; whenever there's any input value or any repetition. &lt;code&gt;Statement&lt;/code&gt; only for fixed, input-free SQL like DDL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;CallableStatement&lt;/code&gt;?&lt;/strong&gt; Only to call stored procedures or functions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;executeQuery&lt;/code&gt;, &lt;code&gt;executeUpdate&lt;/code&gt; or &lt;code&gt;execute&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;executeQuery&lt;/code&gt; for &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;executeUpdate&lt;/code&gt; for everything that changes data or structure, and &lt;code&gt;execute&lt;/code&gt; only when the kind of result is unknown or there may be several. Use &lt;code&gt;executeBatch&lt;/code&gt; for bulk work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;DriverManager&lt;/code&gt; or &lt;code&gt;DataSource&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;DriverManager&lt;/code&gt; is fine for learning and small scripts. Use a pooled &lt;code&gt;DataSource&lt;/code&gt; in real applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get columns by name or by index?&lt;/strong&gt; Name, for readability. Index is a little faster and fine for tiny queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JDBC directly, or a framework?&lt;/strong&gt; Plain JDBC is perfect for learning, small tools and cases where you want full control. For bigger applications, tools built on top of JDBC (like Spring's &lt;code&gt;JdbcTemplate&lt;/code&gt;, jOOQ or JPA with Hibernate) remove repetitive code. They all use JDBC underneath, so understanding it makes every one of them easier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-commit or manual transactions?&lt;/strong&gt; Auto-commit for single statements. Manual &lt;code&gt;commit&lt;/code&gt; and &lt;code&gt;rollback&lt;/code&gt; whenever several statements belong together.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"No suitable driver found."&lt;/strong&gt; The driver jar isn't on the classpath, or the URL is wrong. Check the dependency (and its scope) and the exact URL format for your database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Joining user input into SQL.&lt;/strong&gt; &lt;code&gt;"... WHERE name = '" + name + "'"&lt;/code&gt; is an SQL injection bug waiting to happen. Use &lt;code&gt;PreparedStatement&lt;/code&gt; with &lt;code&gt;?&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not closing resources.&lt;/strong&gt; Leaked connections, statements and result sets slowly exhaust the database. Use try-with-resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Off-by-one and cursor mistakes.&lt;/strong&gt; Parameter and column positions start at &lt;strong&gt;1&lt;/strong&gt;, and a &lt;code&gt;ResultSet&lt;/code&gt; must be advanced with &lt;code&gt;next()&lt;/code&gt; before you read it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using the wrong execute method.&lt;/strong&gt; Calling &lt;code&gt;executeQuery&lt;/code&gt; with an &lt;code&gt;INSERT&lt;/code&gt;, or &lt;code&gt;executeUpdate&lt;/code&gt; with a &lt;code&gt;SELECT&lt;/code&gt;, throws an &lt;code&gt;SQLException&lt;/code&gt;. Match the method to the SQL, or use &lt;code&gt;execute&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction surprises.&lt;/strong&gt; With auto-commit on, a half-finished multi-step job leaves half the changes saved. With auto-commit off, forgetting &lt;code&gt;commit()&lt;/code&gt; throws all the changes away.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JDBC&lt;/strong&gt; is Java's standard API (&lt;code&gt;java.sql&lt;/code&gt; and &lt;code&gt;javax.sql&lt;/code&gt;) for talking to relational databases. Your code uses the interfaces, and a vendor's &lt;strong&gt;driver&lt;/strong&gt; does the translation.&lt;/li&gt;
&lt;li&gt;Drivers come in four types, but you'll use &lt;strong&gt;Type 4 (pure Java)&lt;/strong&gt;: &lt;code&gt;mysql-connector-j&lt;/code&gt;, &lt;code&gt;postgresql&lt;/code&gt;, &lt;code&gt;ojdbc11&lt;/code&gt;, &lt;code&gt;mssql-jdbc&lt;/code&gt;, &lt;code&gt;h2&lt;/code&gt;, &lt;code&gt;sqlite-jdbc&lt;/code&gt; and others. Add the right one with Maven, usually in &lt;code&gt;runtime&lt;/code&gt; scope.&lt;/li&gt;
&lt;li&gt;A JDBC URL looks like &lt;code&gt;jdbc:&amp;lt;database&amp;gt;://host:port/name&lt;/code&gt;. Since JDBC 4, drivers register themselves, so &lt;code&gt;Class.forName&lt;/code&gt; is no longer needed.&lt;/li&gt;
&lt;li&gt;The steps: add the driver, open a &lt;code&gt;Connection&lt;/code&gt;, create a statement, execute the SQL, process the results, handle &lt;code&gt;SQLException&lt;/code&gt; and close everything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execute methods:&lt;/strong&gt; &lt;code&gt;executeQuery&lt;/code&gt; (&lt;code&gt;SELECT&lt;/code&gt;, returns a &lt;code&gt;ResultSet&lt;/code&gt;), &lt;code&gt;executeUpdate&lt;/code&gt; (changes data, returns a row count), &lt;code&gt;execute&lt;/code&gt; (unknown or multiple results, returns a boolean) and &lt;code&gt;executeBatch&lt;/code&gt; (many statements at once).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Statements:&lt;/strong&gt; &lt;code&gt;Statement&lt;/code&gt; (plain, fixed SQL), &lt;code&gt;PreparedStatement&lt;/code&gt; (placeholders, safe, faster, the default) and &lt;code&gt;CallableStatement&lt;/code&gt; (stored procedures).&lt;/li&gt;
&lt;li&gt;Joining user input into SQL causes &lt;strong&gt;SQL injection&lt;/strong&gt;. &lt;code&gt;PreparedStatement&lt;/code&gt; prevents it.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;ResultSet&lt;/code&gt; is a cursor: call &lt;code&gt;next()&lt;/code&gt; first, and columns start at 1. Watch out for NULL values.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;transactions&lt;/strong&gt; (&lt;code&gt;setAutoCommit(false)&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt;, &lt;code&gt;rollback&lt;/code&gt;) when several statements must succeed together.&lt;/li&gt;
&lt;li&gt;Best practices: &lt;strong&gt;try-with-resources&lt;/strong&gt;, &lt;code&gt;PreparedStatement&lt;/code&gt; for all input, a &lt;strong&gt;connection pool&lt;/strong&gt;, careful &lt;code&gt;SQLException&lt;/code&gt; handling, credentials outside the code and small, focused queries.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: build a &lt;code&gt;StudentDao&lt;/code&gt; class with five methods: &lt;code&gt;insert&lt;/code&gt;, &lt;code&gt;findById&lt;/code&gt;, &lt;code&gt;findAll&lt;/code&gt;, &lt;code&gt;updateMarks&lt;/code&gt; and &lt;code&gt;delete&lt;/code&gt;, all using &lt;code&gt;PreparedStatement&lt;/code&gt; and try-with-resources, against the H2 table from this post. Then add a &lt;code&gt;insertAll(List&amp;lt;Student&amp;gt;)&lt;/code&gt; method that uses a batch, and a method that moves marks from one student to another inside a transaction, rolling back if either update fails.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, switch to a real database. Install MySQL or PostgreSQL (or run one in Docker), swap the H2 dependency for the right driver, and change only the URL, user and password. The rest of your code should run unchanged, and that's the whole point of JDBC. Then put your connection settings in environment variables, and add a HikariCP pool.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

</description>
      <category>java</category>
      <category>jdbc</category>
      <category>database</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Git Branches Are Just Pointers: A Simple Explanation</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Fri, 23 Oct 2026 11:56:19 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/git-branches-are-just-pointers-a-simple-explanation-1ikn</link>
      <guid>https://dev.to/mayur_bodhare/git-branches-are-just-pointers-a-simple-explanation-1ikn</guid>
      <description>&lt;p&gt;Years ago, I had a folder on my laptop that looked like this: &lt;code&gt;project&lt;/code&gt;, &lt;code&gt;project_final&lt;/code&gt;, &lt;code&gt;project_final_v2&lt;/code&gt;, &lt;code&gt;project_final_v2_REAL&lt;/code&gt; and &lt;code&gt;project_final_v2_REAL_use_this_one&lt;/code&gt;. I was scared to delete any of them, because I couldn't remember which one had the fix I made on Tuesday. Then a friend and I edited the same file at the same time, and one of us overwrote the other's work.&lt;/p&gt;

&lt;p&gt;If that sounds familiar, you already understand the problem that &lt;strong&gt;version control&lt;/strong&gt; solves. And the tool that almost every developer uses today for it is &lt;strong&gt;Git&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this post, we'll learn what version control is and the three types of version control systems, where Git came from, how Git stores your work, what repositories are (and how GitHub, GitLab and Bitbucket fit in), the working directory and the staging area, the everyday workflow, branches, &lt;code&gt;HEAD&lt;/code&gt;, tags and the common commands with examples. I've drawn the important pictures in text, and most commands come with the output you'll see.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Version control systems

&lt;ul&gt;
&lt;li&gt;What is a version control system?&lt;/li&gt;
&lt;li&gt;Why we need one&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Types of version control systems

&lt;ul&gt;
&lt;li&gt;1. Local VCS&lt;/li&gt;
&lt;li&gt;2. Centralized VCS&lt;/li&gt;
&lt;li&gt;3. Distributed VCS&lt;/li&gt;
&lt;li&gt;Comparing the three types&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
What is Git?

&lt;ul&gt;
&lt;li&gt;A short history of Git&lt;/li&gt;
&lt;li&gt;How Git stores your work&lt;/li&gt;
&lt;li&gt;What is inside the .git folder&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Repositories

&lt;ul&gt;
&lt;li&gt;Local and remote repositories&lt;/li&gt;
&lt;li&gt;GitHub, GitLab and Bitbucket&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Setting up Git for the first time&lt;/li&gt;
&lt;li&gt;
The three areas of Git

&lt;ul&gt;
&lt;li&gt;Working directory&lt;/li&gt;
&lt;li&gt;Staging area&lt;/li&gt;
&lt;li&gt;Local repository&lt;/li&gt;
&lt;li&gt;The four states of a file&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
The Git workflow

&lt;ul&gt;
&lt;li&gt;A solo workflow&lt;/li&gt;
&lt;li&gt;A team workflow&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Branches

&lt;ul&gt;
&lt;li&gt;What a branch really is&lt;/li&gt;
&lt;li&gt;Creating, switching and merging&lt;/li&gt;
&lt;li&gt;Merge conflicts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Pointers in Git and HEAD

&lt;ul&gt;
&lt;li&gt;What HEAD is&lt;/li&gt;
&lt;li&gt;Detached HEAD&lt;/li&gt;
&lt;li&gt;Moving relative to HEAD&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Tags

&lt;ul&gt;
&lt;li&gt;Lightweight and annotated tags&lt;/li&gt;
&lt;li&gt;Working with tags&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Common Git commands with examples

&lt;ul&gt;
&lt;li&gt;Starting a repository&lt;/li&gt;
&lt;li&gt;Checking status and differences&lt;/li&gt;
&lt;li&gt;Staging and committing&lt;/li&gt;
&lt;li&gt;Viewing history&lt;/li&gt;
&lt;li&gt;Branching and merging&lt;/li&gt;
&lt;li&gt;Working with remotes&lt;/li&gt;
&lt;li&gt;Undoing things&lt;/li&gt;
&lt;li&gt;Saving work with stash&lt;/li&gt;
&lt;li&gt;Ignoring files with .gitignore&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Which one should I use?&lt;/li&gt;
&lt;li&gt;Common mistakes&lt;/li&gt;
&lt;li&gt;Quick recap&lt;/li&gt;
&lt;li&gt;Try it yourself&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Version control systems
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a version control system?
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;version control system&lt;/strong&gt; (VCS) is a tool that records the changes you make to your files over time, so you can bring back any earlier version whenever you want. Instead of keeping only the latest copy, it keeps the &lt;strong&gt;whole history&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every saved version is usually called a &lt;strong&gt;commit&lt;/strong&gt; or a &lt;strong&gt;revision&lt;/strong&gt;. With a VCS, you can answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What did this file look like last month?&lt;/li&gt;
&lt;li&gt;Who changed this line, when, and why?&lt;/li&gt;
&lt;li&gt;Which change broke the build?&lt;/li&gt;
&lt;li&gt;How do I go back to the version that worked?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why we need one
&lt;/h3&gt;

&lt;p&gt;Without version control, people copy folders, rename files with "final" in the name and email zip files to each other. That causes real problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No history.&lt;/strong&gt; You can't see what changed, or why.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lost work.&lt;/strong&gt; One person overwrites another person's changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fear of experiments.&lt;/strong&gt; Trying a new idea feels risky, because you can't easily undo it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No clear record.&lt;/strong&gt; Nobody knows which copy is the right one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A VCS fixes all of this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   WITHOUT version control               WITH version control

   project/                              project/        one folder, one history
   project_final/
   project_final_v2/                     v1 -- v2 -- v3 -- v4 -- v5
   project_final_v2_REAL/                 ^                      ^
   project_final_v2_REAL_use_this_one/    go back to any point   latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get a full &lt;strong&gt;history&lt;/strong&gt;, easy &lt;strong&gt;undo&lt;/strong&gt;, safe &lt;strong&gt;teamwork&lt;/strong&gt;, cheap &lt;strong&gt;experiments&lt;/strong&gt; (with branches, as we'll see) and a &lt;strong&gt;backup&lt;/strong&gt; if the history is stored on a server. It also fits naturally with the other tools in a developer's day, like build tools and automated tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of version control systems
&lt;/h2&gt;

&lt;p&gt;Version control systems have grown through three generations: local, centralized and distributed.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Local VCS
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;local VCS&lt;/strong&gt; keeps a small database of versions &lt;strong&gt;on your own computer&lt;/strong&gt;. When you change a file, the tool saves the new version in that database. A classic example is &lt;strong&gt;RCS&lt;/strong&gt; (Revision Control System), from the 1980s.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   YOUR COMPUTER
  +-----------------------------------------+
  |   working files        local database   |
  |   report.txt   &amp;lt;----&amp;gt;  v1, v2, v3 ...   |
  +-----------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Good:&lt;/strong&gt; simple, and you don't need a server or a network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not good:&lt;/strong&gt; it works for one person on one machine. There's no way to collaborate, and if your disk dies, the history dies with it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Centralized VCS
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;centralized VCS&lt;/strong&gt; keeps all the versions on &lt;strong&gt;one central server&lt;/strong&gt;. Each developer "checks out" a working copy from it, and sends changes back to the server with a commit. Examples are &lt;strong&gt;CVS&lt;/strong&gt;, &lt;strong&gt;Subversion (SVN)&lt;/strong&gt; and &lt;strong&gt;Perforce&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                   +-------------------------+
                   |     CENTRAL SERVER      |
                   |  the ONLY full history  |
                   +-------------------------+
                     ^      ^       ^      ^
              commit |      |       |      | update
                     v      v       v      v
                  Alice    Bob    Carol    Dan
              (working copy only: the latest files)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Good:&lt;/strong&gt; everyone works from the same place, and admins can control who can do what. It's easy to understand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not good:&lt;/strong&gt; the server is a &lt;strong&gt;single point of failure&lt;/strong&gt;. If it goes down, nobody can commit or look at history. If its disk is lost and there's no backup, the history is gone. You also need the network for most actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Distributed VCS
&lt;/h3&gt;

&lt;p&gt;In a &lt;strong&gt;distributed VCS&lt;/strong&gt;, every developer gets a &lt;strong&gt;full copy of the entire repository, including all of its history&lt;/strong&gt;. You commit to your own copy, with no server needed, and later share your commits with others. Examples are &lt;strong&gt;Git&lt;/strong&gt;, &lt;strong&gt;Mercurial&lt;/strong&gt; and &lt;strong&gt;Bazaar&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                +--------------------------+
                |  SHARED REMOTE (GitHub)  |
                |   full copy + history    |
                +--------------------------+
                   ^  push/pull   ^  push/pull
                   |              |
        +--------------------+  +--------------------+
        |  Alice's computer  |  |   Bob's computer   |
        |  FULL copy +       |  |   FULL copy +      |
        |  full history      |  |   full history     |
        +--------------------+  +--------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Good:&lt;/strong&gt; you can work offline, commits are instant, there are many backups (every clone is one) and branching is cheap. Teams can choose any workflow they like.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not good:&lt;/strong&gt; there's more to learn at first, and a clone downloads the whole history. Also, which copy is "the official one" is a rule your team agrees on (by convention, the shared remote), not something the tool enforces.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comparing the three types
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                      LOCAL            CENTRALIZED           DISTRIBUTED
   Examples           RCS              CVS, SVN, Perforce    Git, Mercurial
   Where is history?  your disk only   on the server         in EVERY clone
   Teamwork?          no               yes                   yes
   Works offline?     yes              very limited          yes (almost everything)
   If a server dies   n/a              history at risk       any clone can restore it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is Git?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Git&lt;/strong&gt; is a free, open-source, distributed version control system. It runs on every major operating system, it's fast, and it's the most widely used VCS in the world.&lt;/p&gt;

&lt;h3&gt;
  
  
  A short history of Git
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Before 2002&lt;/strong&gt;, the Linux kernel (one of the biggest open-source projects) was managed by sharing patches and archive files by hand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;From 2002&lt;/strong&gt;, the kernel team used &lt;strong&gt;BitKeeper&lt;/strong&gt;, a proprietary distributed system that gave the kernel developers free use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In 2005&lt;/strong&gt;, that free arrangement ended after a dispute. &lt;strong&gt;Linus Torvalds&lt;/strong&gt;, the creator of Linux, decided to write a replacement himself.&lt;/li&gt;
&lt;li&gt;His goals were: &lt;strong&gt;speed&lt;/strong&gt;, a &lt;strong&gt;simple design&lt;/strong&gt;, strong support for &lt;strong&gt;thousands of parallel branches&lt;/strong&gt; (non-linear development), being &lt;strong&gt;fully distributed&lt;/strong&gt;, and the ability to handle huge projects like the Linux kernel.&lt;/li&gt;
&lt;li&gt;Git was working within days, and &lt;strong&gt;in April 2005&lt;/strong&gt; it was already being used to manage its own source. By mid-2005, the Linux kernel was managed with Git. &lt;strong&gt;Junio Hamano&lt;/strong&gt; took over as the maintainer in July 2005 and has led the project since. Git 1.0 followed in December 2005.&lt;/li&gt;
&lt;li&gt;The name "git" is British slang for an unpleasant person. Linus joked that he names his projects after himself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt; launched in 2008 and made Git easy to share, and Git became the standard for modern software teams.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Git stores your work
&lt;/h3&gt;

&lt;p&gt;Many older systems store a list of &lt;strong&gt;changes&lt;/strong&gt; for each file. Git thinks differently: every commit is a &lt;strong&gt;snapshot of your whole project&lt;/strong&gt; at that moment. If a file didn't change, Git doesn't store it again. It simply points to the earlier identical copy. (Internally, Git also compresses data efficiently, but the model to keep in your head is "snapshots.")&lt;/p&gt;

&lt;p&gt;Git keeps four kinds of objects in its database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blob:&lt;/strong&gt; the contents of one file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tree:&lt;/strong&gt; a folder. It lists file names and points to blobs and other trees.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit:&lt;/strong&gt; a snapshot. It points to one tree, to its &lt;strong&gt;parent&lt;/strong&gt; commit(s), and holds the author, date and message.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tag:&lt;/strong&gt; a named label (we'll see these later).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   commit a1b2c3d
     |-- tree  (the snapshot of the whole project folder)
     |      |-- blob  README.md
     |      +-- tree  src/
     |             +-- blob  App.java
     |-- parent  3f2a9c1   &amp;lt;-- the previous commit
     |-- author, date
     +-- message: "Update README"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each object is named by a &lt;strong&gt;hash&lt;/strong&gt;, a 40-character code (SHA-1) calculated from its content, like &lt;code&gt;3f2a9c1e5d6b7a8c9d0e1f2a3b4c5d6e7f8a9b0c&lt;/code&gt;. (Git can also use SHA-256 as an option.) This has two nice effects: the same content always gets the same name, and if anyone changes even one letter of an old commit, its hash changes. That's how Git notices tampering and corruption. You usually only need the first 7 characters of a hash.&lt;/p&gt;

&lt;p&gt;You can look inside a commit with &lt;code&gt;git cat-file&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tree 9c8f2e1d7a5b3c4e6f8a0b1c2d3e4f5a6b7c8d9e
parent 3f2a9c1e5d6b7a8c9d0e1f2a3b4c5d6e7f8a9b0c
author Asha Rao &amp;lt;asha@example.com&amp;gt; 1792730700 +0530
committer Asha Rao &amp;lt;asha@example.com&amp;gt; 1792730700 +0530

Update README
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Your hashes and dates will be different.) A commit is just a small text object: a tree, a parent and a message.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is inside the .git folder
&lt;/h3&gt;

&lt;p&gt;When you create a repository, Git makes a hidden folder called &lt;strong&gt;&lt;code&gt;.git&lt;/code&gt;&lt;/strong&gt; inside your project. This folder &lt;strong&gt;is&lt;/strong&gt; the repository: all the history lives there. If you delete it, your project folder becomes a normal folder again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   my-project/
   |-- README.md                 &amp;lt;- your files (the working directory)
   |-- src/
   +-- .git/                     &amp;lt;- the repository itself
        |-- HEAD                 &amp;lt;- which branch (or commit) you're on now
        |-- config               &amp;lt;- settings for this repository
        |-- index                &amp;lt;- the staging area
        |-- objects/             &amp;lt;- all content: blobs, trees, commits, tags
        |-- refs/
        |    |-- heads/          &amp;lt;- one small file per branch
        |    +-- tags/           &amp;lt;- one small file per tag
        +-- hooks/               &amp;lt;- optional scripts that run on events
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember &lt;code&gt;HEAD&lt;/code&gt;, &lt;code&gt;index&lt;/code&gt; and &lt;code&gt;refs&lt;/code&gt;. They explain most of what follows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repositories
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;repository&lt;/strong&gt; (or &lt;strong&gt;repo&lt;/strong&gt;) is a project folder that Git is tracking, together with its complete history. It's the main thing in Git.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local and remote repositories
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;local repository&lt;/strong&gt; is the one on your computer (the &lt;code&gt;.git&lt;/code&gt; folder in your project).&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;remote repository&lt;/strong&gt; is a copy stored on a server, such as GitHub, which the whole team shares. Git gives each remote a short name. The default is &lt;strong&gt;&lt;code&gt;origin&lt;/code&gt;&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   YOUR COMPUTER                                    SERVER (GitHub, GitLab ...)
  +--------------------+     git push  -------&amp;gt;   +-------------------------+
  |  local repository  |                           |    remote repository    |
  |  (full history)    |  &amp;lt;------- git fetch/pull  |      called "origin"    |
  +--------------------+                           +-------------------------+
            ^
            |  git clone  (makes a local copy of a remote, once)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git clone&lt;/code&gt; copies a remote repository to your computer (once).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git push&lt;/code&gt; uploads your new commits.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git fetch&lt;/code&gt; and &lt;code&gt;git pull&lt;/code&gt; bring other people's commits down.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You connect to a remote over &lt;strong&gt;HTTPS&lt;/strong&gt; or &lt;strong&gt;SSH&lt;/strong&gt;. GitHub no longer accepts your account password for Git over HTTPS. You use a &lt;strong&gt;personal access token&lt;/strong&gt; instead, or an &lt;strong&gt;SSH key&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub, GitLab and Bitbucket
&lt;/h3&gt;

&lt;p&gt;First, a very common mix-up: &lt;strong&gt;Git is the tool, and GitHub is a website.&lt;/strong&gt; Git works fine without any of them. GitHub, GitLab and Bitbucket are &lt;strong&gt;hosting services&lt;/strong&gt; that store your remote repositories and add useful team features around them: a website to browse code, issue tracking, code review, permissions and automation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; the biggest, and home to most open-source projects. It's owned by Microsoft (since 2018). Its review feature is called a &lt;strong&gt;pull request&lt;/strong&gt;, and its built-in automation is &lt;strong&gt;GitHub Actions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitLab:&lt;/strong&gt; an all-in-one DevOps platform with built-in CI/CD (&lt;strong&gt;GitLab CI/CD&lt;/strong&gt;). Its review feature is called a &lt;strong&gt;merge request&lt;/strong&gt;. You can also &lt;strong&gt;host it yourself&lt;/strong&gt;, which many companies prefer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bitbucket:&lt;/strong&gt; from Atlassian, so it works very closely with Jira and other Atlassian tools. It has pull requests and its own pipelines (&lt;strong&gt;Bitbucket Pipelines&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Others exist too, like Azure DevOps Repos and the self-hosted Gitea. All of them speak Git, so your commands are exactly the same on each. You can even push one repository to two of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Git for the first time
&lt;/h2&gt;

&lt;p&gt;Install Git from the official site (&lt;code&gt;git-scm.com&lt;/code&gt;) or your package manager, then check it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git version 2.x.y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tell Git who you are. This name and email are stored in every commit you make:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"Asha Rao"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"asha@example.com"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; init.defaultBranch main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--global&lt;/code&gt; means "for my user on this computer." Without it, the setting applies to just one repository (&lt;code&gt;--local&lt;/code&gt;). There's also a &lt;code&gt;--system&lt;/code&gt; level for the whole machine.&lt;/li&gt;
&lt;li&gt;The last line makes new repositories start with a branch called &lt;code&gt;main&lt;/code&gt;. Older Git versions used &lt;code&gt;master&lt;/code&gt; by default.&lt;/li&gt;
&lt;li&gt;To see all your settings, run &lt;code&gt;git config --list&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The three areas of Git
&lt;/h2&gt;

&lt;p&gt;This is the idea that makes Git click. Your files move through &lt;strong&gt;three areas&lt;/strong&gt; on your computer, and then to a fourth place, the remote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   WORKING DIRECTORY      STAGING AREA          LOCAL REPOSITORY        REMOTE REPOSITORY
   (your files,           (index: what goes     (.git: the history)     (GitHub, GitLab ...)
    where you edit)        into the next commit)
          |                      |                      |                      |
          |   git add            |    git commit        |    git push          |
          |---------------------&amp;gt;|---------------------&amp;gt;|---------------------&amp;gt;|
          |                      |                      |                      |
          |                      |                      |&amp;lt;---------------------|
          |                      |                      |   git fetch / pull   |
          |&amp;lt;--------------------------------------------|                      |
                     git switch / git restore (bring files back)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Working directory
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;working directory&lt;/strong&gt; (also called the &lt;strong&gt;working tree&lt;/strong&gt;) is simply your project folder, with the actual files you open and edit. It starts as a checked-out snapshot of one commit. Whatever you change here, Git notices, but &lt;strong&gt;nothing is saved to history yet&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Staging area
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;staging area&lt;/strong&gt; (also called the &lt;strong&gt;index&lt;/strong&gt;) is a waiting room for your next commit. You choose exactly &lt;strong&gt;which changes&lt;/strong&gt; should go in, using &lt;code&gt;git add&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why does Git have this extra step? Imagine you fixed a bug and, at the same time, tidied some unrelated code. With a staging area, you can stage and commit the bug fix first, and the tidying as a separate commit. Small, focused commits are much easier to review and to undo later. A good way to think about it is &lt;strong&gt;packing a box before you seal it&lt;/strong&gt;: &lt;code&gt;git add&lt;/code&gt; puts things in the box, and &lt;code&gt;git commit&lt;/code&gt; seals it and puts it on the shelf.&lt;/p&gt;

&lt;p&gt;Behind the scenes, the staging area is just the &lt;code&gt;.git/index&lt;/code&gt; file, a list of what the next snapshot will contain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local repository
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;local repository&lt;/strong&gt; is the &lt;code&gt;.git&lt;/code&gt; folder: the permanent, committed history on your own machine. When you run &lt;code&gt;git commit&lt;/code&gt;, Git takes whatever is in the staging area and saves it as a new snapshot here.&lt;/p&gt;

&lt;h3&gt;
  
  
  The four states of a file
&lt;/h3&gt;

&lt;p&gt;At any moment, each file is in one of four states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Untracked:&lt;/strong&gt; a new file that Git doesn't know about yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Committed&lt;/strong&gt; (also called unmodified): the file is the same as in the last commit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modified:&lt;/strong&gt; you changed it, but didn't stage it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staged:&lt;/strong&gt; you marked the change for the next commit.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Untracked ---- git add ----&amp;gt; Staged ---- git commit ----&amp;gt; Committed
                                  ^                              |
                                  |                           edit the file
                               git add                           |
                                  |                              v
                                  +---------------------------- Modified
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Git workflow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A solo workflow
&lt;/h3&gt;

&lt;p&gt;Here's the everyday loop, as a hands-on session. We'll create a project and watch the file move through the states:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-project
&lt;span class="nb"&gt;cd &lt;/span&gt;my-project
git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Initialized empty Git repository in /home/asha/my-project/.git/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a file, then ask Git what it sees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"# My Project"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; README.md
git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On branch main

No commits yet

Untracked files:
  (use "git add &amp;lt;file&amp;gt;..." to include in what will be committed)
    README.md

nothing added to commit but untracked files present (use "git add" to track)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file is &lt;strong&gt;untracked&lt;/strong&gt;. Now stage it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add README.md
git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached &amp;lt;file&amp;gt;..." to unstage)
    new file:   README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's &lt;strong&gt;staged&lt;/strong&gt;. Now commit it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add README"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[main (root-commit) 3f2a9c1] Add README
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's &lt;strong&gt;committed&lt;/strong&gt;. Now edit the file and check again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"A small demo project."&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; README.md
git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;On branch main
Changes not staged for commit:
  (use "git add &amp;lt;file&amp;gt;..." to update what will be committed)
  (use "git restore &amp;lt;file&amp;gt;..." to discard changes in working directory)
    modified:   README.md

no changes added to commit (use "git add" and/or "git commit -a")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's &lt;strong&gt;modified&lt;/strong&gt;. See exactly what changed, then stage and commit again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;diff --git a/README.md b/README.md
index 8c7e5a6..2b1f4d9 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
 # My Project
+A small demo project.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add README.md
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Describe the project"&lt;/span&gt;
git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a1b2c3d (HEAD -&amp;gt; main) Describe the project
3f2a9c1 Add README
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The loop is always the same: &lt;strong&gt;edit, check, stage, commit&lt;/strong&gt;, and push when you want to share. A good commit message is short (about 50 characters for the first line), written as a command ("Add login form", not "added stuff"), and says what the change does.&lt;/p&gt;

&lt;h3&gt;
  
  
  A team workflow
&lt;/h3&gt;

&lt;p&gt;When several people work together, the most common method is the &lt;strong&gt;feature-branch workflow&lt;/strong&gt;. Nobody works directly on &lt;code&gt;main&lt;/code&gt;. Each new piece of work gets its own branch, and it joins &lt;code&gt;main&lt;/code&gt; through a &lt;strong&gt;pull request&lt;/strong&gt; (called a merge request on GitLab):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   main      o---o---o---------------------o---o        (always stable)
                      \                   /
   feature             o---o---o---------+              (your work, reviewed, then merged)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone the repository once: &lt;code&gt;git clone &amp;lt;url&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Update your local &lt;code&gt;main&lt;/code&gt;: &lt;code&gt;git switch main&lt;/code&gt;, then &lt;code&gt;git pull&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create a branch for your work: &lt;code&gt;git switch -c feature/login&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Edit, then &lt;code&gt;git add&lt;/code&gt; and &lt;code&gt;git commit&lt;/code&gt;, as often as you like.&lt;/li&gt;
&lt;li&gt;Upload the branch: &lt;code&gt;git push -u origin feature/login&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Open a &lt;strong&gt;pull request&lt;/strong&gt; on the website. Teammates review it, and automated tests run.&lt;/li&gt;
&lt;li&gt;After approval, merge it (usually with a button on the website).&lt;/li&gt;
&lt;li&gt;Clean up: &lt;code&gt;git switch main&lt;/code&gt;, &lt;code&gt;git pull&lt;/code&gt;, then &lt;code&gt;git branch -d feature/login&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Branches
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What a branch really is
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;branch&lt;/strong&gt; is a &lt;strong&gt;lightweight, movable pointer to a commit&lt;/strong&gt;. That's all. It is not a copy of your files. Creating a branch just writes the 40-character hash of a commit into a tiny file in &lt;code&gt;.git/refs/heads/&lt;/code&gt;. When you make a new commit on a branch, the pointer moves forward to it automatically.&lt;/p&gt;

&lt;p&gt;That's why branching in Git is instant and almost free, while in older systems, a branch could mean copying the entire project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Each commit points back to its parent. Branches point to commits.

        C1 &amp;lt;-- C2 &amp;lt;-- C3 &amp;lt;-- C4                 &amp;lt;- main
                       \
                        C5 &amp;lt;-- C6               &amp;lt;- feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see the file for yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .git/refs/heads/main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating, switching and merging
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch                       &lt;span class="c"&gt;# list branches (* marks the current one)&lt;/span&gt;
git branch feature/login         &lt;span class="c"&gt;# create a branch (doesn't switch to it)&lt;/span&gt;
git switch feature/login         &lt;span class="c"&gt;# move to that branch&lt;/span&gt;
git switch &lt;span class="nt"&gt;-c&lt;/span&gt; feature/login      &lt;span class="c"&gt;# create AND switch in one step&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;code&gt;git switch&lt;/code&gt; needs Git 2.23 or newer. Older tutorials use &lt;code&gt;git checkout&lt;/code&gt; for the same jobs.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Switched to a new branch 'feature/login'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's add a commit on the branch, then &lt;strong&gt;merge&lt;/strong&gt; it back into &lt;code&gt;main&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"login page"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; login.txt
git add login.txt
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add login page"&lt;/span&gt;

git switch main
git merge feature/login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;main&lt;/code&gt; hasn't moved since you branched, Git simply slides the &lt;code&gt;main&lt;/code&gt; pointer forward. This is called a &lt;strong&gt;fast-forward merge&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Updating a1b2c3d..9e8d7c6
Fast-forward
 login.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 login.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Before:    C1 &amp;lt;- C2 &amp;lt;- C3                      main
                           \
                            C4 &amp;lt;- C5              feature

   After a fast-forward merge (main just moves to C5):

              C1 &amp;lt;- C2 &amp;lt;- C3 &amp;lt;- C4 &amp;lt;- C5          main, feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If both branches have new commits, Git can't just slide the pointer. It creates a new &lt;strong&gt;merge commit&lt;/strong&gt; with &lt;strong&gt;two parents&lt;/strong&gt;, combining both lines of work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Merge made by the 'ort' strategy.
 login.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 login.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Older Git versions say &lt;code&gt;recursive&lt;/code&gt; instead of &lt;code&gt;ort&lt;/code&gt;.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        C1 &amp;lt;- C2 &amp;lt;- C3 &amp;lt;- C6 &amp;lt;------------ M        main (merge commit M)
                       \                  /
                        C4 &amp;lt;- C5 &amp;lt;-------+          feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once a branch is merged, you can delete it. The commits stay in history. Only the pointer goes away:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch &lt;span class="nt"&gt;-d&lt;/span&gt; feature/login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deleted branch feature/login (was 9e8d7c6).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's another way to combine work called &lt;strong&gt;rebase&lt;/strong&gt;. It replays your commits on top of another branch to make a straight line of history. It's powerful, but never rebase commits that other people already have.&lt;/p&gt;

&lt;h3&gt;
  
  
  Merge conflicts
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;merge conflict&lt;/strong&gt; happens when both branches changed the &lt;strong&gt;same lines&lt;/strong&gt; of the same file. Git can't guess which version is right, so it stops and asks you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Auto-merging greeting.txt
CONFLICT (content): Merge conflict in greeting.txt
Automatic merge failed; fix conflicts and then commit the result.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the file. Git marks the conflicting part:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD
Welcome to my app
=======
Welcome to my awesome app
&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; feature/greeting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Between &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD&lt;/code&gt; and &lt;code&gt;=======&lt;/code&gt; is &lt;strong&gt;your current branch's&lt;/strong&gt; version.&lt;/li&gt;
&lt;li&gt;Between &lt;code&gt;=======&lt;/code&gt; and &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; is the &lt;strong&gt;incoming&lt;/strong&gt; branch's version.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To resolve it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Edit the file so it contains exactly what you want, and delete the three marker lines.&lt;/li&gt;
&lt;li&gt;Stage the file: &lt;code&gt;git add greeting.txt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Finish the merge: &lt;code&gt;git commit&lt;/code&gt; (Git suggests a merge message for you).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you'd rather start over, run &lt;code&gt;git merge --abort&lt;/code&gt; to go back to how things were before the merge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pointers in Git and HEAD
&lt;/h2&gt;

&lt;p&gt;Here's a secret that makes Git much easier to understand: almost everything is a &lt;strong&gt;pointer&lt;/strong&gt; (called a &lt;strong&gt;ref&lt;/strong&gt;). A branch is a pointer to a commit. A tag is a pointer to a commit. Even the remote branch names, like &lt;code&gt;origin/main&lt;/code&gt;, are pointers that remember where the remote was last time you checked. They're all small files under &lt;code&gt;.git/refs&lt;/code&gt;. The most important pointer is &lt;strong&gt;&lt;code&gt;HEAD&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What HEAD is
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;HEAD&lt;/code&gt;&lt;/strong&gt; is a pointer that means &lt;strong&gt;"where I am right now."&lt;/strong&gt; Usually, it points to the &lt;strong&gt;current branch&lt;/strong&gt;, and that branch points to a commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   HEAD  ---&amp;gt;  main  ---&amp;gt;  C4
                            ^
                          your latest commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see it directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .git/HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ref: refs/heads/main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That file says: "HEAD points to the branch &lt;code&gt;main&lt;/code&gt;." When you make a commit, Git creates it, then moves the branch that HEAD points to. When you switch branches (&lt;code&gt;git switch feature&lt;/code&gt;), Git changes what &lt;code&gt;HEAD&lt;/code&gt; points to, and updates your working files to match.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git log --oneline --decorate&lt;/code&gt; shows where the pointers are. In the output, &lt;code&gt;(HEAD -&amp;gt; main)&lt;/code&gt; means HEAD is on main:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a1b2c3d (HEAD -&amp;gt; main, origin/main) Describe the project
3f2a9c1 Add README
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Detached HEAD
&lt;/h3&gt;

&lt;p&gt;Sometimes &lt;code&gt;HEAD&lt;/code&gt; points &lt;strong&gt;straight at a commit&lt;/strong&gt; instead of at a branch. This is called a &lt;strong&gt;detached HEAD&lt;/strong&gt;. It happens when you check out a specific commit or a tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git switch &lt;span class="nt"&gt;--detach&lt;/span&gt; 3f2a9c1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Note: switching to '3f2a9c1'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c &amp;lt;new-branch-name&amp;gt;

HEAD is now at 3f2a9c1 Add README
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Trimmed. Older Git versions use &lt;code&gt;git checkout 3f2a9c1&lt;/code&gt;.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Normal:      HEAD --&amp;gt; main --&amp;gt; C4

   Detached:    HEAD ------------&amp;gt; C2        (no branch name is attached)
                main ------------&amp;gt; C4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's fine for looking around at old code. But if you make commits while detached, &lt;strong&gt;they don't belong to any branch&lt;/strong&gt;, and when you switch away, they're easy to lose. Two fixes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To keep your work, create a branch &lt;strong&gt;before&lt;/strong&gt; you leave: &lt;code&gt;git switch -c rescue-branch&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To go back to normal, switch to a branch: &lt;code&gt;git switch main&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you ever lose commits, &lt;code&gt;git reflog&lt;/code&gt; shows the places &lt;code&gt;HEAD&lt;/code&gt; has been, and you can usually find them there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Moving relative to HEAD
&lt;/h3&gt;

&lt;p&gt;You can describe commits relative to &lt;code&gt;HEAD&lt;/code&gt;, without remembering hashes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;HEAD&lt;/code&gt; is the current commit.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HEAD~1&lt;/code&gt; (or just &lt;code&gt;HEAD~&lt;/code&gt;) is its parent, one step back.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HEAD~2&lt;/code&gt; is two steps back, and so on.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HEAD^&lt;/code&gt; also means the parent. The difference shows up only on merge commits: &lt;code&gt;HEAD^1&lt;/code&gt; is the first parent and &lt;code&gt;HEAD^2&lt;/code&gt; is the second.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git show &lt;span class="nt"&gt;--stat&lt;/span&gt; HEAD~1          &lt;span class="c"&gt;# what was in the previous commit&lt;/span&gt;
git diff HEAD~2                 &lt;span class="c"&gt;# compare now with two commits ago&lt;/span&gt;
git reset &lt;span class="nt"&gt;--soft&lt;/span&gt; HEAD~1         &lt;span class="c"&gt;# undo the last commit but keep the changes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tags
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;tag&lt;/strong&gt; is a name for &lt;strong&gt;one specific commit&lt;/strong&gt;. Unlike a branch, a tag &lt;strong&gt;never moves&lt;/strong&gt;. That makes tags perfect for marking releases, like &lt;code&gt;v1.0.0&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   C1 &amp;lt;-- C2 &amp;lt;-- C3 &amp;lt;-- C4 &amp;lt;-- C5       main keeps moving forward (now at C5)
           ^
         v1.0.0                         the tag stays on C2 forever
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Lightweight and annotated tags
&lt;/h3&gt;

&lt;p&gt;There are two kinds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;lightweight tag&lt;/strong&gt; is just a name pointing at a commit. It's a quick bookmark.&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;annotated tag&lt;/strong&gt; is a full Git object. It stores the tagger's name and email, the date and a message, and it can be signed. It's the recommended kind for real releases.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag v1.0.0                              &lt;span class="c"&gt;# lightweight&lt;/span&gt;
git tag &lt;span class="nt"&gt;-a&lt;/span&gt; v1.1.0 &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Release 1.1.0"&lt;/span&gt;        &lt;span class="c"&gt;# annotated&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;git show&lt;/code&gt; shows the extra information in an annotated tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git show v1.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tag v1.1.0
Tagger: Asha Rao &amp;lt;asha@example.com&amp;gt;
Date:   Fri Oct 23 11:00:00 2026 +0530

Release 1.1.0

commit 9e8d7c6a1b2c3d4e5f60718293a4b5c6d7e8f901
Author: Asha Rao &amp;lt;asha@example.com&amp;gt;
Date:   Fri Oct 23 10:45:00 2026 +0530

    Merge branch 'feature/login'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Trimmed, with example values.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Working with tags
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag                          &lt;span class="c"&gt;# list all tags&lt;/span&gt;
git tag &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="s2"&gt;"v1.*"&lt;/span&gt;                &lt;span class="c"&gt;# list tags that match a pattern&lt;/span&gt;
git tag &lt;span class="nt"&gt;-a&lt;/span&gt; v0.9.0 3f2a9c1 &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Beta"&lt;/span&gt;   &lt;span class="c"&gt;# tag an OLD commit&lt;/span&gt;
git push origin v1.1.0           &lt;span class="c"&gt;# upload one tag&lt;/span&gt;
git push origin &lt;span class="nt"&gt;--tags&lt;/span&gt;           &lt;span class="c"&gt;# upload all tags&lt;/span&gt;
git tag &lt;span class="nt"&gt;-d&lt;/span&gt; v1.0.0                &lt;span class="c"&gt;# delete a tag locally&lt;/span&gt;
git push origin &lt;span class="nt"&gt;--delete&lt;/span&gt; v1.0.0  &lt;span class="c"&gt;# delete a tag on the remote&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v1.0.0
v1.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important: &lt;strong&gt;&lt;code&gt;git push&lt;/code&gt; does not send tags by default.&lt;/strong&gt; You must push them yourself. Hosting sites like GitHub use tags to build their "Releases" pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Git commands with examples
&lt;/h2&gt;

&lt;p&gt;Here's a quick reference, grouped by job. Most of these you've already seen in action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Starting a repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init                              &lt;span class="c"&gt;# turn the current folder into a repository&lt;/span&gt;
git clone https://github.com/asha/my-project.git          &lt;span class="c"&gt;# copy a remote repository&lt;/span&gt;
git clone https://github.com/asha/my-project.git demo     &lt;span class="c"&gt;# ... into a folder named "demo"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cloning into 'my-project'...
remote: Enumerating objects: 12, done.
Receiving objects: 100% (12/12), done.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checking status and differences
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status            &lt;span class="c"&gt;# full status&lt;/span&gt;
git status &lt;span class="nt"&gt;-s&lt;/span&gt;         &lt;span class="c"&gt;# short status&lt;/span&gt;
git diff              &lt;span class="c"&gt;# changes you have NOT staged yet&lt;/span&gt;
git diff &lt;span class="nt"&gt;--staged&lt;/span&gt;     &lt;span class="c"&gt;# changes that ARE staged (what the next commit will contain)&lt;/span&gt;
git diff main..feature/login     &lt;span class="c"&gt;# differences between two branches&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The short status uses two letters. The first is the staging area, and the second is the working directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; M README.md
M  src/App.java
?? notes.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;M&lt;/code&gt; means modified but not staged.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;M&lt;/code&gt; means staged.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;??&lt;/code&gt; means untracked.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Staging and committing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add README.md          &lt;span class="c"&gt;# stage one file&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;                  &lt;span class="c"&gt;# stage everything in this folder and below&lt;/span&gt;
git add &lt;span class="nt"&gt;-p&lt;/span&gt;                 &lt;span class="c"&gt;# stage piece by piece, choosing each change&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Fix typo in README"&lt;/span&gt;      &lt;span class="c"&gt;# commit what is staged&lt;/span&gt;
git commit &lt;span class="nt"&gt;-am&lt;/span&gt; &lt;span class="s2"&gt;"Update docs"&lt;/span&gt;            &lt;span class="c"&gt;# stage tracked files AND commit&lt;/span&gt;
git commit &lt;span class="nt"&gt;--amend&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Better message"&lt;/span&gt;  &lt;span class="c"&gt;# replace the last commit&lt;/span&gt;
git &lt;span class="nb"&gt;rm &lt;/span&gt;old.txt             &lt;span class="c"&gt;# delete a file and stage the deletion&lt;/span&gt;
git &lt;span class="nb"&gt;mv &lt;/span&gt;old.txt new.txt     &lt;span class="c"&gt;# rename a file and stage it&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;git commit -am&lt;/code&gt; skips untracked files, so new files still need &lt;code&gt;git add&lt;/code&gt;. Use &lt;code&gt;--amend&lt;/code&gt; only on commits you haven't pushed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Viewing history
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log                     &lt;span class="c"&gt;# full history&lt;/span&gt;
git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;           &lt;span class="c"&gt;# one line per commit&lt;/span&gt;
git log &lt;span class="nt"&gt;--oneline&lt;/span&gt; &lt;span class="nt"&gt;--graph&lt;/span&gt; &lt;span class="nt"&gt;--decorate&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt;     &lt;span class="c"&gt;# a picture of all branches&lt;/span&gt;
git log &lt;span class="nt"&gt;-3&lt;/span&gt;                  &lt;span class="c"&gt;# only the last 3 commits&lt;/span&gt;
git log &lt;span class="nt"&gt;--author&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Asha"&lt;/span&gt;     &lt;span class="c"&gt;# commits by one person&lt;/span&gt;
git log &lt;span class="nt"&gt;-p&lt;/span&gt;                  &lt;span class="c"&gt;# include the changes in each commit&lt;/span&gt;
git show 3f2a9c1            &lt;span class="c"&gt;# details of one commit&lt;/span&gt;
git blame README.md         &lt;span class="c"&gt;# who last changed each line&lt;/span&gt;
git reflog                  &lt;span class="c"&gt;# where HEAD has been (a safety net)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A default &lt;code&gt;git log&lt;/code&gt; entry looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit 3f2a9c1e5d6b7a8c9d0e1f2a3b4c5d6e7f8a9b0c (HEAD -&amp;gt; main)
Author: Asha Rao &amp;lt;asha@example.com&amp;gt;
Date:   Fri Oct 23 10:15:00 2026 +0530

    Add README
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the graph view shows how branches split and join:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*   9e8d7c6 (HEAD -&amp;gt; main) Merge branch 'feature/login'
|\
| * 5d4c3b2 (feature/login) Add login page
* | a1b2c3d Describe the project
|/
* 3f2a9c1 Add README
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Branching and merging
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch                  &lt;span class="c"&gt;# list local branches&lt;/span&gt;
git branch &lt;span class="nt"&gt;-a&lt;/span&gt;               &lt;span class="c"&gt;# also list remote branches&lt;/span&gt;
git switch &lt;span class="nt"&gt;-c&lt;/span&gt; feature/x     &lt;span class="c"&gt;# create and switch to a branch&lt;/span&gt;
git switch main             &lt;span class="c"&gt;# go back to main&lt;/span&gt;
git merge feature/x         &lt;span class="c"&gt;# merge feature/x into the current branch&lt;/span&gt;
git merge &lt;span class="nt"&gt;--abort&lt;/span&gt;           &lt;span class="c"&gt;# cancel a merge that has conflicts&lt;/span&gt;
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; feature/x     &lt;span class="c"&gt;# delete a merged branch&lt;/span&gt;
git branch &lt;span class="nt"&gt;-D&lt;/span&gt; feature/x     &lt;span class="c"&gt;# force-delete (even if not merged)&lt;/span&gt;
git cherry-pick 5d4c3b2     &lt;span class="c"&gt;# copy ONE commit onto the current branch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Working with remotes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote add origin https://github.com/asha/my-project.git
git remote &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin  https://github.com/asha/my-project.git (fetch)
origin  https://github.com/asha/my-project.git (push)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enumerating objects: 6, done.
Writing objects: 100% (6/6), 512 bytes | 512.00 KiB/s, done.
To https://github.com/asha/my-project.git
 * [new branch]      main -&amp;gt; main
branch 'main' set up to track 'origin/main'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Trimmed.) The &lt;code&gt;-u&lt;/code&gt; option links your local &lt;code&gt;main&lt;/code&gt; to &lt;code&gt;origin/main&lt;/code&gt;, so from now on a plain &lt;code&gt;git push&lt;/code&gt; and &lt;code&gt;git pull&lt;/code&gt; know where to go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch               &lt;span class="c"&gt;# download new commits, but don't change your files&lt;/span&gt;
git pull                &lt;span class="c"&gt;# fetch + merge into your current branch&lt;/span&gt;
git pull &lt;span class="nt"&gt;--rebase&lt;/span&gt;       &lt;span class="c"&gt;# fetch + rebase (keeps history in a straight line)&lt;/span&gt;
git branch &lt;span class="nt"&gt;-vv&lt;/span&gt;          &lt;span class="c"&gt;# show which remote branch each local branch follows&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   git fetch  =  download what others did (your files stay untouched)
   git pull   =  git fetch  +  git merge   (your current branch is updated)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If someone pushed before you, Git refuses your push:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;To https://github.com/asha/my-project.git
 ! [rejected]        main -&amp;gt; main (fetch first)
error: failed to push some refs to 'https://github.com/asha/my-project.git'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fix is simple: run &lt;code&gt;git pull&lt;/code&gt; to get their work, then push again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Undoing things
&lt;/h3&gt;

&lt;p&gt;Git gives you several kinds of "undo", and they work at different levels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git restore README.md                 &lt;span class="c"&gt;# throw away unstaged changes in a file&lt;/span&gt;
git restore &lt;span class="nt"&gt;--staged&lt;/span&gt; README.md        &lt;span class="c"&gt;# unstage a file (changes stay in the file)&lt;/span&gt;
git commit &lt;span class="nt"&gt;--amend&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"New message"&lt;/span&gt;   &lt;span class="c"&gt;# fix the last commit (if not pushed)&lt;/span&gt;
git reset &lt;span class="nt"&gt;--soft&lt;/span&gt; HEAD~1               &lt;span class="c"&gt;# undo last commit, keep changes STAGED&lt;/span&gt;
git reset HEAD~1                      &lt;span class="c"&gt;# undo last commit, keep changes UNSTAGED&lt;/span&gt;
git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; HEAD~1               &lt;span class="c"&gt;# undo last commit, DELETE the changes&lt;/span&gt;
git revert 5d4c3b2                    &lt;span class="c"&gt;# make a NEW commit that cancels an old one&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The three &lt;code&gt;reset&lt;/code&gt; modes differ in how far they go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    HEAD moves?    staging area     working directory
   reset --soft        yes          unchanged         unchanged
   reset (mixed)       yes          reset             unchanged
   reset --hard        yes          reset             reset      (changes are LOST)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two warnings to remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git restore &amp;lt;file&amp;gt;&lt;/code&gt; and &lt;code&gt;git reset --hard&lt;/code&gt; &lt;strong&gt;destroy uncommitted work&lt;/strong&gt;, and you can't get it back.&lt;/li&gt;
&lt;li&gt;If a commit is already &lt;strong&gt;pushed and shared&lt;/strong&gt;, don't rewrite it with &lt;code&gt;reset&lt;/code&gt; or &lt;code&gt;--amend&lt;/code&gt;. Use &lt;strong&gt;&lt;code&gt;git revert&lt;/code&gt;&lt;/strong&gt; instead. It adds a new commit that undoes the old one, and keeps everyone's history intact.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Older tutorials use &lt;code&gt;git checkout -- &amp;lt;file&amp;gt;&lt;/code&gt; instead of &lt;code&gt;git restore&lt;/code&gt;.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Saving work with stash
&lt;/h3&gt;

&lt;p&gt;Sometimes you're halfway through a change and need to switch branches. &lt;strong&gt;&lt;code&gt;git stash&lt;/code&gt;&lt;/strong&gt; puts your uncommitted changes on a shelf and gives you a clean working directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Saved working directory and index state WIP on main: a1b2c3d Describe the project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stash@{0}: WIP on main: a1b2c3d Describe the project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash pop        &lt;span class="c"&gt;# bring the changes back and remove them from the shelf&lt;/span&gt;
git stash apply      &lt;span class="c"&gt;# bring them back but keep a copy on the shelf&lt;/span&gt;
git stash drop       &lt;span class="c"&gt;# throw the newest stash away&lt;/span&gt;
git stash &lt;span class="nt"&gt;-u&lt;/span&gt;         &lt;span class="c"&gt;# also stash untracked (new) files&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ignoring files with .gitignore
&lt;/h3&gt;

&lt;p&gt;Some files should never be committed: build output, editor settings, logs and secrets. Put patterns for them in a file named &lt;strong&gt;&lt;code&gt;.gitignore&lt;/code&gt;&lt;/strong&gt; at the top of your project. For a Java and Maven project, it might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;target/
*.class
.idea/
*.log
.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;target/&lt;/code&gt; ignores a whole folder (the Maven build output).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*.class&lt;/code&gt; ignores every file ending in &lt;code&gt;.class&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A line starting with &lt;code&gt;!&lt;/code&gt; makes an exception, for example &lt;code&gt;!important.log&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A line starting with &lt;code&gt;#&lt;/code&gt; is a comment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.gitignore&lt;/code&gt; only affects &lt;strong&gt;untracked&lt;/strong&gt; files. If a file is already tracked, stop tracking it with &lt;code&gt;git rm --cached &amp;lt;file&amp;gt;&lt;/code&gt;, then commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Never commit passwords, tokens or keys. Once something is in the history, removing it completely is hard, and a leaked secret should be treated as stolen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Merge or rebase?&lt;/strong&gt; Merge is safe and keeps the true history, including merge commits. Rebase gives a cleaner straight line, but rewrites commits. Use rebase only on your own, unpublished work, and merge for shared branches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;reset&lt;/code&gt; or &lt;code&gt;revert&lt;/code&gt;?&lt;/strong&gt; Use &lt;code&gt;reset&lt;/code&gt; for local commits nobody else has. Use &lt;code&gt;revert&lt;/code&gt; for anything already pushed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;fetch&lt;/code&gt; or &lt;code&gt;pull&lt;/code&gt;?&lt;/strong&gt; Use &lt;code&gt;fetch&lt;/code&gt; when you want to look before you change anything. Use &lt;code&gt;pull&lt;/code&gt; when you just want to update.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;git add .&lt;/code&gt; or &lt;code&gt;git add -p&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;git add .&lt;/code&gt; is quick, but it can sweep in files you didn't intend. &lt;code&gt;git add -p&lt;/code&gt; lets you review each change and build clean commits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lightweight or annotated tag?&lt;/strong&gt; Annotated for releases (it records who, when and why). Lightweight for personal bookmarks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS or SSH?&lt;/strong&gt; HTTPS with a token is simplest to start. SSH keys are more convenient once they're set up, because you don't type credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;stash&lt;/code&gt;, a WIP commit or a branch?&lt;/strong&gt; &lt;code&gt;stash&lt;/code&gt; is for short interruptions. For longer work, make a branch and commit to it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub, GitLab or Bitbucket?&lt;/strong&gt; Choose by what your team already uses: open-source reach (GitHub), a built-in all-in-one platform or self-hosting (GitLab), or tight Jira integration (Bitbucket).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;git switch&lt;/code&gt; and &lt;code&gt;git restore&lt;/code&gt; or &lt;code&gt;git checkout&lt;/code&gt;?&lt;/strong&gt; On a modern Git, use &lt;code&gt;switch&lt;/code&gt; and &lt;code&gt;restore&lt;/code&gt;. Each does one job, while &lt;code&gt;checkout&lt;/code&gt; does several.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Committing things that don't belong.&lt;/strong&gt; Build folders, &lt;code&gt;.class&lt;/code&gt; files, editor settings and, worst of all, secrets. Set up &lt;code&gt;.gitignore&lt;/code&gt; on day one, and if a secret was committed, change it immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Huge, vague commits.&lt;/strong&gt; "fix stuff" with 40 changed files is impossible to review or undo. Make small, focused commits with clear messages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rewriting shared history.&lt;/strong&gt; Using &lt;code&gt;--amend&lt;/code&gt;, &lt;code&gt;rebase&lt;/code&gt;, &lt;code&gt;reset --hard&lt;/code&gt; or &lt;code&gt;push --force&lt;/code&gt; on commits others already have causes painful conflicts for the whole team. Use &lt;code&gt;git revert&lt;/code&gt;, and if you must force push, use &lt;code&gt;--force-with-lease&lt;/code&gt;, which refuses to overwrite work you haven't seen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Working in a detached HEAD, then moving away.&lt;/strong&gt; The commits are on no branch and are easy to lose. Make a branch first with &lt;code&gt;git switch -c&lt;/code&gt;, and remember that &lt;code&gt;git reflog&lt;/code&gt; can usually rescue them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Panicking about merge conflicts.&lt;/strong&gt; A conflict is normal. Open the file, search for &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/code&gt;, choose what you want, remove the markers, &lt;code&gt;git add&lt;/code&gt; and commit. Use &lt;code&gt;git merge --abort&lt;/code&gt; if you want to start again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forgetting what's local.&lt;/strong&gt; A commit isn't shared until you &lt;code&gt;git push&lt;/code&gt; it, and tags aren't pushed unless you ask. If a push is rejected, &lt;code&gt;git pull&lt;/code&gt; first, then push again.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;version control system&lt;/strong&gt; records the history of your files. There are three types: &lt;strong&gt;local&lt;/strong&gt; (history on one machine), &lt;strong&gt;centralized&lt;/strong&gt; (one server, like SVN) and &lt;strong&gt;distributed&lt;/strong&gt; (every clone has the full history, like Git).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Git&lt;/strong&gt; was created by &lt;strong&gt;Linus Torvalds in 2005&lt;/strong&gt;, after the free BitKeeper arrangement for the Linux kernel ended. It's fast, distributed and built for non-linear work.&lt;/li&gt;
&lt;li&gt;Git stores &lt;strong&gt;snapshots&lt;/strong&gt;, made of &lt;strong&gt;blobs, trees, commits and tags&lt;/strong&gt;, each named by a &lt;strong&gt;hash&lt;/strong&gt;. Everything lives in the hidden &lt;strong&gt;&lt;code&gt;.git&lt;/code&gt;&lt;/strong&gt; folder.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;repository&lt;/strong&gt; can be &lt;strong&gt;local&lt;/strong&gt; or &lt;strong&gt;remote&lt;/strong&gt; (usually called &lt;code&gt;origin&lt;/code&gt;). &lt;strong&gt;GitHub, GitLab and Bitbucket&lt;/strong&gt; host remotes and add review, issues and automation. They are not the same as Git.&lt;/li&gt;
&lt;li&gt;Files move through the &lt;strong&gt;working directory&lt;/strong&gt;, the &lt;strong&gt;staging area&lt;/strong&gt; and the &lt;strong&gt;local repository&lt;/strong&gt;, using &lt;code&gt;git add&lt;/code&gt; and &lt;code&gt;git commit&lt;/code&gt;. Then &lt;code&gt;git push&lt;/code&gt; shares them.&lt;/li&gt;
&lt;li&gt;A file is &lt;strong&gt;untracked&lt;/strong&gt;, &lt;strong&gt;committed&lt;/strong&gt;, &lt;strong&gt;modified&lt;/strong&gt; or &lt;strong&gt;staged&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;branch&lt;/strong&gt; is a movable pointer to a commit. &lt;strong&gt;&lt;code&gt;HEAD&lt;/code&gt;&lt;/strong&gt; points to where you are now. Merging joins branches. Conflicts are resolved by hand.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;tag&lt;/strong&gt; is a pointer that never moves, ideal for releases. Push tags explicitly.&lt;/li&gt;
&lt;li&gt;Everyday commands: &lt;code&gt;init&lt;/code&gt;, &lt;code&gt;clone&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt;, &lt;code&gt;log&lt;/code&gt;, &lt;code&gt;diff&lt;/code&gt;, &lt;code&gt;branch&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt;, &lt;code&gt;merge&lt;/code&gt;, &lt;code&gt;fetch&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;restore&lt;/code&gt;, &lt;code&gt;reset&lt;/code&gt;, &lt;code&gt;revert&lt;/code&gt;, &lt;code&gt;stash&lt;/code&gt; and &lt;code&gt;tag&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: make a new folder, run &lt;code&gt;git init&lt;/code&gt;, and create three commits that each add or change a file. Then create a branch called &lt;code&gt;feature/greeting&lt;/code&gt;, change the same line of a file on both &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;feature/greeting&lt;/code&gt;, and merge them to cause a conflict on purpose. Resolve it, finish the merge and tag the result &lt;code&gt;v1.0.0&lt;/code&gt; with an annotated tag. Finally, create an empty repository on GitHub, add it as &lt;code&gt;origin&lt;/code&gt;, and push your branch and your tag.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, run &lt;code&gt;git log --oneline --graph --decorate --all&lt;/code&gt; to see your history as a picture. Then look inside &lt;code&gt;.git&lt;/code&gt;: run &lt;code&gt;cat .git/HEAD&lt;/code&gt;, &lt;code&gt;cat .git/refs/heads/main&lt;/code&gt; and &lt;code&gt;git cat-file -p HEAD&lt;/code&gt;, and match what you see to the diagrams in this post. If you ever get stuck on a command, &lt;code&gt;git help &amp;lt;command&amp;gt;&lt;/code&gt; (for example, &lt;code&gt;git help merge&lt;/code&gt;) opens its full manual.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

</description>
      <category>git</category>
      <category>versioncontrol</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>JUnit 5 Explained: Unit Testing, TDD and Annotations</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Thu, 22 Oct 2026 07:01:53 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/junit-5-explained-unit-testing-tdd-and-annotations-27g2</link>
      <guid>https://dev.to/mayur_bodhare/junit-5-explained-unit-testing-tdd-and-annotations-27g2</guid>
      <description>&lt;p&gt;The first time a bug reached production because of a change I made, I was told the same thing three times: "Did you test it?" I had. I had run the program, clicked around and it looked fine. But "it looked fine when I tried it" is not a test. It's a hope.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unit tests&lt;/strong&gt; turn that hope into a safety net. They're small programs that check your code for you, in milliseconds, every time you change something. In Java, the most popular tool for writing them is &lt;strong&gt;JUnit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this post, we'll look at how testing used to work, what unit testing and TDD are, how JUnit 5 differs from JUnit 4, how JUnit 5 is built, how to set it up with Maven and Surefire, and then the main assertions and annotations you'll use every day.&lt;/p&gt;

&lt;p&gt;A quick version note: JUnit's newest major version is &lt;strong&gt;JUnit 6&lt;/strong&gt; (released in September 2025). It needs Java 17, and the Jupiter API you learn here carries over to it. I'm using JUnit 5 because it still runs on older Java versions and is everywhere in existing projects. To try JUnit 6, you mostly change the version number.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Testing in the traditional SDLC&lt;/li&gt;
&lt;li&gt;Unit testing&lt;/li&gt;
&lt;li&gt;Test-driven development (TDD)&lt;/li&gt;
&lt;li&gt;JUnit 4 vs JUnit 5&lt;/li&gt;
&lt;li&gt;JUnit 5 architecture&lt;/li&gt;
&lt;li&gt;JUnit 5 in a Maven project&lt;/li&gt;
&lt;li&gt;Your first JUnit 5 test&lt;/li&gt;
&lt;li&gt;
Assertions

&lt;ul&gt;
&lt;li&gt;assertEquals and assertNotEquals&lt;/li&gt;
&lt;li&gt;assertTrue and assertFalse&lt;/li&gt;
&lt;li&gt;assertNull, assertNotNull, assertSame, assertNotSame&lt;/li&gt;
&lt;li&gt;assertArrayEquals and assertIterableEquals&lt;/li&gt;
&lt;li&gt;assertThrows and assertDoesNotThrow&lt;/li&gt;
&lt;li&gt;assertAll&lt;/li&gt;
&lt;li&gt;assertTimeout&lt;/li&gt;
&lt;li&gt;fail()&lt;/li&gt;
&lt;li&gt;Failure messages&lt;/li&gt;
&lt;li&gt;Assumptions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Annotations

&lt;ul&gt;
&lt;li&gt;@Test, @DisplayName and @Disabled&lt;/li&gt;
&lt;li&gt;@BeforeEach, @AfterEach, @BeforeAll and @AfterAll&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Test instance lifecycle (@TestInstance)&lt;/li&gt;
&lt;li&gt;More features worth knowing&lt;/li&gt;
&lt;li&gt;Which one should I use?&lt;/li&gt;
&lt;li&gt;Common mistakes&lt;/li&gt;
&lt;li&gt;Quick recap&lt;/li&gt;
&lt;li&gt;Try it yourself&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testing in the traditional SDLC
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SDLC&lt;/strong&gt; stands for Software Development Life Cycle: the steps a team follows to build software. In the traditional style, often called the &lt;strong&gt;waterfall&lt;/strong&gt; model, each step happens &lt;strong&gt;after&lt;/strong&gt; the previous one is finished:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Requirements --&amp;gt; Design --&amp;gt; Coding --&amp;gt; TESTING --&amp;gt; Release --&amp;gt; Maintenance
                                            ^
                         a separate testing (QA) team starts here,
                         only after ALL the code is "done"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Developers write all the code. Then they hand it over to a &lt;strong&gt;separate testing team&lt;/strong&gt;, who run it, find problems and send them back. It's sometimes called "throwing the code over the wall."&lt;/p&gt;

&lt;p&gt;This has real problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Feedback comes late.&lt;/strong&gt; A bug written in week 2 might be found in week 12. By then, the developer has forgotten the details of that code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixes are expensive.&lt;/strong&gt; The later a bug is found, the more code is built on top of it, and the more places need to change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handoffs cause friction.&lt;/strong&gt; Developers wait for test results. Testers wait for builds. Each side may blame the other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repeat work is manual.&lt;/strong&gt; After every fix, someone must re-test the old features by hand to make sure nothing broke. This is called &lt;strong&gt;regression testing&lt;/strong&gt;, and by hand it's slow and boring.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Today, most teams work differently. &lt;strong&gt;Developers test their own code as they write it&lt;/strong&gt;, with automated tests that run on every change. A dedicated QA role still matters (for exploring the product, checking the whole system and thinking like a user), but it no longer carries the whole burden, and it doesn't wait until the end.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   MODERN:   write code + write tests --&amp;gt; run tests automatically on every commit
                  |                                  |
                  +---- fast feedback, within minutes ----+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Unit testing
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;unit test&lt;/strong&gt; checks one small piece of code, usually a single method or class, &lt;strong&gt;in isolation&lt;/strong&gt;. It's written by the developer, in code, and it runs automatically. A unit test answers one question: "Given this input, does this method give the output I expect?"&lt;/p&gt;

&lt;h3&gt;
  
  
  Why developers write them
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bugs are caught early&lt;/strong&gt;, while the code is still fresh in your mind.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refactoring becomes safe.&lt;/strong&gt; You can improve the code and instantly know if you broke something.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They work as living documentation.&lt;/strong&gt; A test shows exactly how a method is supposed to behave.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regression testing becomes free.&lt;/strong&gt; The whole suite runs in seconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They give confidence.&lt;/strong&gt; You can change code without fear.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What makes a good unit test?
&lt;/h3&gt;

&lt;p&gt;A handy memory trick is &lt;strong&gt;FIRST&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;F&lt;/strong&gt;ast: a test runs in milliseconds, so you can run thousands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I&lt;/strong&gt;ndependent: no test depends on another test or on the order.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;R&lt;/strong&gt;epeatable: it gives the same result every time, on any machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S&lt;/strong&gt;elf-validating: it passes or fails by itself, with no human checking the output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;T&lt;/strong&gt;imely: written at the right time, ideally right alongside the code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Arrange-Act-Assert pattern
&lt;/h3&gt;

&lt;p&gt;Most tests follow three steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addsTwoNumbers&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;      &lt;span class="c1"&gt;// Arrange: set things up&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;             &lt;span class="c1"&gt;// Act: do the thing&lt;/span&gt;

    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;                 &lt;span class="c1"&gt;// Assert: check the result&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The test pyramid
&lt;/h3&gt;

&lt;p&gt;Unit tests aren't the only kind. A healthy project has many cheap tests at the bottom and few expensive ones at the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             /\
            /  \         END-TO-END tests: few, slow, test the whole app
           /----\
          /      \       INTEGRATION tests: some, test parts working together
         /--------\
        /          \     UNIT tests: many, very fast, test small pieces alone
       /____________\
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This post is about the bottom layer: unit tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test-driven development (TDD)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TDD&lt;/strong&gt; flips the usual order. Instead of writing code and then tests, you write the &lt;strong&gt;test first&lt;/strong&gt;, watch it fail, and only then write the code to make it pass. It follows a short loop called &lt;strong&gt;Red, Green, Refactor&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        +------------------------------------+
        |                                    |
        v                                    |
  1. RED      write a small test that FAILS (the code doesn't exist yet)
        |
        v
  2. GREEN    write the SIMPLEST code that makes the test pass
        |
        v
  3. REFACTOR clean up the code, tests stay green
        |
        +------------------------------------&amp;gt; repeat with the next small test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's try it. The rule we want: orders of 1000 or more get 10% off, smaller orders get no discount, and negative amounts are invalid.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 (red).&lt;/strong&gt; Write the first test before the class exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DiscountCalculatorTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;noDiscountBelow1000&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DiscountCalculator&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;applyDiscount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It doesn't even compile yet (&lt;code&gt;cannot find symbol: class DiscountCalculator&lt;/code&gt;). That counts as red. Now write the simplest code that passes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DiscountCalculator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;applyDiscount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Green.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 (red).&lt;/strong&gt; Add the next test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;tenPercentOffAt1000&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DiscountCalculator&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;applyDiscount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ERROR] DiscountCalculatorTest.tenPercentOffAt1000 expected: &amp;lt;900&amp;gt; but was: &amp;lt;1000&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Red. Now make it pass:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;applyDiscount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Green.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 (red).&lt;/strong&gt; Negative amounts should fail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;rejectsNegativeAmounts&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assertThrows&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DiscountCalculator&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;applyDiscount&lt;/span&gt;&lt;span class="o"&gt;(-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ERROR] Expected java.lang.IllegalArgumentException to be thrown, but nothing was thrown.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make it pass, then &lt;strong&gt;refactor&lt;/strong&gt; the magic numbers into constants. After the cleanup, all three tests still pass, which proves the refactoring didn't break anything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DiscountCalculator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;THRESHOLD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;PERCENT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;applyDiscount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Amount cannot be negative"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="no"&gt;THRESHOLD&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;PERCENT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TDD's benefits: you only write the code that's needed, every feature has a test from the start, and the code tends to be easier to test (and often simpler) because you thought about how it would be used first.&lt;/p&gt;

&lt;h2&gt;
  
  
  JUnit 4 vs JUnit 5
&lt;/h2&gt;

&lt;p&gt;JUnit 4 served Java for over a decade. &lt;strong&gt;JUnit 5&lt;/strong&gt; (also called &lt;strong&gt;Jupiter&lt;/strong&gt;, after the name of its new programming model) was a complete rewrite. The main reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JUnit 4 was one big jar, hard to extend, and it couldn't use modern Java features.&lt;/li&gt;
&lt;li&gt;Its extension tools (&lt;code&gt;@RunWith&lt;/code&gt; and &lt;code&gt;@Rule&lt;/code&gt;) were awkward, and you couldn't combine several runners.&lt;/li&gt;
&lt;li&gt;Tools like IDEs had to depend on its internal classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  No backward compatibility
&lt;/h3&gt;

&lt;p&gt;JUnit 5 is &lt;strong&gt;not backward compatible&lt;/strong&gt; with JUnit 4. It uses &lt;strong&gt;new packages and new annotations&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JUnit 4: &lt;code&gt;org.junit.Test&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;JUnit 5: &lt;code&gt;org.junit.jupiter.api.Test&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A test class written with JUnit 4 annotations &lt;strong&gt;won't run on the Jupiter engine&lt;/strong&gt;, and the other way around. They're simply different APIs.&lt;/p&gt;

&lt;p&gt;The saving grace is the &lt;strong&gt;Vintage engine&lt;/strong&gt; (we'll meet it in the architecture section). It lets the new platform &lt;strong&gt;run your old JUnit 4 tests&lt;/strong&gt;, so you can migrate gradually, with old and new tests living side by side.&lt;/p&gt;

&lt;h3&gt;
  
  
  The same test, written both ways
&lt;/h3&gt;

&lt;p&gt;JUnit 4:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Before&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Before&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;calc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ArithmeticException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;divideByZero&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;divide&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JUnit 5:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jupiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assertions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertThrows&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.BeforeEach&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@BeforeEach&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;calc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;divideByZero&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertThrows&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ArithmeticException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;divide&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that in JUnit 5, the class and methods don't need to be &lt;code&gt;public&lt;/code&gt;. Package-private is fine.&lt;/p&gt;

&lt;h3&gt;
  
  
  The renamed pieces
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  JUNIT 4                         JUNIT 5
  org.junit.Test                  org.junit.jupiter.api.Test
  @Before                         @BeforeEach
  @After                          @AfterEach
  @BeforeClass                    @BeforeAll
  @AfterClass                     @AfterAll
  @Ignore                         @Disabled
  @Category                       @Tag
  @RunWith / @Rule                @ExtendWith  (the extension model)
  @Test(expected = X.class)       assertThrows(X.class, ...)
  @Test(timeout = 500)            @Timeout  or  assertTimeout(...)
  Assert  (the class)             Assertions  (the class)
  assertEquals(msg, exp, act)     assertEquals(exp, act, msg)   &amp;lt;- message moved to the END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last row is a classic trap. In JUnit 4, the optional failure message came &lt;strong&gt;first&lt;/strong&gt;. In JUnit 5, it comes &lt;strong&gt;last&lt;/strong&gt;. If you migrate carelessly, your code may still compile (when everything is a &lt;code&gt;String&lt;/code&gt;), but behave confusingly.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's new in JUnit 5
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@DisplayName&lt;/code&gt;: readable names with spaces and symbols.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assertAll&lt;/code&gt;: check several things and see &lt;strong&gt;all&lt;/strong&gt; failures at once.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assertThrows&lt;/code&gt;: with lambdas, replaces &lt;code&gt;@Test(expected=...)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Nested&lt;/code&gt;: group tests into inner classes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@ParameterizedTest&lt;/code&gt;: one test, many inputs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@RepeatedTest&lt;/code&gt;, &lt;code&gt;@Tag&lt;/code&gt;, &lt;code&gt;@Timeout&lt;/code&gt;, &lt;code&gt;@TempDir&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Dynamic tests (&lt;code&gt;@TestFactory&lt;/code&gt;): create tests at run time.&lt;/li&gt;
&lt;li&gt;Test classes and methods can be package-private.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency injection&lt;/strong&gt; for test constructors and methods, through extensions.&lt;/li&gt;
&lt;li&gt;A real &lt;strong&gt;extension model&lt;/strong&gt; that replaces runners and rules.&lt;/li&gt;
&lt;li&gt;It needs only Java 8 (JUnit 6 needs Java 17).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What changed in JUnit 6
&lt;/h3&gt;

&lt;p&gt;Going from JUnit 5 to 6 is much gentler than going from 4 to 5. The &lt;code&gt;org.junit.jupiter.api&lt;/code&gt; package and the annotations stay, so most JUnit 5 tests compile and run unchanged. The main changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Java 17 is the minimum&lt;/strong&gt; (JUnit 5 needed only Java 8). Kotlin projects need Kotlin 2.2 or newer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One version number for everything.&lt;/strong&gt; In JUnit 5, the versions didn't match: Jupiter and Vintage were &lt;code&gt;5.x&lt;/code&gt;, but the Platform was &lt;code&gt;1.x&lt;/code&gt; (for example, Platform 1.14 went with Jupiter 5.14). In JUnit 6, the &lt;strong&gt;Platform, Jupiter and Vintage all share the same version&lt;/strong&gt;, like &lt;code&gt;6.1.0&lt;/code&gt;. That makes dependency management much simpler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kotlin coroutine support.&lt;/strong&gt; Kotlin tests can use &lt;code&gt;suspend&lt;/code&gt; functions directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A cancellation API&lt;/strong&gt; in the Platform, so a running test run can be stopped early.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean-up of old modules.&lt;/strong&gt; &lt;code&gt;junit-platform-runner&lt;/code&gt; and &lt;code&gt;junit-platform-jfr&lt;/code&gt; were removed, and &lt;code&gt;junit-jupiter-migrationsupport&lt;/code&gt; (a helper that let some JUnit 4 rules work inside Jupiter tests) is deprecated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard Java rules&lt;/strong&gt; are now followed for which fields and methods are visible or overridden.&lt;/li&gt;
&lt;li&gt;If you use &lt;code&gt;@CsvSource&lt;/code&gt; with complex or unusual CSV data, double-check those tests after upgrading.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To upgrade from JUnit 5, the usual steps are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure your project builds on &lt;strong&gt;Java 17 or newer&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Change the JUnit version to a 6.x version (a BOM makes this a one-line change).&lt;/li&gt;
&lt;li&gt;Read the official &lt;strong&gt;Migration Guide&lt;/strong&gt; on the JUnit site.&lt;/li&gt;
&lt;li&gt;Move off anything that was removed or deprecated.&lt;/li&gt;
&lt;li&gt;Run your tests.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  JUnit 5 architecture
&lt;/h2&gt;

&lt;p&gt;JUnit 5 isn't one jar. It's a set of three parts, each with its own job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  JUnit 5  =  JUnit PLATFORM  +  JUnit JUPITER  +  JUnit VINTAGE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. JUnit Platform
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;foundation&lt;/strong&gt;. It does two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It defines how test frameworks plug in, through the &lt;strong&gt;TestEngine API&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It provides the &lt;strong&gt;Launcher&lt;/strong&gt;, which finds tests and starts them. Build tools and IDEs call this Launcher.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. JUnit Jupiter
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;new programming model&lt;/strong&gt; (the annotations and assertions you write) &lt;strong&gt;and&lt;/strong&gt; the engine that runs them. When you write &lt;code&gt;@Test&lt;/code&gt; from &lt;code&gt;org.junit.jupiter.api&lt;/code&gt;, you're using Jupiter. It also contains the &lt;strong&gt;extension model&lt;/strong&gt; for adding custom behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. JUnit Vintage
&lt;/h3&gt;

&lt;p&gt;An &lt;strong&gt;engine&lt;/strong&gt; that runs old &lt;strong&gt;JUnit 3 and JUnit 4&lt;/strong&gt; tests on the new platform. It's what makes gradual migration possible.&lt;/p&gt;

&lt;p&gt;Here's the whole picture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    IDEs (IntelliJ IDEA, Eclipse, VS Code)       Build tools (Maven Surefire, Gradle)
                        \                               /
                         v                             v
  +-------------------------------------------------------------------------+
  |                          JUNIT PLATFORM                                  |
  |         Launcher API (finds and starts tests)  +  TestEngine API         |
  +-------------------------------------------------------------------------+
             |                       |                        |
             v                       v                        v
      JUnit Jupiter            JUnit Vintage           Third-party engines
   (JUnit 5 tests and        (runs JUnit 3/4         (Spock, Cucumber, TestNG...)
    extension model)          tests)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why this design is smart
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;IDEs and build tools talk only to the Platform's Launcher&lt;/strong&gt;, not to any particular test framework. When IntelliJ IDEA shows green and red bars, or Maven runs your tests, they ask the Launcher to discover and run tests, and the Launcher asks each available engine to do its part. Because of this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding a new test framework doesn't require changing every IDE and build tool. It just needs a new engine.&lt;/li&gt;
&lt;li&gt;You can run JUnit 5 and JUnit 4 tests in the same project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What happens when a test runs (behind the scenes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Surefire or IDE
       |
       v
  Launcher --&amp;gt; Jupiter engine: scans for classes with @Test methods (using reflection)
                     |
                     |  for EACH test method:
                     |     1. create a NEW instance of the test class
                     |     2. run @BeforeEach methods
                     |     3. run the @Test method
                     |     4. run @AfterEach methods
                     |
                     v
             report PASS / FAIL / SKIPPED back up to the Launcher --&amp;gt; shown in the IDE or Maven
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The extension model
&lt;/h3&gt;

&lt;p&gt;In JUnit 4, you extended behavior with &lt;code&gt;@RunWith&lt;/code&gt; (only one allowed per class) and &lt;code&gt;@Rule&lt;/code&gt;. In Jupiter, there's one concept: the &lt;strong&gt;extension&lt;/strong&gt;. You add it with &lt;code&gt;@ExtendWith&lt;/code&gt;, and you can add &lt;strong&gt;many&lt;/strong&gt;. Libraries like Mockito and Spring plug in this way. We'll write a tiny one later.&lt;/p&gt;

&lt;h2&gt;
  
  
  JUnit 5 in a Maven project
&lt;/h2&gt;

&lt;p&gt;You need two things in your &lt;code&gt;pom.xml&lt;/code&gt;: the &lt;strong&gt;JUnit dependency&lt;/strong&gt; and a &lt;strong&gt;recent Surefire plugin&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.release&amp;gt;&lt;/span&gt;17&lt;span class="nt"&gt;&amp;lt;/maven.compiler.release&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;junit.version&amp;gt;&lt;/span&gt;5.14.3&lt;span class="nt"&gt;&amp;lt;/junit.version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.junit.jupiter&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit-jupiter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;${junit.version}&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-surefire-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.5.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What each part does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;junit-jupiter&lt;/code&gt;&lt;/strong&gt; is a convenient "aggregate" dependency. It brings in three libraries at once: &lt;code&gt;junit-jupiter-api&lt;/code&gt; (what you write tests with), &lt;code&gt;junit-jupiter-params&lt;/code&gt; (parameterized tests) and &lt;code&gt;junit-jupiter-engine&lt;/code&gt; (what runs them).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;/code&gt;&lt;/strong&gt; means the library is used only for testing, and it's not packaged into your final JAR.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Surefire&lt;/strong&gt; is the Maven plugin that runs your unit tests during the &lt;code&gt;test&lt;/code&gt; phase. JUnit 5 needs Surefire &lt;strong&gt;version 2.22.0 or newer&lt;/strong&gt;, and I pin a recent one so builds are repeatable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;To use JUnit 6 instead,&lt;/strong&gt; change &lt;code&gt;junit.version&lt;/code&gt; to a 6.x version and make sure you use Java 17 or newer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;To keep running old JUnit 4 tests,&lt;/strong&gt; add &lt;code&gt;junit-vintage-engine&lt;/code&gt; as another test dependency.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Surefire finds your tests
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Test code goes in &lt;strong&gt;&lt;code&gt;src/test/java&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;By default, Surefire runs classes named &lt;code&gt;*Test&lt;/code&gt;, &lt;code&gt;Test*&lt;/code&gt;, &lt;code&gt;*Tests&lt;/code&gt; or &lt;code&gt;*TestCase&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When Surefire sees the Jupiter engine on the test classpath, it switches to its &lt;strong&gt;JUnit Platform provider&lt;/strong&gt;, which uses the Launcher from the architecture section.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run your tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can run a single class or method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-Dtest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;CalculatorTest
mvn &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-Dtest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;CalculatorTest#addsTwoNumbers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A trimmed result looks like this (numbers and times will differ):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.example.CalculatorTest
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Detailed reports are saved in &lt;code&gt;target/surefire-reports&lt;/code&gt;. Note the difference between two counts: a &lt;strong&gt;Failure&lt;/strong&gt; means an assertion didn't hold, and an &lt;strong&gt;Error&lt;/strong&gt; means an unexpected exception happened.&lt;/p&gt;

&lt;p&gt;(Surefire runs unit tests. For slower integration tests, Maven teams usually use the &lt;strong&gt;Failsafe&lt;/strong&gt; plugin, with files named &lt;code&gt;*IT&lt;/code&gt;.)&lt;/p&gt;

&lt;h3&gt;
  
  
  A quick note for Gradle users
&lt;/h3&gt;

&lt;p&gt;In Gradle, add the same dependency under &lt;code&gt;testImplementation&lt;/code&gt;, and turn on JUnit Platform in the test task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;useJUnitPlatform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Your first JUnit 5 test
&lt;/h2&gt;

&lt;p&gt;Here's the class we'll test throughout the rest of the post:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isEven&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And its test, in &lt;code&gt;src/test/java/com/example/CalculatorTest.java&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jupiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assertions&lt;/span&gt;&lt;span class="o"&gt;.*;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addsTwoNumbers&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things to notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@Test&lt;/code&gt; marks a method as a test.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;import static ...Assertions.*&lt;/code&gt; line lets us write &lt;code&gt;assertEquals(...)&lt;/code&gt; without the class name.&lt;/li&gt;
&lt;li&gt;The class and method are package-private. No &lt;code&gt;public&lt;/code&gt; needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a test fails, the report tells you exactly what happened. If we wrote &lt;code&gt;assertEquals(6, calc.add(2, 3))&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ERROR] Failures:
[ERROR]   CalculatorTest.addsTwoNumbers:15 expected: &amp;lt;6&amp;gt; but was: &amp;lt;5&amp;gt;
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Assertions
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;assertion&lt;/strong&gt; is a check inside a test. If it holds, the test continues. If it doesn't, the test fails right there.&lt;/p&gt;

&lt;p&gt;In JUnit 5, all the assertions are &lt;code&gt;static&lt;/code&gt; methods of one class: &lt;strong&gt;&lt;code&gt;org.junit.jupiter.api.Assertions&lt;/code&gt;&lt;/strong&gt;. (Careful: in JUnit 4, the class was called &lt;code&gt;Assert&lt;/code&gt;, singular. In JUnit 5 it's &lt;code&gt;Assertions&lt;/code&gt;, plural.)&lt;/p&gt;

&lt;h3&gt;
  
  
  assertEquals and assertNotEquals
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;assertEquals(expected, actual)&lt;/code&gt; passes when the two values are equal. Always put the &lt;strong&gt;expected&lt;/strong&gt; value first, because the failure message uses that order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;equalityChecks&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;assertNotEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Java"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ja"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"va"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For &lt;code&gt;double&lt;/code&gt; and &lt;code&gt;float&lt;/code&gt;, you must give a &lt;strong&gt;tolerance&lt;/strong&gt; (called a delta), because of rounding errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doublesNeedADelta&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0001&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// passes&lt;/span&gt;
    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;           &lt;span class="c1"&gt;// FAILS&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expected: &amp;lt;0.3&amp;gt; but was: &amp;lt;0.30000000000000004&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;0.1 + 0.2&lt;/code&gt; isn't exactly &lt;code&gt;0.3&lt;/code&gt; in floating-point math. The delta says "close enough is fine."&lt;/p&gt;

&lt;p&gt;For objects, &lt;code&gt;assertEquals&lt;/code&gt; uses the object's &lt;code&gt;.equals()&lt;/code&gt; method.&lt;/p&gt;

&lt;h3&gt;
  
  
  assertTrue and assertFalse
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;booleanChecks&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEven&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;assertFalse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEven&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use these when the thing you're checking is naturally a yes/no. If you're comparing two values, prefer &lt;code&gt;assertEquals&lt;/code&gt;, because its failure message shows both values.&lt;/p&gt;

&lt;h3&gt;
  
  
  assertNull, assertNotNull, assertSame, assertNotSame
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;nullAndSameChecks&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;assertNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"missing"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"k"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"v"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;assertNotNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"k"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hi"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hi"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// same text&lt;/span&gt;
    &lt;span class="n"&gt;assertNotSame&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// but two different objects&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;assertSame&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;          &lt;span class="c1"&gt;// exactly the same object&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;assertEquals&lt;/code&gt; asks "are they equal?" (like &lt;code&gt;.equals()&lt;/code&gt;). &lt;code&gt;assertSame&lt;/code&gt; asks "are they the very same object?" (like &lt;code&gt;==&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  assertArrayEquals and assertIterableEquals
&lt;/h3&gt;

&lt;p&gt;Arrays don't override &lt;code&gt;equals&lt;/code&gt;, so &lt;code&gt;assertEquals&lt;/code&gt; compares their &lt;strong&gt;references&lt;/strong&gt;, not their contents. Use &lt;code&gt;assertArrayEquals&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;arrayChecks&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt;

    &lt;span class="n"&gt;assertArrayEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// passes: compares the contents&lt;/span&gt;
    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actual&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;          &lt;span class="c1"&gt;// FAILS: two different array objects&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expected: &amp;lt;[I@6d06d69c&amp;gt; but was: &amp;lt;[I@7852e922&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For collections, &lt;code&gt;assertIterableEquals&lt;/code&gt; compares the items one by one, in order, even if the two lists are different types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;assertIterableEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's also &lt;code&gt;assertLinesMatch&lt;/code&gt; for comparing lists of text lines.&lt;/p&gt;

&lt;h3&gt;
  
  
  assertThrows and assertDoesNotThrow
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;assertThrows&lt;/code&gt; checks that some code throws a specific exception. It takes the exception class and a &lt;strong&gt;lambda&lt;/strong&gt; (the code to run). It also &lt;strong&gt;returns&lt;/strong&gt; the exception, so you can inspect it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;divisionByZeroThrows&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ArithmeticException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;assertThrows&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;ArithmeticException&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;divide&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/ by zero"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the replacement for JUnit 4's &lt;code&gt;@Test(expected = ...)&lt;/code&gt;, and it's better, because it checks that exactly &lt;strong&gt;this line&lt;/strong&gt; throws, not just any line in the method.&lt;/p&gt;

&lt;p&gt;Related methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;assertThrowsExactly(X.class, ...)&lt;/code&gt; requires the exact type. (&lt;code&gt;assertThrows&lt;/code&gt; also accepts a subclass.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assertDoesNotThrow(() -&amp;gt; calc.divide(10, 2))&lt;/code&gt; checks that nothing is thrown.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  assertAll
&lt;/h3&gt;

&lt;p&gt;Normally, the first failed assertion &lt;strong&gt;stops&lt;/strong&gt; the test, so you only see one problem at a time. &lt;code&gt;assertAll&lt;/code&gt; runs a group of checks and reports &lt;strong&gt;all&lt;/strong&gt; the failures together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;groupedChecks&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Asha Rao"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;assertAll&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name checks"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt;
        &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;endsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sharma"&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt;
        &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;org.opentest4j.MultipleFailuresError: name checks (2 failures)
   org.opentest4j.AssertionFailedError: expected: &amp;lt;true&amp;gt; but was: &amp;lt;false&amp;gt;
   org.opentest4j.AssertionFailedError: expected: &amp;lt;true&amp;gt; but was: &amp;lt;false&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two checks failed, and both were reported in a single run. It's useful when checking several fields of one object.&lt;/p&gt;

&lt;h3&gt;
  
  
  assertTimeout
&lt;/h3&gt;

&lt;p&gt;Checks that code finishes within a time limit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;finishesQuickly&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assertTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofMillis&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;assertTimeout&lt;/code&gt; waits for the code to finish, then fails if it took too long.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assertTimeoutPreemptively&lt;/code&gt; runs the code in &lt;strong&gt;another thread&lt;/strong&gt; and stops it as soon as the time is up. Use it with care, because things tied to the original thread (like some transactions) may not work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also put &lt;code&gt;@Timeout&lt;/code&gt; on a test method (see the annotations part).&lt;/p&gt;

&lt;h3&gt;
  
  
  fail()
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;fail()&lt;/code&gt; makes a test fail on purpose. It's handy for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a placeholder for a test you haven't written yet,&lt;/li&gt;
&lt;li&gt;a line that should never be reached.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;notWrittenYet&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TODO: write this test"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;org.opentest4j.AssertionFailedError: TODO: write this test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Failure messages
&lt;/h3&gt;

&lt;p&gt;Every assertion accepts an optional message as the &lt;strong&gt;last&lt;/strong&gt; argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"adding 2 and 2"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;adding 2 and 2 ==&amp;gt; expected: &amp;lt;5&amp;gt; but was: &amp;lt;4&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If building the message is expensive, pass a lambda. It's only evaluated when the assertion fails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEven&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"Expected an even number but got "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Assumptions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Assumptions&lt;/strong&gt; are different from assertions. If an assumption is false, the test is &lt;strong&gt;aborted (skipped)&lt;/strong&gt;, not failed. Use them when a test only makes sense in certain conditions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jupiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assumptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assumeTrue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onlyOnCiServer&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assumeTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CI"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ENV"&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt; &lt;span class="s"&gt;"Runs only on the CI server"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// the rest of the test runs only if the assumption holds&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the Surefire summary, this shows up as &lt;code&gt;Skipped&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Annotations
&lt;/h2&gt;

&lt;p&gt;Annotations tell JUnit what each method is for. Here are the core ones in one place:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@Test&lt;/code&gt;: this method is a test.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@DisplayName&lt;/code&gt;: a readable name for the test.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Disabled&lt;/code&gt;: skip this test.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@BeforeEach&lt;/code&gt;: run before &lt;strong&gt;each&lt;/strong&gt; test.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@AfterEach&lt;/code&gt;: run after &lt;strong&gt;each&lt;/strong&gt; test.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@BeforeAll&lt;/code&gt;: run &lt;strong&gt;once&lt;/strong&gt; before all the tests in the class.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@AfterAll&lt;/code&gt;: run &lt;strong&gt;once&lt;/strong&gt; after all the tests in the class.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@TestInstance&lt;/code&gt;: control how test class objects are created.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;a class="mentioned-user" href="https://dev.to/test"&gt;@test&lt;/a&gt;, @DisplayName and @Disabled
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="nd"&gt;@DisplayName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2 + 3 = 5"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addsTwoNumbers&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="nd"&gt;@Disabled&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bug #123: not fixed yet"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;brokenForNow&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Should not run"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@DisplayName&lt;/code&gt; shows a friendly name in IDEs and reports, with spaces and symbols if you like.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Disabled&lt;/code&gt; skips the test. Always give a &lt;strong&gt;reason&lt;/strong&gt;, so nobody forgets why it's off. It appears as &lt;code&gt;Skipped&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  @BeforeEach, @AfterEach, @BeforeAll and @AfterAll
&lt;/h3&gt;

&lt;p&gt;These are &lt;strong&gt;lifecycle methods&lt;/strong&gt;: they run at set moments around your tests. Use them for setup and cleanup. Let's print messages to see the order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LifecycleTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@BeforeAll&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;beforeAll&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"beforeAll"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@BeforeEach&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"  beforeEach"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testA&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"    testA"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testB&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"    testB"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@AfterEach&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;afterEach&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"  afterEach"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@AfterAll&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;afterAll&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"afterAll"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output (&lt;code&gt;testA&lt;/code&gt; and &lt;code&gt;testB&lt;/code&gt; may swap places):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;beforeAll
  beforeEach
    testA
  afterEach
  beforeEach
    testB
  afterEach
afterAll
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the timeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  @BeforeAll                    &amp;lt;- once, at the start
     @BeforeEach  testA  @AfterEach
     @BeforeEach  testB  @AfterEach
  @AfterAll                     &amp;lt;- once, at the end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@BeforeEach&lt;/code&gt; and &lt;code&gt;@AfterEach&lt;/code&gt; run around &lt;strong&gt;every&lt;/strong&gt; test. They're the right place to create fresh objects (like a new &lt;code&gt;Calculator&lt;/code&gt;) so tests don't affect each other.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@BeforeAll&lt;/code&gt; and &lt;code&gt;@AfterAll&lt;/code&gt; run &lt;strong&gt;once&lt;/strong&gt; per class. They're for expensive setup, such as starting a test database.&lt;/li&gt;
&lt;li&gt;By default, &lt;code&gt;@BeforeAll&lt;/code&gt; and &lt;code&gt;@AfterAll&lt;/code&gt; methods must be &lt;strong&gt;&lt;code&gt;static&lt;/code&gt;&lt;/strong&gt;. If they aren't, you get:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JUnit Jupiter @BeforeAll method 'beforeAll' must be static unless the test class is annotated with @TestInstance(Lifecycle.PER_CLASS).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That error message points to our next topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test instance lifecycle (@TestInstance)
&lt;/h2&gt;

&lt;p&gt;By default, JUnit creates a &lt;strong&gt;brand-new object of your test class for every single test method.&lt;/strong&gt; This is the default setting, called &lt;code&gt;PER_METHOD&lt;/code&gt;. It exists so that tests can't affect each other through fields. Watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PerMethodTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"counter = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;second&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"counter = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;counter = 1
counter = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both tests print 1, because each test got its own fresh object with &lt;code&gt;counter&lt;/code&gt; starting at 0.&lt;/p&gt;

&lt;p&gt;You can change this with &lt;strong&gt;&lt;code&gt;@TestInstance&lt;/code&gt;&lt;/strong&gt;, which takes one of two options from the &lt;code&gt;TestInstance.Lifecycle&lt;/code&gt; enum:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PER_METHOD&lt;/code&gt;&lt;/strong&gt; (the default): a new instance for each test method.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PER_CLASS&lt;/code&gt;&lt;/strong&gt;: &lt;strong&gt;one instance&lt;/strong&gt; shared by all the test methods in the class.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@TestInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TestInstance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Lifecycle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PER_CLASS&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PerClassTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"counter = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;second&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"counter = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output (the order of the two tests can change, but the counts keep rising):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;counter = 1
counter = 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the one object is shared, so &lt;code&gt;counter&lt;/code&gt; carries over. Here are the two modes side by side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  PER_METHOD (default)                       PER_CLASS

  @BeforeAll (static)                        @BeforeAll (can be non-static)
    new instance #1 -&amp;gt; testA                   ONE instance -&amp;gt; testA
    new instance #2 -&amp;gt; testB                                 -&amp;gt; testB
  @AfterAll (static)                         @AfterAll (can be non-static)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When should you use &lt;code&gt;PER_CLASS&lt;/code&gt;?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you want &lt;strong&gt;&lt;code&gt;@BeforeAll&lt;/code&gt; and &lt;code&gt;@AfterAll&lt;/code&gt; to be non-static&lt;/strong&gt;, so they can use instance fields.&lt;/li&gt;
&lt;li&gt;When you have &lt;strong&gt;expensive setup&lt;/strong&gt; you want to share, and you accept the risk of shared state.&lt;/li&gt;
&lt;li&gt;When you want to write ordered or dependent steps (though independent tests are usually better).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cost is that tests can now affect each other through the shared fields, so the &lt;strong&gt;independent&lt;/strong&gt; rule of FIRST is easier to break. If you use it, reset the state in &lt;code&gt;@BeforeEach&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  More features worth knowing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Parameterized tests
&lt;/h3&gt;

&lt;p&gt;Instead of copying a test with different inputs, write it once and feed it many values. (It uses the &lt;code&gt;junit-jupiter-params&lt;/code&gt; library, which is included in &lt;code&gt;junit-jupiter&lt;/code&gt;.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ParameterizedTest&lt;/span&gt;
&lt;span class="nd"&gt;@ValueSource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;evenNumbersAreEven&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEven&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ParameterizedTest&lt;/span&gt;
&lt;span class="nd"&gt;@CsvSource&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"1, 2, 3"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"5, 5, 10"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"-1, 1, 0"&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addsManyPairs&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first test runs &lt;strong&gt;4 times&lt;/strong&gt;, and the second &lt;strong&gt;3 times&lt;/strong&gt;. Each run is reported separately, so you see exactly which input failed. You can also use &lt;code&gt;@MethodSource&lt;/code&gt; to feed data from a method.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nested tests
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;@Nested&lt;/code&gt; lets you group tests into inner classes, which is nice for describing different situations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ListTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Nested&lt;/span&gt;
    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WhenEmpty&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;@BeforeEach&lt;/span&gt;
        &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nd"&gt;@Test&lt;/span&gt;
        &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Nested&lt;/span&gt;
    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WhenNotEmpty&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;@BeforeEach&lt;/span&gt;
        &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nd"&gt;@Test&lt;/span&gt;
        &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;hasOneItem&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Repeated tests, tags, timeouts and ordering
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@RepeatedTest(3)&lt;/code&gt;&lt;/strong&gt; runs the same test three times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Tag("slow")&lt;/code&gt;&lt;/strong&gt; labels a test. With Maven, you can include or exclude by tag: &lt;code&gt;mvn test -Dgroups=slow&lt;/code&gt; or &lt;code&gt;-DexcludedGroups=slow&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@Timeout(2)&lt;/code&gt;&lt;/strong&gt; fails the test if it runs longer than 2 seconds (the default unit is seconds).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@TempDir&lt;/code&gt;&lt;/strong&gt; gives your test a temporary folder that is deleted afterwards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@TestMethodOrder&lt;/code&gt;&lt;/strong&gt; with &lt;strong&gt;&lt;code&gt;@Order&lt;/code&gt;&lt;/strong&gt; sets the order of test methods. Don't rely on order in normal tests. It's meant for special cases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditional tests&lt;/strong&gt; like &lt;code&gt;@EnabledOnOs(OS.LINUX)&lt;/code&gt; or &lt;code&gt;@EnabledIfEnvironmentVariable&lt;/code&gt; run a test only in some environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Extensions
&lt;/h3&gt;

&lt;p&gt;An extension is a class that hooks into the test lifecycle. Here's a tiny one that logs when each test starts and ends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.extension.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoggingExtension&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;BeforeEachCallback&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;AfterEachCallback&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ExtensionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"START "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDisplayName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;afterEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ExtensionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"END   "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDisplayName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ExtendWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;LoggingExtension&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExtensionDemoTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;works&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"  running"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;START works()
  running
END   works()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real libraries use the same mechanism. For example, &lt;code&gt;@ExtendWith(MockitoExtension.class)&lt;/code&gt; sets up mock objects for you. And you can add as many extensions as you like.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JUnit 4 or JUnit 5?&lt;/strong&gt; For new projects, use JUnit 5 (or JUnit 6 if you're on Java 17 or newer). Keep JUnit 4 only for old code, and run it through the Vintage engine while you migrate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;assertThrows&lt;/code&gt; or try/catch?&lt;/strong&gt; Always &lt;code&gt;assertThrows&lt;/code&gt;. It's shorter, and it fails if nothing is thrown.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;assertEquals&lt;/code&gt; or &lt;code&gt;assertTrue(a.equals(b))&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;assertEquals&lt;/code&gt;. On failure, it shows both values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@BeforeEach&lt;/code&gt; or a field initializer?&lt;/strong&gt; Either works for simple setup. Use &lt;code&gt;@BeforeEach&lt;/code&gt; when setup needs several steps. Use &lt;code&gt;final&lt;/code&gt; fields for simple, unchanging objects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PER_METHOD&lt;/code&gt; or &lt;code&gt;PER_CLASS&lt;/code&gt;?&lt;/strong&gt; Stay with the default &lt;code&gt;PER_METHOD&lt;/code&gt; for independent tests. Use &lt;code&gt;PER_CLASS&lt;/code&gt; only when you need non-static &lt;code&gt;@BeforeAll&lt;/code&gt; or expensive shared setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One test with a loop, or &lt;code&gt;@ParameterizedTest&lt;/code&gt;?&lt;/strong&gt; Parameterized. Each input is reported on its own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JUnit's assertions or a fluent library?&lt;/strong&gt; JUnit's built-in assertions are enough to start. Libraries like &lt;strong&gt;AssertJ&lt;/strong&gt; and &lt;strong&gt;Hamcrest&lt;/strong&gt; read more naturally for complex checks (JUnit 5 has no built-in &lt;code&gt;assertThat&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real dependencies or mocks?&lt;/strong&gt; A unit test should be isolated. When your class talks to a database or a web service, replace it with a &lt;strong&gt;mock&lt;/strong&gt; (a fake). &lt;strong&gt;Mockito&lt;/strong&gt; is the common tool, and it plugs into JUnit 5 as an extension.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mixing JUnit 4 and JUnit 5 imports.&lt;/strong&gt; If you import &lt;code&gt;org.junit.Test&lt;/code&gt; (JUnit 4) but only the Jupiter engine is present, your test is &lt;strong&gt;never discovered&lt;/strong&gt;, and it silently doesn't run. Check that your imports start with &lt;code&gt;org.junit.jupiter.api&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Getting the argument order wrong.&lt;/strong&gt; It's &lt;code&gt;assertEquals(expected, actual)&lt;/code&gt;, and the message comes &lt;strong&gt;last&lt;/strong&gt; in JUnit 5. Swapping the first two gives misleading failure messages ("expected 5 but was 4" when it's the other way round).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comparing arrays or doubles the wrong way.&lt;/strong&gt; &lt;code&gt;assertEquals&lt;/code&gt; on arrays compares references, so use &lt;code&gt;assertArrayEquals&lt;/code&gt;. And &lt;code&gt;double&lt;/code&gt; values need a delta.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Letting tests depend on each other.&lt;/strong&gt; Tests that share state, or only work in a certain order, will fail randomly. Keep each test independent, and be careful with &lt;code&gt;PER_CLASS&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests that never run.&lt;/strong&gt; The causes are an old Surefire (older than 2.22.0 can't find JUnit 5 tests), a class name that doesn't match &lt;code&gt;*Test&lt;/code&gt;, or tests placed outside &lt;code&gt;src/test/java&lt;/code&gt;. If Maven says "No tests to run," check these.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests that can't fail.&lt;/strong&gt; A test with no assertion always passes, which gives false comfort. And a try/catch inside a test can swallow the very exception you meant to catch. Use &lt;code&gt;assertThrows&lt;/code&gt;, and make sure every test asserts something.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In the &lt;strong&gt;traditional SDLC&lt;/strong&gt;, a separate team tested after coding was done, so bugs were found late and fixes were costly. Now developers write automated tests as they go.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;unit test&lt;/strong&gt; checks one small piece of code in isolation. Good tests are &lt;strong&gt;FIRST&lt;/strong&gt;: fast, independent, repeatable, self-validating and timely. Use the &lt;strong&gt;Arrange-Act-Assert&lt;/strong&gt; pattern.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TDD&lt;/strong&gt; is &lt;strong&gt;Red, Green, Refactor&lt;/strong&gt;: write a failing test, write the simplest code to pass it, then clean up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JUnit 5&lt;/strong&gt; is a rewrite and &lt;strong&gt;not backward compatible&lt;/strong&gt; with JUnit 4: new package &lt;code&gt;org.junit.jupiter.api&lt;/code&gt;, new annotations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architecture:&lt;/strong&gt; &lt;strong&gt;Platform&lt;/strong&gt; (the Launcher and TestEngine API that IDEs and build tools use) + &lt;strong&gt;Jupiter&lt;/strong&gt; (the new tests and extension model) + &lt;strong&gt;Vintage&lt;/strong&gt; (runs JUnit 3 and 4 tests).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;With Maven:&lt;/strong&gt; add &lt;code&gt;junit-jupiter&lt;/code&gt; in &lt;code&gt;test&lt;/code&gt; scope, and use Surefire 2.22.0 or newer. Run &lt;code&gt;mvn test&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assertions&lt;/strong&gt; live in &lt;code&gt;Assertions&lt;/code&gt;: &lt;code&gt;assertEquals&lt;/code&gt;, &lt;code&gt;assertNotEquals&lt;/code&gt;, &lt;code&gt;assertTrue&lt;/code&gt;, &lt;code&gt;assertFalse&lt;/code&gt;, &lt;code&gt;assertNull&lt;/code&gt;, &lt;code&gt;assertNotNull&lt;/code&gt;, &lt;code&gt;assertSame&lt;/code&gt;, &lt;code&gt;assertArrayEquals&lt;/code&gt;, &lt;code&gt;assertIterableEquals&lt;/code&gt;, &lt;code&gt;assertThrows&lt;/code&gt;, &lt;code&gt;assertDoesNotThrow&lt;/code&gt;, &lt;code&gt;assertAll&lt;/code&gt;, &lt;code&gt;assertTimeout&lt;/code&gt; and &lt;code&gt;fail()&lt;/code&gt;. The message goes last.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Annotations:&lt;/strong&gt; &lt;code&gt;@Test&lt;/code&gt;, &lt;code&gt;@DisplayName&lt;/code&gt;, &lt;code&gt;@Disabled&lt;/code&gt;, &lt;code&gt;@BeforeEach&lt;/code&gt;, &lt;code&gt;@AfterEach&lt;/code&gt;, &lt;code&gt;@BeforeAll&lt;/code&gt;, &lt;code&gt;@AfterAll&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@TestInstance&lt;/code&gt;:&lt;/strong&gt; &lt;code&gt;PER_METHOD&lt;/code&gt; (default, a new object per test) or &lt;code&gt;PER_CLASS&lt;/code&gt; (one shared object, and non-static &lt;code&gt;@BeforeAll&lt;/code&gt; and &lt;code&gt;@AfterAll&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Also useful: &lt;code&gt;@ParameterizedTest&lt;/code&gt;, &lt;code&gt;@Nested&lt;/code&gt;, &lt;code&gt;@RepeatedTest&lt;/code&gt;, &lt;code&gt;@Tag&lt;/code&gt;, &lt;code&gt;@Timeout&lt;/code&gt; and extensions through &lt;code&gt;@ExtendWith&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: build a &lt;code&gt;PasswordValidator&lt;/code&gt; class &lt;strong&gt;using TDD&lt;/strong&gt;. The rules are: at least 8 characters, at least one digit and at least one uppercase letter. Write one failing test per rule first, make each pass with the simplest code, then refactor. Use a &lt;code&gt;@ParameterizedTest&lt;/code&gt; with &lt;code&gt;@CsvSource&lt;/code&gt; to check many valid and invalid passwords, and &lt;code&gt;assertThrows&lt;/code&gt; for a &lt;code&gt;null&lt;/code&gt; password.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, copy the &lt;code&gt;LifecycleTest&lt;/code&gt; class from this post and add &lt;code&gt;@TestInstance(TestInstance.Lifecycle.PER_CLASS)&lt;/code&gt;. Make &lt;code&gt;@BeforeAll&lt;/code&gt; non-static, and add a counter field to prove that the instance is shared. Then run a single test with &lt;code&gt;mvn test -Dtest=CalculatorTest#addsTwoNumbers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

</description>
      <category>java</category>
      <category>testing</category>
      <category>junit</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Gradle vs Maven: Which Java Build Tool Should You Pick?</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Wed, 21 Oct 2026 11:25:14 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/gradle-vs-maven-which-java-build-tool-should-you-pick-3cc6</link>
      <guid>https://dev.to/mayur_bodhare/gradle-vs-maven-which-java-build-tool-should-you-pick-3cc6</guid>
      <description>&lt;p&gt;When I learned Maven, everything felt tidy: one &lt;code&gt;pom.xml&lt;/code&gt;, one fixed lifecycle, one set of rules. Then I opened an Android project, and the build file looked completely different. It had no XML, and it had words like &lt;code&gt;plugins&lt;/code&gt;, &lt;code&gt;implementation&lt;/code&gt; and &lt;code&gt;tasks.register&lt;/code&gt;. Someone told me, "That's Gradle. It's like Maven, but it's actually code."&lt;/p&gt;

&lt;p&gt;That sentence is the key to understanding Gradle. It solves the same problems as Maven (compile, test, package and download libraries), but it does it in a different way: your build file is a &lt;strong&gt;small program&lt;/strong&gt;, and your build is a &lt;strong&gt;graph of tasks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this post, we'll learn what Gradle is, how it works, &lt;code&gt;build.gradle.kts&lt;/code&gt;, the &lt;code&gt;gradle init&lt;/code&gt; command, Gradle's terms, dependencies, tasks, repositories and the build lifecycle. At the end, there's a clear &lt;strong&gt;Gradle vs Maven comparison&lt;/strong&gt; to help you choose. I've drawn the important pictures in text so you can see how the pieces fit.&lt;/p&gt;

&lt;p&gt;If you've already read about Maven, Part 1 is a quick refresher, and you can skip ahead. I'm using Gradle 9.x with the Kotlin DSL. Gradle 9 needs Java 17 or newer to run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1: Build tools and why we need them (quick refresher)
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;build tool&lt;/strong&gt; automates the steps between your source code and a finished application. You describe the steps once, and the tool repeats them the same way every time.&lt;/p&gt;

&lt;p&gt;Every Java project goes through the same journey:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   source code        byte code          unit tests          package            build output
    (.java)    --&amp;gt;    (.class)    --&amp;gt;    (JUnit)     --&amp;gt;    (zip it up)  --&amp;gt;   .jar or .war
       |                  |                  |                   |
    you write          javac             check that         deployable
                       compiles          the code works     format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compile:&lt;/strong&gt; &lt;code&gt;javac&lt;/code&gt; turns &lt;code&gt;.java&lt;/code&gt; files into &lt;code&gt;.class&lt;/code&gt; bytecode.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test:&lt;/strong&gt; unit tests check that the code works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Package:&lt;/strong&gt; the classes are bundled into one file. A &lt;strong&gt;JAR&lt;/strong&gt; is for libraries and normal applications. A &lt;strong&gt;WAR&lt;/strong&gt; is for web apps on a server like Tomcat.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing this by hand means downloading JAR files yourself, writing long &lt;code&gt;javac&lt;/code&gt; commands and hoping that everyone on the team has the same setup. A build tool fixes that. The most useful part is &lt;strong&gt;dependency management&lt;/strong&gt;: you say &lt;strong&gt;what&lt;/strong&gt; libraries you need (name and version), and the tool downloads them, along with the libraries they need.&lt;/p&gt;

&lt;p&gt;The three popular Java build tools are &lt;strong&gt;Ant&lt;/strong&gt; (every step written by hand), &lt;strong&gt;Maven&lt;/strong&gt; (XML and a fixed lifecycle) and &lt;strong&gt;Gradle&lt;/strong&gt; (a script and a task graph). This post is about Gradle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: What is Gradle?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Gradle&lt;/strong&gt; is a build automation and dependency management tool. It builds Java, Kotlin, Android and many other kinds of projects. Instead of describing your project in XML, you write a &lt;strong&gt;build script&lt;/strong&gt; in a real programming language:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kotlin DSL:&lt;/strong&gt; &lt;code&gt;build.gradle.kts&lt;/code&gt; (the default for new projects)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Groovy DSL:&lt;/strong&gt; &lt;code&gt;build.gradle&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(A &lt;strong&gt;DSL&lt;/strong&gt;, a domain-specific language, is a language shaped for one job. It looks like configuration, but underneath it's real code.)&lt;/p&gt;

&lt;h3&gt;
  
  
  What does Gradle do?
&lt;/h3&gt;

&lt;p&gt;The same five jobs as Maven:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Project structure.&lt;/strong&gt; It uses the same standard folders (&lt;code&gt;src/main/java&lt;/code&gt; and so on).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependencies.&lt;/strong&gt; It downloads the libraries you list, and what they need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unit tests.&lt;/strong&gt; It runs your tests (for example, with JUnit).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compile.&lt;/strong&gt; It compiles your code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Package.&lt;/strong&gt; It builds a JAR (or a WAR, with the right plugin).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It can also run your application, create distribution files and publish your library to a repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does Gradle do it?
&lt;/h3&gt;

&lt;p&gt;Gradle is built on three ideas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Everything is a task.&lt;/strong&gt; A &lt;strong&gt;task&lt;/strong&gt; is one unit of work: &lt;code&gt;compileJava&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;, &lt;code&gt;jar&lt;/code&gt;. Gradle's tasks can depend on other tasks. When you ask for one task, Gradle works out which other tasks must run first, and builds a &lt;strong&gt;graph&lt;/strong&gt; (a map of who depends on whom).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Plugins add the tasks.&lt;/strong&gt; Gradle itself is small. When you add the &lt;code&gt;java&lt;/code&gt; plugin, it gives your project tasks like &lt;code&gt;compileJava&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt; and &lt;code&gt;jar&lt;/code&gt;, plus the standard folder layout and conventions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. It avoids repeating work.&lt;/strong&gt; Each task declares its &lt;strong&gt;inputs&lt;/strong&gt; (like source files) and &lt;strong&gt;outputs&lt;/strong&gt; (like class files). If nothing changed since the last run, Gradle skips the task and marks it &lt;code&gt;UP-TO-DATE&lt;/code&gt;. It also keeps a background process (the &lt;strong&gt;Gradle daemon&lt;/strong&gt;) alive between builds so each build starts quickly.&lt;/p&gt;

&lt;p&gt;When you run a build, Gradle goes through three phases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ./gradlew build
        |
        v
   1. INITIALIZATION   Find settings.gradle.kts. Decide which projects are part of the build.
        |
        v
   2. CONFIGURATION    Read the build scripts. Create the tasks. Build the task graph.
        |
        v
   3. EXECUTION        Run only the tasks that are needed, in dependency order.
                       Skip any that are UP-TO-DATE.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Gradle Wrapper
&lt;/h3&gt;

&lt;p&gt;Gradle projects almost always include a small helper called the &lt;strong&gt;wrapper&lt;/strong&gt;: the files &lt;code&gt;gradlew&lt;/code&gt; (Linux and macOS) and &lt;code&gt;gradlew.bat&lt;/code&gt; (Windows). Instead of installing Gradle yourself, you run &lt;code&gt;./gradlew&lt;/code&gt;. The first time, it downloads the &lt;strong&gt;exact Gradle version&lt;/strong&gt; the project needs. This means every developer and every build server uses the same version. Commit the wrapper files to your repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see the Gradle version and the Java version it uses. Make sure the Java version is 17 or newer for Gradle 9.&lt;/p&gt;

&lt;h2&gt;
  
  
  The standard project structure
&lt;/h2&gt;

&lt;p&gt;Gradle uses the same folder conventions as Maven:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   my-app/
   |-- settings.gradle.kts          &amp;lt;- project name, and which sub-projects exist
   |-- build.gradle.kts             &amp;lt;- the build script
   |-- gradlew, gradlew.bat         &amp;lt;- the wrapper scripts
   |-- gradle/wrapper/              &amp;lt;- wrapper files (commit these)
   |-- src/
   |    |-- main/
   |    |    |-- java/              &amp;lt;- your application code
   |    |    +-- resources/         &amp;lt;- config files, images
   |    +-- test/
   |         |-- java/              &amp;lt;- your unit tests
   |         +-- resources/
   +-- build/                       &amp;lt;- created by Gradle: all build output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;src/main&lt;/code&gt; is code that ships. &lt;code&gt;src/test&lt;/code&gt; is code that only checks it. &lt;code&gt;build/&lt;/code&gt; is the output folder (the same idea as Maven's &lt;code&gt;target/&lt;/code&gt;), and you can delete it any time.&lt;/p&gt;

&lt;p&gt;(When you create a project with &lt;code&gt;gradle init&lt;/code&gt;, the code usually goes inside an &lt;code&gt;app/&lt;/code&gt; folder, which is a sub-project, with its own &lt;code&gt;build.gradle.kts&lt;/code&gt;. The layout inside it is the same.)&lt;/p&gt;

&lt;h2&gt;
  
  
  The build script: build.gradle.kts
&lt;/h2&gt;

&lt;p&gt;Two small files describe a project. First, &lt;code&gt;settings.gradle.kts&lt;/code&gt; gives it a name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;rootProject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"my-app"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then &lt;code&gt;build.gradle.kts&lt;/code&gt; describes how to build it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;java&lt;/span&gt;
    &lt;span class="n"&gt;application&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"com.example"&lt;/span&gt;
&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0-SNAPSHOT"&lt;/span&gt;

&lt;span class="nf"&gt;repositories&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;mavenCentral&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;testImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.junit:junit-bom:5.11.0"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;testImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.junit.jupiter:junit-jupiter"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;testRuntimeOnly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.junit.platform:junit-platform-launcher"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;withType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JavaCompile&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;release&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;application&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mainClass&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"com.example.App"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;useJUnitPlatform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what each part means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;plugins { ... }&lt;/code&gt;&lt;/strong&gt;: which plugins to apply. &lt;code&gt;java&lt;/code&gt; adds compile, test and jar tasks. &lt;code&gt;application&lt;/code&gt; adds the ability to run your program (a &lt;code&gt;run&lt;/code&gt; task).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;group&lt;/code&gt; and &lt;code&gt;version&lt;/code&gt;&lt;/strong&gt;: the project's coordinates. The name comes from &lt;code&gt;rootProject.name&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;repositories { ... }&lt;/code&gt;&lt;/strong&gt;: where to download libraries from. &lt;code&gt;mavenCentral()&lt;/code&gt; is the big public repository. &lt;strong&gt;You must declare it&lt;/strong&gt;, because Gradle doesn't assume any repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;dependencies { ... }&lt;/code&gt;&lt;/strong&gt;: your libraries. The word before the brackets (like &lt;code&gt;testImplementation&lt;/code&gt;) says &lt;strong&gt;when&lt;/strong&gt; the library is needed. The &lt;code&gt;platform(...)&lt;/code&gt; line imports a BOM (a list of matching versions), so the other JUnit lines don't need version numbers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;options.release = 17&lt;/code&gt;&lt;/strong&gt;: the Java version to compile for. Set it to your JDK version, like 17 or 21.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;application { mainClass }&lt;/code&gt;&lt;/strong&gt;: which class has &lt;code&gt;main&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tasks.test { useJUnitPlatform() }&lt;/code&gt;&lt;/strong&gt;: tells the test task to use JUnit 5. Without this line, JUnit 5 tests don't run.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;junit-platform-launcher&lt;/code&gt; line is needed with Gradle 9 so that tests can start.&lt;/p&gt;

&lt;h3&gt;
  
  
  The same thing in Groovy
&lt;/h3&gt;

&lt;p&gt;If you see &lt;code&gt;build.gradle&lt;/code&gt; (no &lt;code&gt;.kts&lt;/code&gt;), it's the Groovy version. It looks a bit lighter, with fewer brackets and quotes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="s1"&gt;'java'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;repositories&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mavenCentral&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;testImplementation&lt;/span&gt; &lt;span class="s1"&gt;'org.junit.jupiter:junit-jupiter:5.11.0'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both do the same job. Kotlin DSL is the default for new projects, because IDEs can autocomplete it and show errors as you type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes: the script is code
&lt;/h3&gt;

&lt;p&gt;When Gradle runs &lt;code&gt;build.gradle.kts&lt;/code&gt;, it &lt;strong&gt;compiles and runs it&lt;/strong&gt; like a program. Lines like &lt;code&gt;dependencies { ... }&lt;/code&gt; are real function calls, and the block in curly braces is code. That's why you can use variables, &lt;code&gt;if&lt;/code&gt; statements and loops in a build script, which isn't possible in a plain XML file. It's powerful, but it also means a build script can become complicated if you aren't careful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a project: gradle init
&lt;/h2&gt;

&lt;p&gt;Maven has &lt;code&gt;archetype:generate&lt;/code&gt;. Gradle has &lt;strong&gt;&lt;code&gt;gradle init&lt;/code&gt;&lt;/strong&gt;. Here's the full command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gradle init &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--type&lt;/span&gt; java-application &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dsl&lt;/span&gt; kotlin &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--test-framework&lt;/span&gt; junit-jupiter &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--package&lt;/span&gt; com.example &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--project-name&lt;/span&gt; my-app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--java-version&lt;/span&gt; 17
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(On Windows Command Prompt, write it on one line without the &lt;code&gt;\&lt;/code&gt; characters.)&lt;/p&gt;

&lt;p&gt;Let's break it down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;gradle init&lt;/code&gt;&lt;/strong&gt;: runs the built-in &lt;code&gt;init&lt;/code&gt; task, which creates a new project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--type java-application&lt;/code&gt;&lt;/strong&gt;: the kind of project. &lt;code&gt;java-application&lt;/code&gt; is a command-line app. Other choices include &lt;code&gt;java-library&lt;/code&gt;, &lt;code&gt;kotlin-application&lt;/code&gt;, &lt;code&gt;groovy-application&lt;/code&gt; and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--dsl kotlin&lt;/code&gt;&lt;/strong&gt;: which language to write the build scripts in (&lt;code&gt;kotlin&lt;/code&gt; or &lt;code&gt;groovy&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--test-framework junit-jupiter&lt;/code&gt;&lt;/strong&gt;: which test library to set up. &lt;code&gt;junit-jupiter&lt;/code&gt; means JUnit 5. Others include &lt;code&gt;junit&lt;/code&gt; (JUnit 4), &lt;code&gt;testng&lt;/code&gt; and &lt;code&gt;spock&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--package com.example&lt;/code&gt;&lt;/strong&gt;: the Java package for the sample classes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--project-name my-app&lt;/code&gt;&lt;/strong&gt;: the name of the project. It defaults to the folder name.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--java-version 17&lt;/code&gt;&lt;/strong&gt;: the Java version to use in the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you run plain &lt;code&gt;gradle init&lt;/code&gt; with no options, Gradle &lt;strong&gt;asks you questions&lt;/strong&gt; one by one (type, language, DSL, test framework), so it works interactively too. To see every option, run &lt;code&gt;gradle help --task init&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The result is a working project with a sample &lt;code&gt;App.java&lt;/code&gt;, a sample test, the build scripts and the wrapper files. A handy extra: if you run &lt;code&gt;gradle init&lt;/code&gt; inside an existing &lt;strong&gt;Maven&lt;/strong&gt; project, Gradle can convert the &lt;code&gt;pom.xml&lt;/code&gt; into Gradle build files for you.&lt;/p&gt;

&lt;p&gt;Note that &lt;code&gt;gradle init&lt;/code&gt; needs Gradle installed once. After that, the generated project carries its own wrapper, so everyone else just uses &lt;code&gt;./gradlew&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gradle terminology
&lt;/h2&gt;

&lt;p&gt;Gradle's words are a little different from Maven's. Here they are side by side.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project, plugin and task
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;project&lt;/strong&gt; is something Gradle builds. A big build can have a &lt;strong&gt;root project&lt;/strong&gt; and several &lt;strong&gt;sub-projects&lt;/strong&gt; (modules).&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;plugin&lt;/strong&gt; adds tasks, folders and conventions to a project (&lt;code&gt;java&lt;/code&gt;, &lt;code&gt;application&lt;/code&gt;, &lt;code&gt;war&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;task&lt;/strong&gt; is one unit of work (&lt;code&gt;compileJava&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;, &lt;code&gt;jar&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Coordinates: group, name, version
&lt;/h3&gt;

&lt;p&gt;Gradle uses the &lt;strong&gt;same coordinate system as Maven&lt;/strong&gt;, so both tools can share libraries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   com.google.code.gson : gson : 2.11.0
        group              name     version      (Maven calls the middle part "artifactId")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;group&lt;/code&gt;&lt;/strong&gt;: who it belongs to, usually a reversed domain: &lt;code&gt;com.example&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;name&lt;/strong&gt;: the project name from &lt;code&gt;rootProject.name&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;version&lt;/code&gt;&lt;/strong&gt;: the version, like &lt;code&gt;1.0-SNAPSHOT&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Version: SNAPSHOT vs release
&lt;/h3&gt;

&lt;p&gt;The same convention applies: a version ending in &lt;strong&gt;&lt;code&gt;-SNAPSHOT&lt;/code&gt;&lt;/strong&gt; means work in progress, and a version without it (like &lt;code&gt;1.0.0&lt;/code&gt;) is a finished &lt;strong&gt;release&lt;/strong&gt; that should never change once published.&lt;/p&gt;

&lt;p&gt;Gradle also allows "dynamic" versions like &lt;code&gt;2.+&lt;/code&gt; or &lt;code&gt;latest.release&lt;/code&gt;, which pick whatever is newest. Avoid them, because your build can change without you touching it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Packaging: there's no &lt;code&gt;&amp;lt;packaging&amp;gt;&lt;/code&gt; tag
&lt;/h3&gt;

&lt;p&gt;Maven has a &lt;code&gt;packaging&lt;/code&gt; setting (&lt;code&gt;jar&lt;/code&gt;, &lt;code&gt;war&lt;/code&gt;). Gradle doesn't. Instead, &lt;strong&gt;the plugin decides&lt;/strong&gt; what gets built:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;java&lt;/code&gt; plugin gives you a &lt;code&gt;jar&lt;/code&gt; task&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;war&lt;/code&gt; plugin gives you a &lt;code&gt;war&lt;/code&gt; task, for web applications&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;application&lt;/code&gt; plugin adds &lt;code&gt;run&lt;/code&gt;, plus tasks to build a runnable ZIP or TAR of your app&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;maven-publish&lt;/code&gt; plugin adds the tasks to publish your result&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Templates: archetype vs init type
&lt;/h3&gt;

&lt;p&gt;Maven's &lt;strong&gt;archetype&lt;/strong&gt; is a project template. In Gradle, the same idea is the &lt;strong&gt;&lt;code&gt;--type&lt;/code&gt;&lt;/strong&gt; option of &lt;code&gt;gradle init&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gradle dependencies
&lt;/h2&gt;

&lt;p&gt;A dependency is declared inside &lt;code&gt;dependencies { }&lt;/code&gt;, using the format &lt;code&gt;"group:name:version"&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.google.code.gson:gson:2.11.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare that to Maven, where the same dependency takes six lines of XML. Now you can use it right away:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.Gson&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Gson&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Gson&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"name":"Asha"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configurations: when is the dependency needed?
&lt;/h3&gt;

&lt;p&gt;In Maven, you use a &lt;strong&gt;scope&lt;/strong&gt;. In Gradle, the word before the brackets is called a &lt;strong&gt;configuration&lt;/strong&gt;. The common ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;implementation&lt;/code&gt;&lt;/strong&gt;: needed to compile and run your code. It's packaged with your app. This is the default choice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;api&lt;/code&gt;&lt;/strong&gt;: like &lt;code&gt;implementation&lt;/code&gt;, but also shows the library to &lt;strong&gt;anyone who uses your library&lt;/strong&gt;. It's available only with the &lt;code&gt;java-library&lt;/code&gt; plugin.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;compileOnly&lt;/code&gt;&lt;/strong&gt;: needed to compile, but not packaged (the server provides it at run time).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;runtimeOnly&lt;/code&gt;&lt;/strong&gt;: not needed to compile, but needed when running (like a database driver).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;testImplementation&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;testRuntimeOnly&lt;/code&gt;&lt;/strong&gt;: only for tests, like JUnit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;annotationProcessor&lt;/code&gt;&lt;/strong&gt;: for tools that run during compilation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Older Gradle versions used &lt;code&gt;compile&lt;/code&gt; and &lt;code&gt;testCompile&lt;/code&gt;. They were removed. If you see them in an old tutorial, use &lt;code&gt;implementation&lt;/code&gt; and &lt;code&gt;testImplementation&lt;/code&gt; instead.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Transitive dependencies and version conflicts
&lt;/h3&gt;

&lt;p&gt;As in Maven, if you add library A, and A needs B, Gradle fetches B too. See the whole tree with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew dependencies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To find out why a specific library is there, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew dependencyInsight &lt;span class="nt"&gt;--dependency&lt;/span&gt; gson
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When two libraries need &lt;strong&gt;different versions&lt;/strong&gt; of the same third library, Gradle's default is simple: &lt;strong&gt;the highest version wins&lt;/strong&gt;. (Maven picks the version nearest to your project. This is a real difference, and it's covered in the comparison below.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   my-app
     |-- lib-a 1.0
     |      +-- lib-b 2.0
     +-- lib-c 1.0
            +-- lib-b 1.5

   Gradle picks lib-b 2.0, the highest.
   Maven would pick lib-b 2.0 here too, but only because lib-a was declared first.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For larger projects, many teams keep all versions in one file, &lt;code&gt;gradle/libs.versions.toml&lt;/code&gt;, called a &lt;strong&gt;version catalog&lt;/strong&gt;. Then every module refers to a library by a short name, and the versions are in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gradle tasks
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;task&lt;/strong&gt; is a named piece of work. When you apply the &lt;code&gt;java&lt;/code&gt; plugin, you get a family of tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;clean&lt;/code&gt;&lt;/strong&gt;: deletes the &lt;code&gt;build&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;compileJava&lt;/code&gt;&lt;/strong&gt;: compiles the main code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;processResources&lt;/code&gt;&lt;/strong&gt;: copies the files from &lt;code&gt;src/main/resources&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;classes&lt;/code&gt;&lt;/strong&gt;: a grouping task that means "main code is compiled and ready."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;compileTestJava&lt;/code&gt;&lt;/strong&gt;: compiles the test code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;test&lt;/code&gt;&lt;/strong&gt;: runs the unit tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;jar&lt;/code&gt;&lt;/strong&gt;: bundles the classes into a JAR.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;assemble&lt;/code&gt;&lt;/strong&gt;: builds all the outputs (like the JAR), without running tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;check&lt;/code&gt;&lt;/strong&gt;: runs all the verification (like the tests).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;build&lt;/code&gt;&lt;/strong&gt;: does both &lt;code&gt;assemble&lt;/code&gt; and &lt;code&gt;check&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the &lt;code&gt;application&lt;/code&gt; plugin, you also get &lt;strong&gt;&lt;code&gt;run&lt;/code&gt;&lt;/strong&gt; (starts your program). And with &lt;code&gt;maven-publish&lt;/code&gt;, you get &lt;strong&gt;&lt;code&gt;publishToMavenLocal&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;publish&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The commands you'll use most:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;./gradlew clean&lt;/code&gt;&lt;/strong&gt;: delete old output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;./gradlew compileJava&lt;/code&gt;&lt;/strong&gt;: compile only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;./gradlew test&lt;/code&gt;&lt;/strong&gt;: compile and run the tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;./gradlew build&lt;/code&gt;&lt;/strong&gt;: compile, test and package.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;./gradlew run&lt;/code&gt;&lt;/strong&gt;: run the application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;./gradlew tasks&lt;/code&gt;&lt;/strong&gt;: list all available tasks (add &lt;code&gt;--all&lt;/code&gt; to see more).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(On Windows, use &lt;code&gt;gradlew.bat&lt;/code&gt; instead of &lt;code&gt;./gradlew&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;Here is a trimmed &lt;code&gt;./gradlew build&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Task :compileJava
&amp;gt; Task :processResources NO-SOURCE
&amp;gt; Task :classes
&amp;gt; Task :jar
&amp;gt; Task :assemble
&amp;gt; Task :compileTestJava
&amp;gt; Task :processTestResources NO-SOURCE
&amp;gt; Task :testClasses
&amp;gt; Task :test
&amp;gt; Task :check
&amp;gt; Task :build

BUILD SUCCESSFUL in 2s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each &lt;code&gt;&amp;gt; Task&lt;/code&gt; line is one task running, in dependency order. Now run it &lt;strong&gt;again&lt;/strong&gt; without changing anything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; Task :compileJava UP-TO-DATE
&amp;gt; Task :processResources NO-SOURCE
&amp;gt; Task :classes UP-TO-DATE
&amp;gt; Task :jar UP-TO-DATE
&amp;gt; Task :assemble UP-TO-DATE
&amp;gt; Task :compileTestJava UP-TO-DATE
&amp;gt; Task :test UP-TO-DATE
&amp;gt; Task :check UP-TO-DATE
&amp;gt; Task :build UP-TO-DATE

BUILD SUCCESSFUL in 400ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gradle noticed that nothing changed, so it &lt;strong&gt;skipped the work&lt;/strong&gt;. That's the "avoid repeating work" idea in action. &lt;code&gt;NO-SOURCE&lt;/code&gt; means the task had no input files, such as an empty resources folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  The task graph behind &lt;code&gt;build&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Gradle doesn't run a fixed list of steps. It works backwards from the task you ask for and builds a graph:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   build
    |-- assemble
    |     +-- jar
    |          +-- classes
    |               |-- compileJava
    |               +-- processResources
    +-- check
          +-- test
               |-- classes                     (same tasks, run only once)
               +-- testClasses
                     |-- compileTestJava
                     +-- processTestResources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you ask for &lt;code&gt;test&lt;/code&gt;, Gradle runs only &lt;code&gt;compileJava&lt;/code&gt;, &lt;code&gt;processResources&lt;/code&gt;, &lt;code&gt;classes&lt;/code&gt;, &lt;code&gt;compileTestJava&lt;/code&gt;, &lt;code&gt;processTestResources&lt;/code&gt;, &lt;code&gt;testClasses&lt;/code&gt; and &lt;code&gt;test&lt;/code&gt;. It doesn't build the JAR, because &lt;code&gt;test&lt;/code&gt; doesn't need it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing with JUnit
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;src/main/java/com/example/Calculator.java&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;src/test/java/com/example/CalculatorTest.java&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jupiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assertions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addsTwoNumbers&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BUILD SUCCESSFUL in 2s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gradle is quiet when everything passes. Now break the test on purpose by changing &lt;code&gt;5&lt;/code&gt; to &lt;code&gt;6&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CalculatorTest &amp;gt; addsTwoNumbers() FAILED
    org.opentest4j.AssertionFailedError at CalculatorTest.java:9

1 test completed, 1 failed

&amp;gt; Task :test FAILED
BUILD FAILED in 1s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The build fails, and the report is saved in &lt;code&gt;build/reports/tests/test/index.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's a difference from Maven worth noticing. In Maven, a failing test stops the lifecycle &lt;strong&gt;before&lt;/strong&gt; &lt;code&gt;package&lt;/code&gt;, so no JAR is built. In Gradle, the &lt;code&gt;jar&lt;/code&gt; task &lt;strong&gt;doesn't depend on &lt;code&gt;test&lt;/code&gt;&lt;/strong&gt;, so with &lt;code&gt;./gradlew build&lt;/code&gt; the JAR may already exist even though the build failed. The overall result is still &lt;code&gt;BUILD FAILED&lt;/code&gt;, so don't ship it. If you publish a library, make sure the publishing task only runs after &lt;code&gt;check&lt;/code&gt; has passed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running your application and your JAR
&lt;/h3&gt;

&lt;p&gt;With the &lt;code&gt;application&lt;/code&gt; plugin, running is one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello World!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(This is the output of the sample &lt;code&gt;App&lt;/code&gt; from &lt;code&gt;gradle init&lt;/code&gt;. Yours prints whatever your &lt;code&gt;main&lt;/code&gt; method prints.)&lt;/p&gt;

&lt;p&gt;The JAR from the &lt;code&gt;jar&lt;/code&gt; task doesn't say which class has &lt;code&gt;main&lt;/code&gt;, so this fails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-jar&lt;/span&gt; build/libs/my-app-1.0-SNAPSHOT.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;no main manifest attribute, in build/libs/my-app-1.0-SNAPSHOT.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can fix that by adding the main class to the manifest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;manifest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Main-Class"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"com.example.App"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your app uses outside libraries, you need a "fat JAR" that bundles them. The popular &lt;strong&gt;Shadow&lt;/strong&gt; plugin does that. Alternatively, the &lt;code&gt;application&lt;/code&gt; plugin's &lt;code&gt;installDist&lt;/code&gt; task creates a folder with your JAR, its libraries and a start script in &lt;code&gt;build/install/&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gradle repositories
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;repository&lt;/strong&gt; is a storage place for libraries, organized by coordinates. Gradle uses the same repositories as Maven, so everything on Maven Central works. You list them in the &lt;code&gt;repositories { }&lt;/code&gt; block, and Gradle searches them &lt;strong&gt;in the order you wrote them&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;repositories&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;mavenCentral&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;maven&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://repo.mycompany.com/maven"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The common ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mavenCentral()&lt;/code&gt;&lt;/strong&gt;: the huge public repository on the internet. This is where most open-source libraries live.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;maven { url = ... }&lt;/code&gt;&lt;/strong&gt;: any other Maven-style server, such as your company's private repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;google()&lt;/code&gt;&lt;/strong&gt;: Google's repository, used mostly for Android.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mavenLocal()&lt;/code&gt;&lt;/strong&gt;: the &lt;code&gt;~/.m2/repository&lt;/code&gt; folder that Maven uses. Use it only when you really must, because it can make builds depend on what's on your machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gradle also keeps its own &lt;strong&gt;cache&lt;/strong&gt; of downloaded libraries, in &lt;code&gt;~/.gradle/caches&lt;/code&gt;. Each library is downloaded once, and later builds reuse it. That's the same idea as Maven's local repository, in a different folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Need gson 2.11.0
        |
        v
   1. Gradle's cache (~/.gradle/caches) --- found? ---&amp;gt; use it (no internet needed)
        | not found
        v
   2. Repositories, in the order you declared them
        (company server, mavenCentral, ...)  --- found? ---&amp;gt; download it
        |                                                      |
        |                                                      v
        +--------------------------------------------&amp;gt; save it in the cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To publish your own library, apply the &lt;code&gt;maven-publish&lt;/code&gt; plugin. &lt;strong&gt;&lt;code&gt;publishToMavenLocal&lt;/code&gt;&lt;/strong&gt; copies it into &lt;code&gt;~/.m2&lt;/code&gt; (like Maven's &lt;code&gt;install&lt;/code&gt;), and &lt;strong&gt;&lt;code&gt;publish&lt;/code&gt;&lt;/strong&gt; uploads it to a remote repository (like Maven's &lt;code&gt;deploy&lt;/code&gt;). You configure the target address and login in the build script.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Gradle build lifecycle
&lt;/h2&gt;

&lt;p&gt;This is where Gradle is most different from Maven, so let's be careful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maven&lt;/strong&gt; has fixed lifecycles (default, clean, site), each with named phases that always run in the same order.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gradle&lt;/strong&gt; has no fixed phase list. It has two different ideas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The three build phases&lt;/strong&gt; (we saw these earlier): &lt;strong&gt;initialization&lt;/strong&gt;, &lt;strong&gt;configuration&lt;/strong&gt; and &lt;strong&gt;execution&lt;/strong&gt;. They describe how Gradle runs &lt;em&gt;any&lt;/em&gt; build, whatever tasks you ask for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The task graph.&lt;/strong&gt; The order in which tasks run comes from the &lt;strong&gt;dependencies between tasks&lt;/strong&gt;. A plugin says "&lt;code&gt;test&lt;/code&gt; needs &lt;code&gt;classes&lt;/code&gt;," and Gradle works out the rest.&lt;/p&gt;

&lt;p&gt;To give you the same comfort as Maven's phases, the &lt;code&gt;java&lt;/code&gt; plugin provides a few &lt;strong&gt;lifecycle tasks&lt;/strong&gt;: grouping tasks that do no work themselves, but depend on others:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   assemble   =  build everything (jar and other outputs), no tests
   check      =  run all verification (tests, and other checks)
   build      =  assemble + check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's how Maven's ideas map across:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   MAVEN                              GRADLE

   default lifecycle                  the task graph for the tasks you ask for
     validate                         (settings and configuration phases)
     compile                          compileJava
     test                             test
     package                          jar  (part of "assemble")
     verify                           check
     install                          publishToMavenLocal
     deploy                           publish

   clean lifecycle (mvn clean)        the "clean" task (./gradlew clean)
   site lifecycle  (mvn site)         no direct equivalent: use the "javadoc" task and report plugins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The big difference: in Maven you run a &lt;strong&gt;phase&lt;/strong&gt; and everything before it runs. In Gradle you run a &lt;strong&gt;task&lt;/strong&gt; and only the tasks it &lt;strong&gt;depends on&lt;/strong&gt; run.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's inside &lt;code&gt;build/&lt;/code&gt; after a build?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   build/
   |-- classes/java/main/            &amp;lt;- compiled main code
   |-- classes/java/test/            &amp;lt;- compiled test code
   |-- libs/                         &amp;lt;- the packaged JAR
   |-- reports/tests/test/           &amp;lt;- the test report (open index.html)
   +-- test-results/                 &amp;lt;- raw test results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Gradle vs Maven: the comparison
&lt;/h2&gt;

&lt;p&gt;Now the part that most people want. Both tools build Java projects, use the same repositories and the same library coordinates. The differences are in &lt;strong&gt;how&lt;/strong&gt; you describe the build and &lt;strong&gt;how&lt;/strong&gt; the build runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  The build file
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maven:&lt;/strong&gt; &lt;code&gt;pom.xml&lt;/code&gt;, which is XML. It's &lt;strong&gt;declarative&lt;/strong&gt;: you describe &lt;em&gt;what&lt;/em&gt; the project is, not what to do. It's verbose, but predictable, and every Maven project looks alike.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradle:&lt;/strong&gt; &lt;code&gt;build.gradle.kts&lt;/code&gt; (or &lt;code&gt;build.gradle&lt;/code&gt;), which is &lt;strong&gt;code&lt;/strong&gt;. It's shorter and you can use variables and logic, but a complex script can be harder to read.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same single dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.google.code.gson&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;gson&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.11.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.google.code.gson:gson:2.11.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The build model
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maven:&lt;/strong&gt; a &lt;strong&gt;fixed lifecycle&lt;/strong&gt; of phases. Easy to learn: run a phase, and everything before it runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradle:&lt;/strong&gt; a &lt;strong&gt;graph of tasks&lt;/strong&gt;. More flexible: you can add your own tasks, connect them anywhere and run only what's needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Speed
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gradle&lt;/strong&gt; is built to skip work. It uses &lt;strong&gt;incremental builds&lt;/strong&gt; (&lt;code&gt;UP-TO-DATE&lt;/code&gt; checks), a long-running &lt;strong&gt;daemon&lt;/strong&gt;, a &lt;strong&gt;build cache&lt;/strong&gt; that can reuse results (even from other machines) and parallel execution. On large projects with many modules, this often makes Gradle noticeably faster, especially on repeated builds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maven&lt;/strong&gt; has also gained speed features (for example, parallel builds with &lt;code&gt;-T&lt;/code&gt;, and an optional daemon tool called &lt;code&gt;mvnd&lt;/code&gt;), and it does the same work each time, which keeps it simple.&lt;/li&gt;
&lt;li&gt;For a small project, you'll hardly notice a difference. The gap grows with project size. Always measure your own project instead of trusting general claims.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Flexibility vs convention
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maven&lt;/strong&gt; strongly prefers convention. If you need something unusual, you usually write or configure a &lt;strong&gt;plugin&lt;/strong&gt;, which takes effort. The benefit is that it's hard to make a build too clever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradle&lt;/strong&gt; makes custom logic easy: you can write a task right in the build script. The risk is the opposite: it's easy to make a build too clever.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dependencies
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scopes vs configurations:&lt;/strong&gt; Maven has a few scopes (&lt;code&gt;compile&lt;/code&gt;, &lt;code&gt;provided&lt;/code&gt;, &lt;code&gt;runtime&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;). Gradle has more fine-grained configurations (&lt;code&gt;implementation&lt;/code&gt;, &lt;code&gt;api&lt;/code&gt;, &lt;code&gt;compileOnly&lt;/code&gt;, &lt;code&gt;runtimeOnly&lt;/code&gt;, &lt;code&gt;testImplementation&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;api&lt;/code&gt; vs &lt;code&gt;implementation&lt;/code&gt;:&lt;/strong&gt; Gradle can hide a library's internal dependencies from the projects that use it (&lt;code&gt;implementation&lt;/code&gt;), and this can cut compile time in big builds. Maven has no direct equivalent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version conflicts:&lt;/strong&gt; Maven's default is "&lt;strong&gt;nearest&lt;/strong&gt; to your project wins." Gradle's default is "&lt;strong&gt;highest&lt;/strong&gt; version wins."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Maven scopes and their Gradle equivalents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   MAVEN SCOPE           GRADLE CONFIGURATION
   compile               implementation  (or api, in a java-library)
   provided              compileOnly
   runtime               runtimeOnly
   test                  testImplementation / testRuntimeOnly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Learning curve
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maven&lt;/strong&gt; is easier to start with and easier to predict. Most Maven builds look nearly the same, so you can read an unfamiliar project quickly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradle&lt;/strong&gt; has more concepts to learn (tasks, configurations, plugins, the DSL, the three phases). Once you know them, you can do more, but the first weeks are steeper.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ecosystem and tooling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Both are well supported in IntelliJ IDEA, Eclipse and VS Code, and both work with Spring Boot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradle&lt;/strong&gt; is the standard build tool for &lt;strong&gt;Android&lt;/strong&gt;. It's also popular in Kotlin projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maven&lt;/strong&gt; is extremely common in enterprise and older Java projects, with a vast number of ready-made plugins.&lt;/li&gt;
&lt;li&gt;Both can use the wrapper (&lt;code&gt;gradlew&lt;/code&gt; and &lt;code&gt;mvnw&lt;/code&gt;) so that every machine uses the same tool version.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Command cheat sheet
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   MAVEN                           GRADLE
   mvn -v                          ./gradlew --version
   mvn archetype:generate          gradle init
   mvn clean                       ./gradlew clean
   mvn compile                     ./gradlew compileJava
   mvn test                        ./gradlew test
   mvn package                     ./gradlew build   (or ./gradlew jar)
   mvn install                     ./gradlew publishToMavenLocal
   mvn deploy                      ./gradlew publish
   mvn dependency:tree             ./gradlew dependencies
   mvn package -DskipTests         ./gradlew build -x test
   mvn test -Dtest=FooTest         ./gradlew test --tests FooTest
   mvn -o                          ./gradlew --offline
   mvn -U                          ./gradlew --refresh-dependencies

   pom.xml                         build.gradle.kts + settings.gradle.kts
   target/                         build/
   ~/.m2/repository               ~/.gradle/caches
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that &lt;code&gt;./gradlew build&lt;/code&gt; is the closest match to Maven's &lt;code&gt;verify&lt;/code&gt;, because it also runs the checks. To package only, with no tests, use &lt;code&gt;./gradlew jar&lt;/code&gt; or &lt;code&gt;./gradlew assemble&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Starting a new Android project?&lt;/strong&gt; Gradle. It's the standard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Joining an existing project?&lt;/strong&gt; Use whatever it already uses. Don't switch just because you like the other one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning Java build tools for the first time?&lt;/strong&gt; Start with Maven if you want the simplest, most predictable model. Learn Gradle next. The concepts (coordinates, repositories, dependencies, plugins) carry over almost completely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large multi-module project with slow builds?&lt;/strong&gt; Gradle's incremental builds and caching can help a lot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Need a lot of custom build logic?&lt;/strong&gt; Gradle makes it easier.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Want every project to look the same, with few surprises?&lt;/strong&gt; Maven.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building with Spring Boot?&lt;/strong&gt; Either works well. Pick the one your team knows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Want to move from Maven to Gradle?&lt;/strong&gt; Run &lt;code&gt;gradle init&lt;/code&gt; inside the Maven project. It can convert the build for you. Then check the result by hand.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A sensible attitude: both are good tools, and the "right" one is usually the one your team already uses well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Running &lt;code&gt;gradle&lt;/code&gt; instead of &lt;code&gt;./gradlew&lt;/code&gt;.&lt;/strong&gt; The globally installed Gradle may be a different version from the one the project needs. Use the wrapper. On Linux and macOS, if you get "permission denied," run &lt;code&gt;chmod +x gradlew&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Running Gradle on an old Java.&lt;/strong&gt; Gradle 9 needs Java 17 or newer to run. Check &lt;code&gt;./gradlew --version&lt;/code&gt; and your &lt;code&gt;JAVA_HOME&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using removed configurations.&lt;/strong&gt; &lt;code&gt;compile&lt;/code&gt; and &lt;code&gt;testCompile&lt;/code&gt; no longer exist. Use &lt;code&gt;implementation&lt;/code&gt; and &lt;code&gt;testImplementation&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forgetting &lt;code&gt;useJUnitPlatform()&lt;/code&gt;.&lt;/strong&gt; Without it, JUnit 5 tests aren't found, and the build "passes" with no tests run. Also remember the &lt;code&gt;junit-platform-launcher&lt;/code&gt; line for Gradle 9.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forgetting the repositories block.&lt;/strong&gt; If you don't declare &lt;code&gt;mavenCentral()&lt;/code&gt;, you get "Could not resolve" errors, because Gradle assumes no default repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unpredictable versions.&lt;/strong&gt; Dynamic versions like &lt;code&gt;2.+&lt;/code&gt; or &lt;code&gt;latest.release&lt;/code&gt;, and heavy use of &lt;code&gt;mavenLocal()&lt;/code&gt;, make builds change from day to day or machine to machine. Pin exact versions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gradle&lt;/strong&gt; automates building Java (and other) projects: compile, test, package and dependency management.&lt;/li&gt;
&lt;li&gt;Build scripts are &lt;strong&gt;code&lt;/strong&gt;: &lt;code&gt;build.gradle.kts&lt;/code&gt; (Kotlin) or &lt;code&gt;build.gradle&lt;/code&gt; (Groovy), plus &lt;code&gt;settings.gradle.kts&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Gradle works with &lt;strong&gt;tasks&lt;/strong&gt; in a &lt;strong&gt;graph&lt;/strong&gt;, added by &lt;strong&gt;plugins&lt;/strong&gt;. It skips tasks that are &lt;strong&gt;UP-TO-DATE&lt;/strong&gt;, and it uses a daemon and caches to stay fast.&lt;/li&gt;
&lt;li&gt;A build has three phases: &lt;strong&gt;initialization&lt;/strong&gt;, &lt;strong&gt;configuration&lt;/strong&gt; and &lt;strong&gt;execution&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Always use the &lt;strong&gt;wrapper&lt;/strong&gt; (&lt;code&gt;./gradlew&lt;/code&gt;) so everyone uses the same Gradle version.&lt;/li&gt;
&lt;li&gt;The standard layout is the same as Maven: &lt;code&gt;src/main/java&lt;/code&gt;, &lt;code&gt;src/test/java&lt;/code&gt;, with output in &lt;code&gt;build/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gradle init --type java-application ...&lt;/code&gt; creates a project, like Maven's &lt;code&gt;archetype:generate&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Coordinates are &lt;strong&gt;group:name:version&lt;/strong&gt;. There's no &lt;code&gt;packaging&lt;/code&gt; tag: &lt;strong&gt;plugins&lt;/strong&gt; decide what is built.&lt;/li&gt;
&lt;li&gt;Dependencies use &lt;strong&gt;configurations&lt;/strong&gt;: &lt;code&gt;implementation&lt;/code&gt;, &lt;code&gt;api&lt;/code&gt;, &lt;code&gt;compileOnly&lt;/code&gt;, &lt;code&gt;runtimeOnly&lt;/code&gt;, &lt;code&gt;testImplementation&lt;/code&gt;. In conflicts, the &lt;strong&gt;highest version&lt;/strong&gt; wins.&lt;/li&gt;
&lt;li&gt;You must declare &lt;strong&gt;repositories&lt;/strong&gt;, usually &lt;code&gt;mavenCentral()&lt;/code&gt;. Gradle caches downloads in &lt;code&gt;~/.gradle/caches&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Key tasks: &lt;code&gt;clean&lt;/code&gt;, &lt;code&gt;compileJava&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;, &lt;code&gt;jar&lt;/code&gt;, &lt;code&gt;assemble&lt;/code&gt;, &lt;code&gt;check&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt; and &lt;code&gt;run&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Compared with Maven: Gradle is code, a task graph and often faster on big builds. Maven is XML, a fixed lifecycle and simpler to predict.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: run &lt;code&gt;gradle init&lt;/code&gt; with the command from this post, then run &lt;code&gt;./gradlew build&lt;/code&gt; twice and watch the second run show &lt;code&gt;UP-TO-DATE&lt;/code&gt;. Add the &lt;code&gt;Calculator&lt;/code&gt; class and &lt;code&gt;CalculatorTest&lt;/code&gt;, run &lt;code&gt;./gradlew test&lt;/code&gt;, then break the test on purpose and read the failure report in &lt;code&gt;build/reports/tests/test/index.html&lt;/code&gt;. Finally, add the Gson dependency, print some JSON in &lt;code&gt;App&lt;/code&gt;, and run it with &lt;code&gt;./gradlew run&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, run &lt;code&gt;./gradlew dependencies&lt;/code&gt; and &lt;code&gt;./gradlew tasks --all&lt;/code&gt;, and see how much Gradle shows you about your own project. If you already have a Maven project, copy it, run &lt;code&gt;gradle init&lt;/code&gt; inside the copy, and compare the generated &lt;code&gt;build.gradle.kts&lt;/code&gt; with the original &lt;code&gt;pom.xml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

</description>
      <category>java</category>
      <category>gradle</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why Java Developers Use Maven (and Not javac by Hand)</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Thu, 15 Oct 2026 10:07:20 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/maven-explained-lifecycle-pomxml-and-dependencies-12c8</link>
      <guid>https://dev.to/mayur_bodhare/maven-explained-lifecycle-pomxml-and-dependencies-12c8</guid>
      <description>&lt;p&gt;When I wrote my first real Java project, I had a folder of &lt;code&gt;.java&lt;/code&gt; files, a folder of JAR files I had downloaded by hand and a very long &lt;code&gt;javac&lt;/code&gt; command that I kept in a text file. When a teammate cloned the project, it didn't compile on their machine. Their JAR versions were different, their folders were different and the command had to be changed.&lt;/p&gt;

&lt;p&gt;That's the problem &lt;strong&gt;Maven&lt;/strong&gt; solves. You describe your project in one file, and one short command builds it the same way on every machine: it downloads the libraries, compiles the code, runs the tests and packages everything into a JAR or WAR.&lt;/p&gt;

&lt;p&gt;In this post, we'll cover what build tools are, why we need them, how Maven works, what &lt;code&gt;pom.xml&lt;/code&gt; is, the full &lt;code&gt;archetype:generate&lt;/code&gt; command, Maven's terms (group id, artifact id, version, packaging), dependencies, goals, repositories and the three build lifecycles. I've drawn the important pictures in text so you can see how the pieces fit.&lt;/p&gt;

&lt;p&gt;A note about versions: I'm using Maven 3.9.x, the stable line at the time of writing. Everything here works the same in newer versions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1: Build tools and why we need them
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a build tool?
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;build tool&lt;/strong&gt; is a program that &lt;strong&gt;automates the steps between your source code and a finished, runnable application&lt;/strong&gt;. Instead of running those steps by hand, you describe them once, and the tool repeats them exactly the same way every time.&lt;/p&gt;

&lt;h3&gt;
  
  
  The journey of your code
&lt;/h3&gt;

&lt;p&gt;Every Java project goes through the same steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   source code        byte code          unit tests          package            build output
    (.java)    --&amp;gt;    (.class)    --&amp;gt;    (JUnit)     --&amp;gt;    (zip it up)  --&amp;gt;   .jar or .war
       |                  |                  |                   |
    you write          javac             check that         deployable
                       compiles          the code works     format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compile:&lt;/strong&gt; &lt;code&gt;javac&lt;/code&gt; turns &lt;code&gt;.java&lt;/code&gt; files into &lt;code&gt;.class&lt;/code&gt; bytecode.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test:&lt;/strong&gt; unit tests check that your code behaves correctly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Package:&lt;/strong&gt; the &lt;code&gt;.class&lt;/code&gt; files and resources are bundled into one file. A &lt;strong&gt;JAR&lt;/strong&gt; (Java ARchive) is for libraries and normal applications. A &lt;strong&gt;WAR&lt;/strong&gt; (Web ARchive) is for web applications that run on a server like Tomcat.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Doing it by hand
&lt;/h3&gt;

&lt;p&gt;Without a build tool, here's what a tiny project with one library needs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;javac &lt;span class="nt"&gt;-cp&lt;/span&gt; lib/gson-2.11.0.jar &lt;span class="nt"&gt;-d&lt;/span&gt; out src/com/example/App.java
java  &lt;span class="nt"&gt;-cp&lt;/span&gt; out:lib/gson-2.11.0.jar com.example.App
jar cf app.jar &lt;span class="nt"&gt;-C&lt;/span&gt; out &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(On Windows, the classpath separator is &lt;code&gt;;&lt;/code&gt; instead of &lt;code&gt;:&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;That's already awkward for one library and one file. Now imagine 200 files, 30 libraries, tests and three developers. The real problems are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Downloading libraries by hand.&lt;/strong&gt; You have to find each JAR, pick a version and put it in a folder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Libraries need other libraries.&lt;/strong&gt; Library A needs B, which needs C. You'd have to find all of them yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version clashes.&lt;/strong&gt; Two libraries need different versions of the same one. This is nicknamed "JAR hell."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Works on my machine."&lt;/strong&gt; Everyone's folders and versions are slightly different.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long manual steps.&lt;/strong&gt; Compile, test and package in the right order, every time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dependency management
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;dependency&lt;/strong&gt; is a library your project needs. &lt;strong&gt;Dependency management&lt;/strong&gt; means the tool finds, downloads and organizes those libraries for you. You just say &lt;strong&gt;what&lt;/strong&gt; you need, with a name and a version, and the tool does the rest, including the libraries that your libraries need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   WITHOUT a build tool                        WITH Maven

   you --&amp;gt; search the web for gson.jar         you --&amp;gt; write 5 lines in pom.xml
   you --&amp;gt; download it, copy to lib/                    |
   you --&amp;gt; find the jars gson needs                     v
   you --&amp;gt; fix the classpath by hand           Maven --&amp;gt; downloads gson + what it needs
   you --&amp;gt; repeat for every library                     and puts them on the classpath
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The popular build tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ant:&lt;/strong&gt; an early tool. You write every step yourself in &lt;code&gt;build.xml&lt;/code&gt;. Flexible, but a lot of manual work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maven:&lt;/strong&gt; you follow standard conventions and describe the project in &lt;code&gt;pom.xml&lt;/code&gt;. Dependencies are built in. This is what we're learning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradle:&lt;/strong&gt; similar goals to Maven, but build files are written in Groovy or Kotlin code instead of XML, and it's known for fast, incremental builds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three are used in real projects. Maven is the most common starting point, and its ideas (repositories, coordinates, lifecycles) show up everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: What is Apache Maven?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Apache Maven&lt;/strong&gt; is a build automation and dependency management tool, mostly used for Java. Its name comes from a word meaning "accumulator of knowledge." The key idea is the &lt;strong&gt;POM&lt;/strong&gt; (Project Object Model): a file called &lt;code&gt;pom.xml&lt;/code&gt; that describes your project.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does Maven do?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Project structure.&lt;/strong&gt; It gives every project the same standard folder layout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependencies.&lt;/strong&gt; It downloads the libraries you list, and the ones they need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unit tests.&lt;/strong&gt; It runs your tests (for example, with JUnit) automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compile.&lt;/strong&gt; It compiles your code with the right Java settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Package.&lt;/strong&gt; It builds a deployable file (JAR or WAR).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And a few more: it can &lt;strong&gt;install&lt;/strong&gt; the result into your local library folder, &lt;strong&gt;deploy&lt;/strong&gt; it to a shared server, and generate project &lt;strong&gt;reports and documentation&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does Maven do it?
&lt;/h3&gt;

&lt;p&gt;Maven works on two simple ideas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Convention over configuration.&lt;/strong&gt; If you put files in the standard places and follow the standard naming, you don't have to configure anything. Maven already knows where your code and tests are, and where to put the output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Plugins do the real work.&lt;/strong&gt; Maven itself is a small "coordinator." It reads your &lt;code&gt;pom.xml&lt;/code&gt;, decides which steps to run in which order, and hands each step to a &lt;strong&gt;plugin&lt;/strong&gt;. The compiler plugin compiles, the surefire plugin runs tests, the jar plugin builds the JAR.&lt;/p&gt;

&lt;p&gt;Here is what happens when you type one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   mvn package
      |
      v
   1. Maven reads pom.xml
      |
      v
   2. Works out the lifecycle: validate -&amp;gt; compile -&amp;gt; test -&amp;gt; package
      |
      v
   3. For each step, runs the plugin goal attached to it
        compile  -&amp;gt;  compiler plugin   (javac)
        test     -&amp;gt;  surefire plugin   (runs JUnit tests)
        package  -&amp;gt;  jar plugin        (builds the .jar)
      |
      v
   4. Needs a library or plugin? Looks in the local repository,
      and downloads it from the internet if it's missing
      |
      v
   5. Puts all results in the "target" folder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install and check
&lt;/h3&gt;

&lt;p&gt;Maven needs a JDK, and the &lt;code&gt;JAVA_HOME&lt;/code&gt; environment variable should point to it. After installing Maven, check it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see something like this (your numbers will differ):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Apache Maven 3.9.x
Maven home: /opt/maven
Java version: 17.0.x, vendor: ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at the &lt;strong&gt;Java version&lt;/strong&gt; line. Maven uses whichever JDK it finds, so make sure it's the one you intend.&lt;/p&gt;

&lt;h2&gt;
  
  
  The standard project structure
&lt;/h2&gt;

&lt;p&gt;Every Maven project looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   my-app/
   |-- pom.xml                      &amp;lt;- the project description
   |-- src/
   |    |-- main/
   |    |    |-- java/              &amp;lt;- your application code (.java)
   |    |    +-- resources/         &amp;lt;- config files, images, etc.
   |    +-- test/
   |         |-- java/              &amp;lt;- your unit tests
   |         +-- resources/         &amp;lt;- files used only by tests
   +-- target/                      &amp;lt;- created by Maven: all build output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;src/main&lt;/code&gt; is code that goes &lt;strong&gt;into&lt;/strong&gt; your finished application.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/test&lt;/code&gt; is code that only &lt;strong&gt;checks&lt;/strong&gt; it. It's never packaged.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;target&lt;/code&gt; is created by Maven. It holds the compiled classes, test reports and the JAR. You can delete it any time and nothing is lost.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because everyone uses this layout, you can open any Maven project in the world and find your way around.&lt;/p&gt;

&lt;h2&gt;
  
  
  pom.xml
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;POM&lt;/strong&gt; (Project Object Model) is the heart of a Maven project. Here's a small but complete example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt;
         &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
         &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.example&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;my-app&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;packaging&amp;gt;&lt;/span&gt;jar&lt;span class="nt"&gt;&amp;lt;/packaging&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;my-app&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.release&amp;gt;&lt;/span&gt;17&lt;span class="nt"&gt;&amp;lt;/maven.compiler.release&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.junit.jupiter&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit-jupiter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;5.11.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-surefire-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.5.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What each part means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;modelVersion&lt;/code&gt;&lt;/strong&gt;: the version of the POM format. It's always &lt;code&gt;4.0.0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;groupId&lt;/code&gt;, &lt;code&gt;artifactId&lt;/code&gt;, &lt;code&gt;version&lt;/code&gt;&lt;/strong&gt;: the project's identity (we'll explain them in a moment).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;packaging&lt;/code&gt;&lt;/strong&gt;: what kind of file to build (&lt;code&gt;jar&lt;/code&gt; is the default).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;name&lt;/code&gt;&lt;/strong&gt;: a friendly name for humans.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;properties&lt;/code&gt;&lt;/strong&gt;: settings and variables. &lt;code&gt;maven.compiler.release&lt;/code&gt; is the Java version to compile for (set it to your JDK version, like 17 or 21), and the encoding avoids platform surprises.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;dependencies&lt;/code&gt;&lt;/strong&gt;: the libraries you need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;build&lt;/code&gt; / &lt;code&gt;plugins&lt;/code&gt;&lt;/strong&gt;: extra configuration for the build. Here we pin the test plugin version, which also makes sure JUnit 5 tests are found. Pinning plugin versions makes builds repeatable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Behind the scenes: your POM is tiny
&lt;/h3&gt;

&lt;p&gt;Your &lt;code&gt;pom.xml&lt;/code&gt; looks short because it &lt;strong&gt;inherits&lt;/strong&gt; from a hidden built-in file called the &lt;strong&gt;Super POM&lt;/strong&gt;. It holds all the defaults: the folder layout, the repository address and the default plugins. Maven merges the Super POM and your POM into one &lt;strong&gt;effective POM&lt;/strong&gt;. You can see the full result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn &lt;span class="nb"&gt;help&lt;/span&gt;:effective-pom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's long, but it shows you everything Maven is actually using.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a project: mvn archetype:generate
&lt;/h2&gt;

&lt;p&gt;You can create the folders and &lt;code&gt;pom.xml&lt;/code&gt; by hand, but Maven can generate a ready-made project from a &lt;strong&gt;template&lt;/strong&gt;. That's what &lt;code&gt;archetype:generate&lt;/code&gt; does. Here's the full command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn archetype:generate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-DgroupId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;com.example &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-DartifactId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-DarchetypeArtifactId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;maven-archetype-quickstart &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-DarchetypeVersion&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.5 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-DinteractiveMode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(On Windows Command Prompt, write it on one line without the &lt;code&gt;\&lt;/code&gt; characters.)&lt;/p&gt;

&lt;p&gt;Let's break it down piece by piece:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mvn&lt;/code&gt;&lt;/strong&gt;: runs Maven.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;archetype:generate&lt;/code&gt;&lt;/strong&gt;: this is &lt;code&gt;plugin:goal&lt;/code&gt;. It means "use the &lt;strong&gt;archetype&lt;/strong&gt; plugin and run its &lt;strong&gt;generate&lt;/strong&gt; goal."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-D&lt;/code&gt;&lt;/strong&gt;: sets a property. Each option is written as &lt;code&gt;-Dname=value&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-DgroupId=com.example&lt;/code&gt;&lt;/strong&gt;: the group id of your new project (usually your reversed domain or company).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-DartifactId=my-app&lt;/code&gt;&lt;/strong&gt;: the name of your project. Maven also creates a folder with this name.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-DarchetypeArtifactId=maven-archetype-quickstart&lt;/code&gt;&lt;/strong&gt;: which template to use. The quickstart template makes a simple Java project with a sample class and a sample test.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-DarchetypeVersion=1.5&lt;/code&gt;&lt;/strong&gt;: the version of that template. Version 1.5 generates a project that uses JUnit 5. (If your Maven can't find it, remove this option, and Maven will pick a version for you.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-DinteractiveMode=false&lt;/code&gt;&lt;/strong&gt;: don't ask questions. Without it, Maven asks you for the template version, the package name and a final confirmation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two extra options you may see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-Dversion=1.0-SNAPSHOT&lt;/code&gt;&lt;/strong&gt;: the starting version (this is already the default).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-Dpackage=com.example.app&lt;/code&gt;&lt;/strong&gt;: the Java package for the sample classes. If you skip it, it defaults to the group id.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first run downloads the archetype and some plugins from the internet, so it takes a little while. When it finishes, you'll see &lt;code&gt;BUILD SUCCESS&lt;/code&gt;, and this project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   my-app/
   |-- pom.xml
   +-- src/
        |-- main/java/com/example/App.java
        +-- test/java/com/example/AppTest.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated &lt;code&gt;App.java&lt;/code&gt; is a simple "Hello World" with a &lt;code&gt;main&lt;/code&gt; method. Open the generated &lt;code&gt;pom.xml&lt;/code&gt; and check the Java version property. If it's older than your JDK, change &lt;code&gt;maven.compiler.release&lt;/code&gt; to your Java version (for example &lt;code&gt;17&lt;/code&gt; or &lt;code&gt;21&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Maven terminology
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Archetype
&lt;/h3&gt;

&lt;p&gt;An &lt;strong&gt;archetype&lt;/strong&gt; is a &lt;strong&gt;project template&lt;/strong&gt;. It's a pattern for creating new projects, like a "starter kit." Besides &lt;code&gt;maven-archetype-quickstart&lt;/code&gt;, there are archetypes for web applications and more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Maven coordinates: groupId, artifactId, version
&lt;/h3&gt;

&lt;p&gt;Every project and library in the Maven world is identified by three values, called its &lt;strong&gt;coordinates&lt;/strong&gt; (or &lt;strong&gt;GAV&lt;/strong&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;groupId&lt;/code&gt;&lt;/strong&gt;: who it belongs to. Usually a reversed domain, like Java packages: &lt;code&gt;com.example&lt;/code&gt;, &lt;code&gt;org.junit.jupiter&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;artifactId&lt;/code&gt;&lt;/strong&gt;: the name of the project or library: &lt;code&gt;my-app&lt;/code&gt;, &lt;code&gt;gson&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;version&lt;/code&gt;&lt;/strong&gt;: which version: &lt;code&gt;1.0-SNAPSHOT&lt;/code&gt;, &lt;code&gt;2.11.0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together they point to exactly one thing, anywhere in the world:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   com.google.code.gson : gson : 2.11.0
        groupId          artifactId   version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The coordinates also decide where the file lives in a repository, which is just a folder path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   com.example : my-app : 1.0-SNAPSHOT
         |
         v   dots in groupId become folders
   com/example/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Version: SNAPSHOT vs release
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A version that ends in &lt;strong&gt;&lt;code&gt;-SNAPSHOT&lt;/code&gt;&lt;/strong&gt; (like &lt;code&gt;1.0-SNAPSHOT&lt;/code&gt;) means &lt;strong&gt;work in progress&lt;/strong&gt;. It can change as you keep developing. Maven treats it as "may have a newer build," and can check for updates.&lt;/li&gt;
&lt;li&gt;A version &lt;strong&gt;without&lt;/strong&gt; &lt;code&gt;-SNAPSHOT&lt;/code&gt; (like &lt;code&gt;1.0.0&lt;/code&gt;) is a &lt;strong&gt;release&lt;/strong&gt;. It's a fixed, finished version. Once a release is published to a public repository such as Maven Central, it &lt;strong&gt;can never be changed or replaced&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A typical life of a version: &lt;code&gt;1.0.0-SNAPSHOT&lt;/code&gt; while you build it, then you publish &lt;code&gt;1.0.0&lt;/code&gt; (the release), then you start &lt;code&gt;1.1.0-SNAPSHOT&lt;/code&gt; for the next work. A good tip is to follow a clear numbering scheme, such as &lt;code&gt;major.minor.patch&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Packaging type
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;packaging&lt;/code&gt;&lt;/strong&gt; tells Maven &lt;strong&gt;what to build&lt;/strong&gt; from your project. It also decides which plugin goals run at each step of the lifecycle.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;jar&lt;/code&gt;&lt;/strong&gt; (the default): a library or a normal application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;war&lt;/code&gt;&lt;/strong&gt;: a web application for a server like Tomcat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;pom&lt;/code&gt;&lt;/strong&gt;: no code of its own. Used for parent projects that group other projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ear&lt;/code&gt;&lt;/strong&gt;: an enterprise application (less common today).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Maven dependencies
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;dependency&lt;/strong&gt; is declared with its coordinates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.google.code.gson&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;gson&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.11.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/xml&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file, and Maven downloads the library the next time you build. Now you can use it in your code right away:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.Gson&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Gson&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Gson&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"name":"Asha"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No JAR downloads and no classpath editing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scope: when is the dependency needed?
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;scope&amp;gt;&lt;/code&gt; tag says &lt;strong&gt;when&lt;/strong&gt; a library is needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;compile&lt;/code&gt;&lt;/strong&gt; (default): needed to compile and run. It's packaged with your app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;test&lt;/code&gt;&lt;/strong&gt;: only for compiling and running tests, like JUnit. Not packaged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;provided&lt;/code&gt;&lt;/strong&gt;: needed to compile, but the server provides it when running (for example, the servlet API on Tomcat). Not packaged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;runtime&lt;/code&gt;&lt;/strong&gt;: not needed to compile, but needed when running (for example, a database driver).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the right scope keeps your final package small and clean.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transitive dependencies
&lt;/h3&gt;

&lt;p&gt;Libraries often depend on other libraries. If you add library A, and A needs B, Maven fetches B too. These are called &lt;strong&gt;transitive dependencies&lt;/strong&gt;. You can see the whole tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn dependency:tree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INFO] com.example:my-app:jar:1.0-SNAPSHOT
[INFO] +- com.google.code.gson:gson:jar:2.11.0:compile
[INFO] \- org.junit.jupiter:junit-jupiter:jar:5.11.0:test
[INFO]    +- org.junit.jupiter:junit-jupiter-api:jar:5.11.0:test
[INFO]    ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The list is trimmed here. Maven also shows the libraries that each one needs, indented underneath.)&lt;/p&gt;

&lt;p&gt;What if two libraries need &lt;strong&gt;different versions&lt;/strong&gt; of the same third library? Maven uses a simple rule: &lt;strong&gt;the version nearest to your project wins&lt;/strong&gt;. If they're equally near, the &lt;strong&gt;first one declared&lt;/strong&gt; wins.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   my-app
     |-- lib-a 1.0
     |      +-- lib-b 2.0      (two steps away)
     +-- lib-c 1.0
            +-- lib-b 1.5      (two steps away: a tie, so the first one, 2.0, wins)

   To take control, declare lib-b yourself in your pom.xml. A direct dependency is nearest.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Maven goals and phases
&lt;/h2&gt;

&lt;p&gt;Here's an important distinction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;goal&lt;/strong&gt; is one specific task done by a plugin. It's written as &lt;code&gt;plugin:goal&lt;/code&gt;, like &lt;code&gt;compiler:compile&lt;/code&gt; or &lt;code&gt;surefire:test&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;phase&lt;/strong&gt; is a named step in a lifecycle, like &lt;code&gt;compile&lt;/code&gt; or &lt;code&gt;test&lt;/code&gt;. Each phase has goals attached to it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you run a &lt;strong&gt;phase&lt;/strong&gt;, Maven runs every earlier phase first, then the goals attached to that one. You can also run a goal directly, like &lt;code&gt;mvn archetype:generate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The commands you'll use most:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mvn clean&lt;/code&gt;&lt;/strong&gt;: deletes the &lt;code&gt;target&lt;/code&gt; folder, so you start fresh.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mvn compile&lt;/code&gt;&lt;/strong&gt;: compiles the main code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mvn test&lt;/code&gt;&lt;/strong&gt;: compiles, then runs the unit tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mvn package&lt;/code&gt;&lt;/strong&gt;: runs the tests, then builds the JAR (or WAR).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mvn install&lt;/code&gt;&lt;/strong&gt;: packages, then copies the result into your local repository, so other projects on your machine can use it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mvn deploy&lt;/code&gt;&lt;/strong&gt;: uploads the package to a remote repository for others to use.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is what a run looks like. This is a trimmed &lt;code&gt;mvn package&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INFO] --- resources:3.x:resources (default-resources) @ my-app ---
[INFO] --- compiler:3.x:compile (default-compile) @ my-app ---
[INFO] Compiling 1 source file with javac [debug release 17] to target/classes
[INFO] --- surefire:3.5.0:test (default-test) @ my-app ---
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- jar:3.x:jar (default-jar) @ my-app ---
[INFO] Building jar: /.../my-app/target/my-app-1.0-SNAPSHOT.jar
[INFO] BUILD SUCCESS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Version numbers on your screen will differ.) Each &lt;code&gt;--- plugin:version:goal ---&lt;/code&gt; line is one goal running. You can see Maven working through the lifecycle: resources, compile, test, jar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing with JUnit
&lt;/h3&gt;

&lt;p&gt;Let's write a real class and test. Create &lt;code&gt;src/main/java/com/example/Calculator.java&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the test, &lt;code&gt;src/test/java/com/example/CalculatorTest.java&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jupiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assertions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addsTwoNumbers&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now break the test on purpose, by changing &lt;code&gt;5&lt;/code&gt; to &lt;code&gt;6&lt;/code&gt;, and run &lt;code&gt;mvn package&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
[INFO] BUILD FAILURE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look what didn't happen: &lt;strong&gt;no JAR was created.&lt;/strong&gt; The &lt;code&gt;test&lt;/code&gt; phase failed, so Maven stopped before the &lt;code&gt;package&lt;/code&gt; phase. That's the value of the lifecycle: broken code can't become a package by accident.&lt;/p&gt;

&lt;p&gt;Maven's test plugin finds tests by name. By default it looks for classes named &lt;code&gt;*Test&lt;/code&gt;, &lt;code&gt;Test*&lt;/code&gt;, &lt;code&gt;*Tests&lt;/code&gt; or &lt;code&gt;*TestCase&lt;/code&gt;, in &lt;code&gt;src/test/java&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running your JAR
&lt;/h3&gt;

&lt;p&gt;After &lt;code&gt;mvn package&lt;/code&gt;, your JAR is in &lt;code&gt;target/&lt;/code&gt;. If you try to run it like a normal application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-jar&lt;/span&gt; target/my-app-1.0-SNAPSHOT.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;no main manifest attribute, in target/my-app-1.0-SNAPSHOT.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JAR doesn't say which class has &lt;code&gt;main&lt;/code&gt;. You can run it by naming the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-cp&lt;/span&gt; target/my-app-1.0-SNAPSHOT.jar com.example.App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or make the JAR runnable by telling the jar plugin about your main class, in &lt;code&gt;pom.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-jar-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.4.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;archive&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;manifest&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;mainClass&amp;gt;&lt;/span&gt;com.example.App&lt;span class="nt"&gt;&amp;lt;/mainClass&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/manifest&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/archive&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(If your app uses outside libraries, you'd need another plugin, such as the shade or assembly plugin, to bundle them into one "fat" JAR.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Maven repositories
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;repository&lt;/strong&gt; is a storage place for libraries and plugins, organized by their coordinates. Maven uses three kinds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local repository:&lt;/strong&gt; a folder on your own computer, by default &lt;code&gt;~/.m2/repository&lt;/code&gt;. It's a cache of everything you've downloaded, plus anything you &lt;code&gt;install&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Central repository:&lt;/strong&gt; &lt;strong&gt;Maven Central&lt;/strong&gt;, the huge public repository on the internet. It's where most open-source libraries live, and Maven uses it by default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remote repository:&lt;/strong&gt; any other server. Companies often run their own (with tools such as Nexus or Artifactory) for private libraries, and to cache Central.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When Maven needs a library, it follows this search:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Need gson 2.11.0
        |
        v
   1. Local repository  (~/.m2/repository)  --- found? ---&amp;gt; use it (no internet needed)
        | not found
        v
   2. Remote repositories you configured (company server)  --- found? ---+
        | not found                                                      |
        v                                                                v
   3. Maven Central (internet)  --- found? ---&amp;gt; download ---------&amp;gt; save a copy in
                                                                      the local repository
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because of that last step, each library is downloaded only &lt;strong&gt;once&lt;/strong&gt;. Later builds use the local copy, and you can even work offline with &lt;code&gt;mvn -o&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How the lifecycle phases connect to repositories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;install&lt;/code&gt;&lt;/strong&gt; copies your JAR into the &lt;strong&gt;local&lt;/strong&gt; repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;deploy&lt;/code&gt;&lt;/strong&gt; uploads it to a &lt;strong&gt;remote&lt;/strong&gt; repository (you must configure the server address and your login).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can configure repositories, mirrors and passwords in a &lt;code&gt;settings.xml&lt;/code&gt; file in your &lt;code&gt;.m2&lt;/code&gt; folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Maven build lifecycle
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;build lifecycle&lt;/strong&gt; is a fixed sequence of &lt;strong&gt;phases&lt;/strong&gt;. Maven has &lt;strong&gt;three&lt;/strong&gt; built-in lifecycles: &lt;strong&gt;default&lt;/strong&gt;, &lt;strong&gt;clean&lt;/strong&gt; and &lt;strong&gt;site&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The default lifecycle (building your project)
&lt;/h3&gt;

&lt;p&gt;These are the main phases, in order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   validate --&amp;gt; compile --&amp;gt; test --&amp;gt; package --&amp;gt; verify --&amp;gt; install --&amp;gt; deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;validate&lt;/code&gt;&lt;/strong&gt;: checks that the project is correct and the needed information is there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;compile&lt;/code&gt;&lt;/strong&gt;: compiles the source code in &lt;code&gt;src/main/java&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;test&lt;/code&gt;&lt;/strong&gt;: runs unit tests, using the compiled code. The tests don't need to be packaged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;package&lt;/code&gt;&lt;/strong&gt;: bundles the compiled code into the packaging type (JAR, WAR).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;verify&lt;/code&gt;&lt;/strong&gt;: runs any extra checks on the package, like integration tests and quality rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;install&lt;/code&gt;&lt;/strong&gt;: copies the package into the &lt;strong&gt;local&lt;/strong&gt; repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;deploy&lt;/code&gt;&lt;/strong&gt;: copies the final package to a &lt;strong&gt;remote&lt;/strong&gt; repository for sharing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(The real lifecycle has more phases in between, such as &lt;code&gt;generate-sources&lt;/code&gt;, &lt;code&gt;process-resources&lt;/code&gt; and &lt;code&gt;test-compile&lt;/code&gt;. The ones above are the ones you'll use directly.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The key rule:&lt;/strong&gt; when you run a phase, Maven runs &lt;strong&gt;all the phases before it, in order&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   mvn compile   runs:  validate, compile
   mvn test      runs:  validate, compile, test
   mvn package   runs:  validate, compile, test, package
   mvn install   runs:  validate, compile, test, package, verify, install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You never need to run &lt;code&gt;mvn compile&lt;/code&gt; and then &lt;code&gt;mvn test&lt;/code&gt; separately. Just run the last phase you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  What runs in each phase?
&lt;/h3&gt;

&lt;p&gt;Each phase has &lt;strong&gt;plugin goals attached&lt;/strong&gt;, and which ones depend on your packaging type. For a normal &lt;code&gt;jar&lt;/code&gt; project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   PHASE        GOAL THAT RUNS               WHAT IT DOES
   compile      compiler:compile             javac on src/main/java
   test         surefire:test                runs the unit tests
   package      jar:jar                      builds the .jar
   install      install:install              copies it to ~/.m2
   deploy       deploy:deploy                uploads to a remote repository

   For packaging "war":   package runs  war:war  instead of  jar:jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This answers the question "how does Maven know what to do?" The packaging type chooses which goals are attached to which phases. That's why &lt;code&gt;&amp;lt;packaging&amp;gt;&lt;/code&gt; matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The clean lifecycle
&lt;/h3&gt;

&lt;p&gt;This one cleans up. It has three phases: &lt;code&gt;pre-clean&lt;/code&gt;, &lt;code&gt;clean&lt;/code&gt; and &lt;code&gt;post-clean&lt;/code&gt;. In practice you use only &lt;code&gt;clean&lt;/code&gt;, which &lt;strong&gt;deletes the &lt;code&gt;target&lt;/code&gt; folder&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn clean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's the way to get rid of old compiled files, so nothing stale is left behind. You'll often combine it with the default lifecycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn clean package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maven runs &lt;code&gt;clean&lt;/code&gt; (the clean lifecycle) first, then the default lifecycle up to &lt;code&gt;package&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The site lifecycle
&lt;/h3&gt;

&lt;p&gt;This one creates &lt;strong&gt;project documentation and reports&lt;/strong&gt;. Its phases are &lt;code&gt;pre-site&lt;/code&gt;, &lt;code&gt;site&lt;/code&gt;, &lt;code&gt;post-site&lt;/code&gt; and &lt;code&gt;site-deploy&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn site
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It generates a website describing your project (test reports, dependency lists, and so on) in &lt;code&gt;target/site&lt;/code&gt;. It's optional, and less common in day-to-day work than the other two.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's inside &lt;code&gt;target/&lt;/code&gt; after a build?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   target/
   |-- classes/                      &amp;lt;- compiled main code (.class)
   |-- test-classes/                 &amp;lt;- compiled test code
   |-- surefire-reports/             &amp;lt;- test result reports
   +-- my-app-1.0-SNAPSHOT.jar       &amp;lt;- the packaged result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A few tips and commands
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Skip tests&lt;/strong&gt; when you must (for example, to package quickly): &lt;code&gt;mvn package -DskipTests&lt;/code&gt;. This still compiles the tests. &lt;code&gt;-Dmaven.test.skip=true&lt;/code&gt; skips compiling them too. Don't make this a habit, since tests are your safety net.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run one test class:&lt;/strong&gt; &lt;code&gt;mvn test -Dtest=CalculatorTest&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Force re-download of snapshots and failed items:&lt;/strong&gt; &lt;code&gt;mvn package -U&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Work offline:&lt;/strong&gt; &lt;code&gt;mvn -o package&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;See the dependency tree:&lt;/strong&gt; &lt;code&gt;mvn dependency:tree&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;See the full merged POM:&lt;/strong&gt; &lt;code&gt;mvn help:effective-pom&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mvn package&lt;/code&gt;, &lt;code&gt;verify&lt;/code&gt; or &lt;code&gt;install&lt;/code&gt;?&lt;/strong&gt; Use &lt;code&gt;package&lt;/code&gt; to build the JAR. Use &lt;code&gt;verify&lt;/code&gt; when you also want the extra checks. Use &lt;code&gt;install&lt;/code&gt; when another project on your machine needs this one as a dependency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mvn clean package&lt;/code&gt; or just &lt;code&gt;package&lt;/code&gt;?&lt;/strong&gt; Use &lt;code&gt;clean&lt;/code&gt; when you want a guaranteed fresh build, for example after renaming or deleting files, so old &lt;code&gt;.class&lt;/code&gt; files don't linger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JAR or WAR?&lt;/strong&gt; A &lt;strong&gt;JAR&lt;/strong&gt; for libraries and normal applications. A &lt;strong&gt;WAR&lt;/strong&gt; for web apps that go on a server like Tomcat. (Frameworks such as Spring Boot also build runnable JARs with an embedded server.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SNAPSHOT or release?&lt;/strong&gt; Use &lt;code&gt;-SNAPSHOT&lt;/code&gt; while developing. Publish a &lt;strong&gt;release&lt;/strong&gt; version when something is finished and tagged, because releases never change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which scope?&lt;/strong&gt; &lt;code&gt;test&lt;/code&gt; for testing libraries, &lt;code&gt;provided&lt;/code&gt; for things the server gives you, &lt;code&gt;runtime&lt;/code&gt; for things only needed when running, and &lt;code&gt;compile&lt;/code&gt; for everything else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Archetype or generator website?&lt;/strong&gt; For plain Java, an archetype is great. For Spring Boot projects, most people use the Spring Initializr website, which creates a ready Maven project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maven or Gradle?&lt;/strong&gt; Both work well. Maven is more standard and predictable. Gradle is more flexible and often faster on big builds. Learning Maven first gives you the concepts that both share.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;JAVA_HOME&lt;/code&gt; or Java version problems.&lt;/strong&gt; If &lt;code&gt;mvn -v&lt;/code&gt; shows the wrong Java, or fails, fix &lt;code&gt;JAVA_HOME&lt;/code&gt;. Also set &lt;code&gt;maven.compiler.release&lt;/code&gt; in &lt;code&gt;pom.xml&lt;/code&gt; to match your JDK.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Running &lt;code&gt;java -jar&lt;/code&gt; on a JAR with no main class.&lt;/strong&gt; You get "no main manifest attribute." Set the main class in the jar plugin, or run it with &lt;code&gt;-cp&lt;/code&gt; and the class name.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wrong folders or test names.&lt;/strong&gt; Code outside &lt;code&gt;src/main/java&lt;/code&gt;, or tests outside &lt;code&gt;src/test/java&lt;/code&gt; or not named like &lt;code&gt;*Test&lt;/code&gt;, are silently ignored. "No tests to run" usually means this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skipping tests all the time.&lt;/strong&gt; &lt;code&gt;-DskipTests&lt;/code&gt; hides real problems. Use it rarely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version surprises.&lt;/strong&gt; Using &lt;code&gt;SNAPSHOT&lt;/code&gt; dependencies in something you release, or two libraries needing different versions of a third. Check with &lt;code&gt;mvn dependency:tree&lt;/code&gt;, and declare the version you want directly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stale or broken builds.&lt;/strong&gt; Old classes in &lt;code&gt;target/&lt;/code&gt; or a half-downloaded file in &lt;code&gt;~/.m2&lt;/code&gt; can cause strange errors. Run &lt;code&gt;mvn clean&lt;/code&gt;, and use &lt;code&gt;-U&lt;/code&gt; to force a fresh download.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;build tool&lt;/strong&gt; automates compile, test, package and dependency handling, so builds are repeatable on every machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency management&lt;/strong&gt; means you declare &lt;strong&gt;what&lt;/strong&gt; you need, and the tool downloads it, including what your libraries need.&lt;/li&gt;
&lt;li&gt;The code journey: &lt;strong&gt;&lt;code&gt;.java&lt;/code&gt; → &lt;code&gt;.class&lt;/code&gt; → unit tests → package → &lt;code&gt;.jar&lt;/code&gt; / &lt;code&gt;.war&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maven&lt;/strong&gt; follows &lt;strong&gt;convention over configuration&lt;/strong&gt;. It reads &lt;code&gt;pom.xml&lt;/code&gt;, runs the lifecycle, and uses &lt;strong&gt;plugins&lt;/strong&gt; to do each step.&lt;/li&gt;
&lt;li&gt;The standard layout: &lt;code&gt;src/main/java&lt;/code&gt;, &lt;code&gt;src/main/resources&lt;/code&gt;, &lt;code&gt;src/test/java&lt;/code&gt;, and output in &lt;code&gt;target/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;pom.xml&lt;/code&gt;&lt;/strong&gt; holds the project's identity (&lt;code&gt;groupId&lt;/code&gt;, &lt;code&gt;artifactId&lt;/code&gt;, &lt;code&gt;version&lt;/code&gt;, &lt;code&gt;packaging&lt;/code&gt;), properties, dependencies and plugins. It inherits defaults from the Super POM.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mvn archetype:generate&lt;/code&gt; creates a project from a template. &lt;code&gt;-D&lt;/code&gt; options set properties.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coordinates&lt;/strong&gt; (&lt;code&gt;groupId:artifactId:version&lt;/code&gt;) identify anything uniquely. &lt;code&gt;-SNAPSHOT&lt;/code&gt; means in development, and a release never changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Packaging&lt;/strong&gt; (&lt;code&gt;jar&lt;/code&gt;, &lt;code&gt;war&lt;/code&gt;, &lt;code&gt;pom&lt;/code&gt;) decides what is built.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Goals&lt;/strong&gt; are plugin tasks (&lt;code&gt;plugin:goal&lt;/code&gt;). &lt;strong&gt;Phases&lt;/strong&gt; are lifecycle steps. Running a phase runs all earlier ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repositories:&lt;/strong&gt; local (&lt;code&gt;~/.m2&lt;/code&gt;), central (Maven Central) and remote (company servers). &lt;code&gt;install&lt;/code&gt; goes to local, &lt;code&gt;deploy&lt;/code&gt; goes to remote.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lifecycles:&lt;/strong&gt; &lt;strong&gt;default&lt;/strong&gt; (&lt;code&gt;validate → compile → test → package → verify → install → deploy&lt;/code&gt;), &lt;strong&gt;clean&lt;/strong&gt; (deletes &lt;code&gt;target&lt;/code&gt;) and &lt;strong&gt;site&lt;/strong&gt; (generates documentation).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: generate a project with the &lt;code&gt;archetype:generate&lt;/code&gt; command from this post. Add the &lt;code&gt;Calculator&lt;/code&gt; class and &lt;code&gt;CalculatorTest&lt;/code&gt;, run &lt;code&gt;mvn test&lt;/code&gt;, and then break the test on purpose and run &lt;code&gt;mvn package&lt;/code&gt; to see that no JAR gets built. Fix it, run &lt;code&gt;mvn clean package&lt;/code&gt;, and find your JAR in &lt;code&gt;target/&lt;/code&gt;. Finally, run &lt;code&gt;mvn dependency:tree&lt;/code&gt; and &lt;code&gt;mvn help:effective-pom&lt;/code&gt; and see how much Maven was doing for you.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, add the Gson dependency, print some JSON from your &lt;code&gt;App&lt;/code&gt;, and then look inside &lt;code&gt;~/.m2/repository/com/google/code/gson&lt;/code&gt; to see the exact folder path your coordinates turned into.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

</description>
      <category>java</category>
      <category>maven</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Java var, Records and Sealed Classes Explained Simply</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Wed, 14 Oct 2026 16:12:27 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/java-var-records-and-sealed-classes-explained-simply-19nk</link>
      <guid>https://dev.to/mayur_bodhare/java-var-records-and-sealed-classes-explained-simply-19nk</guid>
      <description>&lt;p&gt;Java has a reputation for being wordy, and for a long time it earned it. To store a simple pair of numbers, I had to write a class with two fields, a constructor, two getters, &lt;code&gt;equals&lt;/code&gt;, &lt;code&gt;hashCode&lt;/code&gt; and &lt;code&gt;toString&lt;/code&gt;. That's around forty lines for something that is just "x and y." And a line like this made my eyes tired:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modern Java fixed a lot of this. In this post, we'll learn three features that make code shorter and safer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;var&lt;/code&gt;&lt;/strong&gt; (local variable type inference), so you stop repeating types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;record&lt;/code&gt;&lt;/strong&gt; classes, which give you data classes in one line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;sealed&lt;/code&gt;&lt;/strong&gt; classes, which let you say exactly which classes may extend yours.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the end, we'll combine all three in one small program. If you read the post about streams, you'll notice that these features fit with them very well.&lt;/p&gt;

&lt;p&gt;A quick note on versions, because each feature arrived at a different time: &lt;code&gt;var&lt;/code&gt; came in &lt;strong&gt;Java 10&lt;/strong&gt;, records are final in &lt;strong&gt;Java 16&lt;/strong&gt;, sealed classes in &lt;strong&gt;Java 17&lt;/strong&gt;, and the pattern-matching &lt;code&gt;switch&lt;/code&gt; that I use with sealed types is final in &lt;strong&gt;Java 21&lt;/strong&gt;. Any recent LTS version has all of them.&lt;/p&gt;

&lt;p&gt;Unless I show a full class, the snippets go inside a &lt;code&gt;main&lt;/code&gt; method. Records and other types are declared outside it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 1: var (local variable type inference)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is var?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;var&lt;/code&gt; lets the compiler &lt;strong&gt;work out the type of a local variable&lt;/strong&gt; from the value on the right side. This is called &lt;strong&gt;LVTI&lt;/strong&gt;, short for Local Variable Type Inference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Double&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The long line from the start of this post becomes much shorter, because the type was already written on the right side. Why say it twice?&lt;/p&gt;

&lt;h3&gt;
  
  
  var is NOT dynamic typing
&lt;/h3&gt;

&lt;p&gt;This is the most common misunderstanding. &lt;code&gt;var&lt;/code&gt; doesn't make Java behave like JavaScript. The variable still has &lt;strong&gt;one fixed type&lt;/strong&gt;, chosen at compile time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ASHA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then a compile error on the last line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;incompatible types: int cannot be converted to String
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;name&lt;/code&gt; is a &lt;code&gt;String&lt;/code&gt; forever. You can call &lt;code&gt;String&lt;/code&gt; methods on it, and you can't put a number in it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes
&lt;/h3&gt;

&lt;p&gt;The compiler simply &lt;strong&gt;replaces &lt;code&gt;var&lt;/code&gt; with the real type&lt;/strong&gt; while compiling. The bytecode is exactly the same as if you had written the type yourself, so &lt;code&gt;var&lt;/code&gt; has &lt;strong&gt;no cost at run time&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   var count = 10;                       --&amp;gt;   int count = 10;
   var names = new ArrayList&amp;lt;String&amp;gt;();  --&amp;gt;   ArrayList&amp;lt;String&amp;gt; names = new ArrayList&amp;lt;String&amp;gt;();

   The type is worked out when you COMPILE. Nothing changes when the program RUNS.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Where you can use it
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;var&lt;/code&gt; works for &lt;strong&gt;local variables&lt;/strong&gt;, in several places:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;                          &lt;span class="c1"&gt;// normal local variable&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;                 &lt;span class="c1"&gt;// classic for loop&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;              &lt;span class="c1"&gt;// enhanced for loop&lt;/span&gt;

&lt;span class="nc"&gt;BiFunction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;                &lt;span class="c1"&gt;// lambda parameters (Java 11+)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Where you can't
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   var x;                  error: cannot infer type (no initial value)
   var x = null;           error: cannot infer type (the value is 'null')
   var f = () -&amp;gt; 1;        error: cannot infer type (lambda needs a target type)
   var a = {1, 2, 3};      error: cannot infer type (array initializer needs a type)

   Also NOT allowed: fields, method parameters and return types.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler can only infer a type when the right side makes it clear. In all these cases, there's nothing (or not enough) to infer from. Also, &lt;code&gt;var&lt;/code&gt; is only for local variables, so it can't be used for class fields or in method signatures.&lt;/p&gt;

&lt;h3&gt;
  
  
  A gotcha: the diamond
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[a, 1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a normal declaration, &lt;code&gt;List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();&lt;/code&gt; tells the compiler to use &lt;code&gt;String&lt;/code&gt; for the diamond &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;. With &lt;code&gt;var&lt;/code&gt;, there's no target type, so the compiler picks &lt;code&gt;ArrayList&amp;lt;Object&amp;gt;&lt;/code&gt;, and the list accepts anything. Write &lt;code&gt;new ArrayList&amp;lt;String&amp;gt;()&lt;/code&gt; when you use &lt;code&gt;var&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Another small thing to know: &lt;code&gt;var list = new ArrayList&amp;lt;String&amp;gt;();&lt;/code&gt; has the type &lt;code&gt;ArrayList&amp;lt;String&amp;gt;&lt;/code&gt;, not &lt;code&gt;List&amp;lt;String&amp;gt;&lt;/code&gt;. If you want your variable to use the interface type (a good habit), write it out: &lt;code&gt;List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is var a good idea?
&lt;/h3&gt;

&lt;p&gt;It depends on &lt;strong&gt;readability&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Good:&lt;/strong&gt; the type is obvious from the right side. &lt;code&gt;var users = new ArrayList&amp;lt;User&amp;gt;();&lt;/code&gt; and &lt;code&gt;var reader = new BufferedReader(...);&lt;/code&gt; need no extra explanation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not good:&lt;/strong&gt; the right side hides the type. In &lt;code&gt;var result = process(data);&lt;/code&gt;, a reader has to look up &lt;code&gt;process&lt;/code&gt; to learn what &lt;code&gt;result&lt;/code&gt; is.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good rule: use &lt;code&gt;var&lt;/code&gt; when it removes &lt;strong&gt;repetition&lt;/strong&gt;, and use the explicit type when it adds &lt;strong&gt;information&lt;/strong&gt;. And since the type is no longer visible, choose clear variable names.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: Records
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The problem: so much code for plain data
&lt;/h3&gt;

&lt;p&gt;Here is a simple class that just carries two numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PointClass&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;PointClass&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getX&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getY&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;PointClass&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;PointClass&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PointClass&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;hashCode&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"PointClass[x="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", y="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"]"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a lot of text, and every line is boilerplate (code you write only because the language requires it). A &lt;strong&gt;record&lt;/strong&gt; does the same in one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Point&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Point&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hashCode&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;hashCode&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Point[x=3, y=4]
3
true
true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two points with the same values are &lt;strong&gt;equal&lt;/strong&gt;, even though they are different objects. Records compare by &lt;strong&gt;value&lt;/strong&gt;, not by identity.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the compiler writes for you
&lt;/h3&gt;

&lt;p&gt;The list in the parentheses, &lt;code&gt;(int x, int y)&lt;/code&gt;, is called the record's &lt;strong&gt;components&lt;/strong&gt;. For them, the compiler generates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   record Point(int x, int y) { }
            |
            |   the compiler expands it into roughly this:
            v
   final class Point extends java.lang.Record {
       private final int x;
       private final int y;

       Point(int x, int y) { ... }         // the "canonical" constructor
       int x() { return x; }               // accessors: note, NO "get" prefix
       int y() { return y; }
       boolean equals(Object o) { ... }    // compares all components
       int hashCode() { ... }
       String toString() { ... }           // Point[x=3, y=4]
   }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can verify the hidden parts yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSuperclass&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reflect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Modifier&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isFinal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getModifiers&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class java.lang.Record
true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So a record is a real class. It's &lt;strong&gt;final&lt;/strong&gt; (nobody can extend it), and its parent is &lt;code&gt;java.lang.Record&lt;/code&gt;. (Behind the scenes, the generated &lt;code&gt;equals&lt;/code&gt;, &lt;code&gt;hashCode&lt;/code&gt; and &lt;code&gt;toString&lt;/code&gt; are wired up with the same &lt;code&gt;invokedynamic&lt;/code&gt; mechanism we saw with lambdas.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Validation with a compact constructor
&lt;/h3&gt;

&lt;p&gt;What if you want to reject bad values? Write a &lt;strong&gt;compact constructor&lt;/strong&gt;. It has the record's name but &lt;strong&gt;no parentheses&lt;/strong&gt;. It runs before the fields are set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Age&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Age cannot be negative"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;(-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IllegalArgumentException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Age[value=25]
Error: Age cannot be negative
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also &lt;strong&gt;adjust&lt;/strong&gt; a value in the compact constructor by reassigning the parameter. And records can have their own methods and static helpers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;trim&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;greeting&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hi, "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="nf"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"  Asha "&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;greeting&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Person[name=Asha, age=25]
Hi, Ravi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The rules of records
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A record is &lt;strong&gt;implicitly &lt;code&gt;final&lt;/code&gt;&lt;/strong&gt; and can't extend another class (it already extends &lt;code&gt;Record&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;can implement interfaces&lt;/strong&gt;, and it can be generic, like &lt;code&gt;record Pair&amp;lt;A, B&amp;gt;(A first, B second)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The component fields are &lt;strong&gt;&lt;code&gt;private final&lt;/code&gt;&lt;/strong&gt;. You &lt;strong&gt;can't add extra instance fields&lt;/strong&gt;, and there are no setters.&lt;/li&gt;
&lt;li&gt;You can add &lt;strong&gt;methods&lt;/strong&gt;, &lt;strong&gt;static methods&lt;/strong&gt; and &lt;strong&gt;static fields&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Any extra constructor must call the canonical one with &lt;code&gt;this(...)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A trap: records are shallowly immutable
&lt;/h3&gt;

&lt;p&gt;The fields can't be reassigned, but if a field &lt;strong&gt;holds a changeable object&lt;/strong&gt;, that object can still change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Team&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;members&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;members&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Team&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Core"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;members&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;members&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;team&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Team[name=Core, members=[Asha, Ravi]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The team changed even though we never touched the record! The fix is a &lt;strong&gt;defensive copy&lt;/strong&gt; in the compact constructor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;SafeTeam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;members&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;SafeTeam&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;members&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;copyOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;members&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;members&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SafeTeam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Core"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;members&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;members&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;team&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SafeTeam[name=Core, members=[Asha]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the record keeps its own unchangeable copy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Records work nicely with streams
&lt;/h3&gt;

&lt;p&gt;Because the accessors are plain methods, they fit method references:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Student&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Meera"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;95&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Student:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Asha
Meera
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Records are ideal for small data carriers: results that return several values, map keys, DTOs (objects that carry data between layers) and test data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 3: Sealed classes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The problem: inheritance is too open
&lt;/h3&gt;

&lt;p&gt;Normally, if you write &lt;code&gt;interface Shape&lt;/code&gt;, &lt;strong&gt;anyone&lt;/strong&gt; can implement it, anywhere, at any time. That's flexible, but sometimes it's a problem. Imagine you want to say "a &lt;code&gt;Shape&lt;/code&gt; is &lt;strong&gt;only&lt;/strong&gt; a &lt;code&gt;Circle&lt;/code&gt; or a &lt;code&gt;Rectangle&lt;/code&gt;, nothing else." With normal inheritance, you can't say that, and the compiler can never be sure it has seen every possible shape.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;sealed&lt;/strong&gt; class or interface solves this. It lists exactly which classes may extend or implement it, using the &lt;code&gt;permits&lt;/code&gt; keyword:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="n"&gt;permits&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Rectangle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Circle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Rectangle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Normal hierarchy:    Shape  &amp;lt;---  anyone can extend it (unknown subclasses)

   Sealed hierarchy:    Shape  &amp;lt;---  ONLY Circle and Rectangle
                                     the compiler knows ALL the cases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If another class tries to join the family uninvited:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Triangle&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class is not allowed to extend sealed class: Shape (as it is not listed in its 'permits' clause)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The three choices for a subclass
&lt;/h3&gt;

&lt;p&gt;Every class that is permitted by a sealed class must declare what happens &lt;strong&gt;next&lt;/strong&gt; in the family, with one of three keywords:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;final&lt;/code&gt;:&lt;/strong&gt; no more subclasses. The family ends here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;sealed&lt;/code&gt;:&lt;/strong&gt; it restricts its own subclasses again, with its own &lt;code&gt;permits&lt;/code&gt; list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;non-sealed&lt;/code&gt;:&lt;/strong&gt; it opens the hierarchy back up, so anyone may extend it.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="n"&gt;permits&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Truck&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Bike&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Truck&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="n"&gt;permits&lt;/span&gt; &lt;span class="nc"&gt;Pickup&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pickup&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Truck&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;non&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bike&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              Vehicle  (sealed)
             /    |     \
          Car   Truck    Bike
        final  sealed   non-sealed
                  |
               Pickup
                final
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Records are automatically &lt;code&gt;final&lt;/code&gt;, which is why they pair so well with sealed interfaces. A few more rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A permitted subclass must &lt;strong&gt;directly&lt;/strong&gt; extend the sealed class.&lt;/li&gt;
&lt;li&gt;It must be in the &lt;strong&gt;same module&lt;/strong&gt; (or the same package, if your project doesn't use modules).&lt;/li&gt;
&lt;li&gt;If all the subclasses are in the &lt;strong&gt;same file&lt;/strong&gt; as the sealed class, you can leave out &lt;code&gt;permits&lt;/code&gt;, and the compiler works it out.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The payoff: exhaustive switch
&lt;/h3&gt;

&lt;p&gt;Because the compiler knows &lt;strong&gt;every possible subtype&lt;/strong&gt;, a &lt;code&gt;switch&lt;/code&gt; over a sealed type doesn't need a &lt;code&gt;default&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;area&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Shape&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Rectangle&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;area&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;area&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Rectangle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3.141592653589793
12.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(This pattern-matching &lt;code&gt;switch&lt;/code&gt; needs Java 21 or newer.) The best part comes later. Imagine you add a &lt;code&gt;Triangle&lt;/code&gt; to the permits list but forget to update &lt;code&gt;area&lt;/code&gt;. The code &lt;strong&gt;stops compiling&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;the switch expression does not cover all possible input values
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler found the bug for you, long before a user would. That's the real value of sealed types: when the set of cases changes, every place that must handle them is flagged.&lt;/p&gt;

&lt;p&gt;In Java 21 and newer, you can even take a record apart inside the &lt;code&gt;case&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;             &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nf"&gt;Rectangle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A practical example: success or failure
&lt;/h3&gt;

&lt;p&gt;A common use is a result type that is &lt;em&gt;either&lt;/em&gt; a success &lt;em&gt;or&lt;/em&gt; a failure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Result&lt;/span&gt; &lt;span class="n"&gt;permits&lt;/span&gt; &lt;span class="nc"&gt;Success&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Failure&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Success&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Result&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Failure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Result&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Result&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Success&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"OK: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Failure&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"Error: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;describe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Success&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"saved"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;describe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Failure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"timeout"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OK: saved
Error: timeout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Behind the scenes
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;permits&lt;/code&gt; list is stored inside the &lt;code&gt;.class&lt;/code&gt; file. When a class is loaded, the JVM checks it, so the rule is enforced both by the compiler &lt;strong&gt;and&lt;/strong&gt; at run time. You can even read it with reflection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Shape&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isSealed&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPermittedSubclasses&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSimpleName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;true
Circle
Rectangle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sealed vs enum vs final
&lt;/h3&gt;

&lt;p&gt;These three often get confused:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;final&lt;/code&gt;&lt;/strong&gt; means no subclasses at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;enum&lt;/code&gt;&lt;/strong&gt; means a fixed set of &lt;strong&gt;objects&lt;/strong&gt; (like &lt;code&gt;MONDAY&lt;/code&gt;, &lt;code&gt;TUESDAY&lt;/code&gt;), each created once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;sealed&lt;/code&gt;&lt;/strong&gt; means a fixed set of &lt;strong&gt;types&lt;/strong&gt;, and each type can have many objects, usually with different data (a &lt;code&gt;Circle&lt;/code&gt; has a radius, and a &lt;code&gt;Rectangle&lt;/code&gt; has a width and height).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Putting it all together
&lt;/h2&gt;

&lt;p&gt;Let's use everything in one small program: a tiny calculator that models expressions as a sealed hierarchy of records, walks them with a &lt;code&gt;switch&lt;/code&gt;, and uses &lt;code&gt;var&lt;/code&gt; for the local variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Expr&lt;/span&gt; &lt;span class="n"&gt;permits&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Add&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Mul&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Num&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Expr&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Expr&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Expr&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Expr&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Mul&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Expr&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Expr&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Expr&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Expr&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Add&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;eval&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;left&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;eval&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;right&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Mul&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;eval&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;left&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;eval&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;right&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="o"&gt;};&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;expr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Mul&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Num&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eval&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;14
Add[left=Num[value=2], right=Mul[left=Num[value=3], right=Num[value=4]]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at how each feature helped:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Records&lt;/strong&gt; gave us four tiny data types in four lines, and a readable &lt;code&gt;toString&lt;/code&gt; for free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sealed&lt;/strong&gt; told the compiler that &lt;code&gt;Expr&lt;/code&gt; is only &lt;code&gt;Num&lt;/code&gt;, &lt;code&gt;Add&lt;/code&gt; or &lt;code&gt;Mul&lt;/code&gt;, so &lt;code&gt;eval&lt;/code&gt; needs no &lt;code&gt;default&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;switch&lt;/code&gt;&lt;/strong&gt; with patterns unpacked each case without casts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;var&lt;/code&gt;&lt;/strong&gt; kept the long type name out of &lt;code&gt;main&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try adding a &lt;code&gt;Sub&lt;/code&gt; record to the &lt;code&gt;permits&lt;/code&gt; list, and watch the compiler point at &lt;code&gt;eval&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;var&lt;/code&gt; or the explicit type?&lt;/strong&gt; Use &lt;code&gt;var&lt;/code&gt; when the right side already shows the type (&lt;code&gt;new ArrayList&amp;lt;String&amp;gt;()&lt;/code&gt;, a constructor call, a clearly named factory). Use the explicit type when it helps the reader, or when you want an interface type like &lt;code&gt;List&amp;lt;String&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Record or class?&lt;/strong&gt; Use a &lt;strong&gt;record&lt;/strong&gt; for plain, unchangeable data carriers: DTOs, map keys, multiple return values, test data. Use a &lt;strong&gt;class&lt;/strong&gt; when you need changeable state, inheritance, hidden internal data or behavior that doesn't revolve around the data. Many frameworks that need changeable, proxied objects (such as JPA entities) don't fit records.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sealed, enum or open interface?&lt;/strong&gt; Use an &lt;strong&gt;enum&lt;/strong&gt; for a fixed set of constants. Use a &lt;strong&gt;sealed&lt;/strong&gt; hierarchy for a fixed set of types that carry different data. Use a normal &lt;strong&gt;open&lt;/strong&gt; interface when other people should be able to add their own implementations (a plugin system, for example).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Records and sealed together?&lt;/strong&gt; This is a great combination for modeling "one of several shapes of data," like results, events, commands and expressions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Using &lt;code&gt;var&lt;/code&gt; when the type becomes unclear.&lt;/strong&gt; If a reader can't tell what the variable is without hunting, write the type. Also remember &lt;code&gt;var list = new ArrayList&amp;lt;&amp;gt;()&lt;/code&gt; gives you &lt;code&gt;ArrayList&amp;lt;Object&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thinking &lt;code&gt;var&lt;/code&gt; makes Java dynamic.&lt;/strong&gt; The type is fixed at compile time. You can't assign a different type later, and you can't use &lt;code&gt;var&lt;/code&gt; for fields, parameters or return types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming records are fully immutable.&lt;/strong&gt; If a component is a list or another changeable object, it can still change. Make a defensive copy in the compact constructor, and remember that you can't add instance fields or setters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using the wrong accessor name.&lt;/strong&gt; A record's accessor is &lt;code&gt;p.x()&lt;/code&gt;, not &lt;code&gt;p.getX()&lt;/code&gt;. And equality is based on &lt;strong&gt;values&lt;/strong&gt;, so two records with the same data are &lt;code&gt;equals&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forgetting what a permitted subclass must say.&lt;/strong&gt; Each one has to be &lt;code&gt;final&lt;/code&gt;, &lt;code&gt;sealed&lt;/code&gt; or &lt;code&gt;non-sealed&lt;/code&gt;, and it must sit in the same module (or package). Otherwise, the code won't compile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adding a &lt;code&gt;default&lt;/code&gt; branch to a switch over a sealed type.&lt;/strong&gt; It silences the compiler's exhaustiveness check. When you add a new subtype later, it falls into &lt;code&gt;default&lt;/code&gt; without any warning. Leave &lt;code&gt;default&lt;/code&gt; out so the compiler can protect you.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;var&lt;/code&gt;&lt;/strong&gt; lets the compiler infer the type of a &lt;strong&gt;local variable&lt;/strong&gt;. The type is still fixed at compile time, and the bytecode is the same as if you'd written it out.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;var&lt;/code&gt; needs an initial value that shows the type. It can't be used for fields, parameters, return types, &lt;code&gt;null&lt;/code&gt; or lambdas without a target type. Use it when it removes repetition, not when it hides the type.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;record&lt;/strong&gt; is a one-line data class. The compiler generates the final fields, canonical constructor, accessors like &lt;code&gt;x()&lt;/code&gt;, and &lt;code&gt;equals&lt;/code&gt;, &lt;code&gt;hashCode&lt;/code&gt; and &lt;code&gt;toString&lt;/code&gt;. It's implicitly &lt;code&gt;final&lt;/code&gt;, extends &lt;code&gt;java.lang.Record&lt;/code&gt; and can't have extra instance fields.&lt;/li&gt;
&lt;li&gt;Use a &lt;strong&gt;compact constructor&lt;/strong&gt; for validation, and make a &lt;strong&gt;defensive copy&lt;/strong&gt; of changeable components.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;sealed&lt;/strong&gt; class or interface lists its allowed subclasses with &lt;code&gt;permits&lt;/code&gt;. Each one must be &lt;code&gt;final&lt;/code&gt;, &lt;code&gt;sealed&lt;/code&gt; or &lt;code&gt;non-sealed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Sealed types give you an &lt;strong&gt;exhaustive &lt;code&gt;switch&lt;/code&gt;&lt;/strong&gt; with no &lt;code&gt;default&lt;/code&gt;, so the compiler tells you when you forget a case.&lt;/li&gt;
&lt;li&gt;Records plus sealed interfaces plus pattern-matching &lt;code&gt;switch&lt;/code&gt; is a powerful modern-Java pattern.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: model a payment system. Create a &lt;code&gt;sealed interface Payment permits Card, Upi, Cash&lt;/code&gt;, with a record for each, such as &lt;code&gt;Card(String number, int amount)&lt;/code&gt;, &lt;code&gt;Upi(String id, int amount)&lt;/code&gt; and &lt;code&gt;Cash(int amount)&lt;/code&gt;. Write a method &lt;code&gt;fee(Payment p)&lt;/code&gt; that returns a different fee for each, using a &lt;code&gt;switch&lt;/code&gt; with no &lt;code&gt;default&lt;/code&gt;. Use &lt;code&gt;var&lt;/code&gt; for your local variables in &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, add a new record &lt;code&gt;NetBanking&lt;/code&gt; to the &lt;code&gt;permits&lt;/code&gt; list, and read the compiler error on your &lt;code&gt;switch&lt;/code&gt;. Then handle the new case and see it compile again.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

&lt;p&gt;That wraps up this two-part series on modern Java.&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Java Stream API for Beginners: From Loops to Pipelines</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Wed, 14 Oct 2026 11:01:25 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/java-stream-api-for-beginners-from-loops-to-pipelines-1p76</link>
      <guid>https://dev.to/mayur_bodhare/java-stream-api-for-beginners-from-loops-to-pipelines-1p76</guid>
      <description>&lt;p&gt;For a long time, my Java code for "take this list, keep the long names, make them uppercase, collect the result" was six lines of loop, an &lt;code&gt;if&lt;/code&gt; and a temporary list. Then I saw this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One line. It read almost like English, but it also raised questions. What is a stream? What does &lt;code&gt;String::toUpperCase&lt;/code&gt; mean? And why do some methods in this style return something called &lt;code&gt;Optional&lt;/code&gt; instead of just the value?&lt;/p&gt;

&lt;p&gt;In this post, we'll answer those questions in order: &lt;strong&gt;method references and constructor references&lt;/strong&gt; (the &lt;code&gt;::&lt;/code&gt; syntax), the &lt;strong&gt;Stream API&lt;/strong&gt;, and the &lt;strong&gt;&lt;code&gt;Optional&lt;/code&gt; class&lt;/strong&gt;. They fit together, so by the end you'll be able to read and write the one-liner above with confidence. If you haven't read about lambdas, skim that first, because everything here builds on them.&lt;/p&gt;

&lt;p&gt;All the snippets assume these imports and go inside a &lt;code&gt;main&lt;/code&gt; method unless I show a full class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.function.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.stream.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Part 1: Method references and constructor references
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;method reference&lt;/strong&gt; is a shorter way to write a lambda that does nothing except call one existing method. You write the class (or object), then &lt;code&gt;::&lt;/code&gt;, then the method name, with &lt;strong&gt;no brackets&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;         &lt;span class="c1"&gt;// lambda&lt;/span&gt;
&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;          &lt;span class="c1"&gt;// method reference, same meaning&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are four kinds. Here they are with their lambda twins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   KIND                          REFERENCE              SAME AS THIS LAMBDA
   1. static method              Integer::parseInt      s -&amp;gt; Integer.parseInt(s)
   2. method of a given object   prefix::concat         s -&amp;gt; prefix.concat(s)
   3. method of "any" object     String::length         s -&amp;gt; s.length()
      of a type
   4. constructor                Person::new            n -&amp;gt; new Person(n)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's see them one by one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. static method&lt;/span&gt;
&lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;parseInt&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"42"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 2. method of a specific object we already have&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello, "&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;greet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nl"&gt;prefix:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;concat&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// 3. method of an object that will be given to us later&lt;/span&gt;
&lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"lambda"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;BiFunction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;same&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;equalsIgnoreCase&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;same&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Java"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"JAVA"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;43
Hello, Asha
6
true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kind 3 is the one that confuses people. In &lt;code&gt;String::length&lt;/code&gt;, no object is named, so where does the string come from? From the &lt;strong&gt;first parameter&lt;/strong&gt; of the functional interface. &lt;code&gt;Function&amp;lt;String, Integer&amp;gt;&lt;/code&gt; gives us one &lt;code&gt;String&lt;/code&gt;, and Java calls &lt;code&gt;.length()&lt;/code&gt; &lt;strong&gt;on it&lt;/strong&gt;. In &lt;code&gt;String::equalsIgnoreCase&lt;/code&gt;, the first parameter is the object, and the second is the argument: &lt;code&gt;(a, b) -&amp;gt; a.equalsIgnoreCase(b)&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constructor references
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;constructor reference&lt;/strong&gt; uses &lt;code&gt;::new&lt;/code&gt;. It's a lambda that creates an object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Person("&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;")"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;maker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nl"&gt;Person:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;Supplier&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;listMaker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nl"&gt;ArrayList:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;IntFunction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;arrayMaker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]::&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;listMaker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"x"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arrayMaker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Person(Asha)
[x]
3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How does Java know which constructor &lt;code&gt;Person::new&lt;/code&gt; means? It looks at the &lt;strong&gt;functional interface&lt;/strong&gt;. &lt;code&gt;Function&amp;lt;String, Person&amp;gt;&lt;/code&gt; takes a &lt;code&gt;String&lt;/code&gt;, so Java picks &lt;code&gt;Person(String)&lt;/code&gt;. &lt;code&gt;Supplier&amp;lt;List&amp;lt;String&amp;gt;&amp;gt;&lt;/code&gt; takes nothing, so &lt;code&gt;ArrayList::new&lt;/code&gt; means the no-argument constructor. The same words, &lt;code&gt;ArrayList::new&lt;/code&gt;, can mean different constructors depending on the target type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes
&lt;/h3&gt;

&lt;p&gt;Method references work like lambdas. The compiler doesn't create a separate class for them. It writes an &lt;code&gt;invokedynamic&lt;/code&gt; instruction, and the JVM builds the function object at run time. The compiler picks the method by matching the &lt;strong&gt;parameter types&lt;/strong&gt; of the functional interface. If two methods could fit, you get an "ambiguous method reference" error, and the fix is to write a normal lambda.&lt;/p&gt;

&lt;p&gt;Use a method reference when it makes the code &lt;strong&gt;shorter and clearer&lt;/strong&gt;. If the lambda does more than one call, or the reference looks cryptic, keep the arrow form.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 2: The Stream API
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a stream?
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;stream&lt;/strong&gt; is a &lt;strong&gt;pipeline for processing a sequence of data&lt;/strong&gt;, usually from a collection. It's not a data structure. It doesn't store anything, and it &lt;strong&gt;never changes the original collection&lt;/strong&gt;. Think of a factory conveyor belt: items come in, pass through stations and come out the other end.&lt;/p&gt;

&lt;p&gt;Every stream pipeline has three parts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   SOURCE            INTERMEDIATE operations           TERMINAL operation
   (where data   --&amp;gt;  (each one returns a stream)  --&amp;gt;  (produces a result
    comes from)                                          and starts the work)

   list.stream()  --&amp;gt; filter(...) --&amp;gt; map(...) --&amp;gt; sorted() --&amp;gt; collect(...) / count() / forEach(...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source:&lt;/strong&gt; &lt;code&gt;list.stream()&lt;/code&gt;, &lt;code&gt;Arrays.stream(array)&lt;/code&gt;, &lt;code&gt;Stream.of(...)&lt;/code&gt;, &lt;code&gt;IntStream.rangeClosed(1, 5)&lt;/code&gt; and others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intermediate operations:&lt;/strong&gt; &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;sorted&lt;/code&gt;, &lt;code&gt;distinct&lt;/code&gt;, &lt;code&gt;limit&lt;/code&gt;, &lt;code&gt;skip&lt;/code&gt;, &lt;code&gt;flatMap&lt;/code&gt;. Each one returns a new stream, so you can chain them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminal operation:&lt;/strong&gt; &lt;code&gt;collect&lt;/code&gt;, &lt;code&gt;toList&lt;/code&gt;, &lt;code&gt;forEach&lt;/code&gt;, &lt;code&gt;count&lt;/code&gt;, &lt;code&gt;sum&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;, &lt;code&gt;min&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt;, &lt;code&gt;findFirst&lt;/code&gt;, &lt;code&gt;anyMatch&lt;/code&gt; and others. It ends the pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  From a loop to a stream
&lt;/h3&gt;

&lt;p&gt;Here's the task from my intro, done the old way and the stream way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Meera"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jo"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jo"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// the old way&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// the stream way&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[MEERA, RAVI, ASHA]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;filter&lt;/code&gt; keeps the items where the condition is true (a &lt;code&gt;Predicate&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;map&lt;/code&gt; transforms each item into something else (a &lt;code&gt;Function&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;toList()&lt;/code&gt; collects the result into a list. (It needs Java 16 or newer. In older versions, write &lt;code&gt;.collect(Collectors.toList())&lt;/code&gt;.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stream version says &lt;strong&gt;what&lt;/strong&gt; you want. The loop says &lt;strong&gt;how&lt;/strong&gt; to do it step by step.&lt;/p&gt;

&lt;h3&gt;
  
  
  The operations you'll use most
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;distinct&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;sorted&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;mapToInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;intValue&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;reduce&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;compare&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;anyMatch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 3, 5, 8]
4
37
37
Optional[9]
true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's read them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;distinct().sorted().limit(4)&lt;/code&gt; removed duplicates, sorted, then kept the first four.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;count()&lt;/code&gt; counted the numbers bigger than 4 (5, 8, 9, 8).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mapToInt(...).sum()&lt;/code&gt; and &lt;code&gt;reduce(0, Integer::sum)&lt;/code&gt; both add everything up. &lt;code&gt;reduce&lt;/code&gt; repeatedly combines two values into one, starting from &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max(...)&lt;/code&gt; returns an &lt;code&gt;Optional&lt;/code&gt;, which we'll meet in the next part. Here it printed as &lt;code&gt;Optional[9]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;anyMatch&lt;/code&gt; checks whether at least one item passes. (&lt;code&gt;allMatch&lt;/code&gt; and &lt;code&gt;noneMatch&lt;/code&gt; work the same way.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A tip: for numbers, prefer &lt;code&gt;mapToInt(...)&lt;/code&gt; and the primitive streams (&lt;code&gt;IntStream&lt;/code&gt;, &lt;code&gt;LongStream&lt;/code&gt;, &lt;code&gt;DoubleStream&lt;/code&gt;). They avoid the boxing cost we discussed in the wrapper classes topic, and they give you &lt;code&gt;sum()&lt;/code&gt;, &lt;code&gt;average()&lt;/code&gt; and similar methods for free.&lt;/p&gt;

&lt;h3&gt;
  
  
  Collecting results: Collectors
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;collect&lt;/code&gt; takes a &lt;strong&gt;collector&lt;/strong&gt;, a recipe for building the final result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Meera"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jo"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jo"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;distinct&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;joining&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;", "&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"["&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"]"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;

&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;byLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;distinct&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;groupingBy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;TreeMap:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byLength&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;frequency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;groupingBy&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;TreeMap:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;counting&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frequency&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Meera, Jo, Ravi, Asha]
{2=[Jo], 4=[Ravi, Asha], 5=[Meera]}
{Asha=1, Jo=2, Meera=1, Ravi=1}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;joining&lt;/code&gt; glued the names into one string.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;groupingBy&lt;/code&gt; made a map from each key (the length) to the list of items that share it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;counting&lt;/code&gt; counted the items in each group.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Look closely at &lt;code&gt;TreeMap::new&lt;/code&gt;. That's a &lt;strong&gt;constructor reference&lt;/strong&gt; from earlier, used to say "put the result in a &lt;code&gt;TreeMap&lt;/code&gt;," so the keys come out sorted.&lt;/p&gt;

&lt;h3&gt;
  
  
  flatMap: flattening nested lists
&lt;/h3&gt;

&lt;p&gt;When each item turns into &lt;strong&gt;several&lt;/strong&gt; items, or you have a list of lists, use &lt;code&gt;flatMap&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nested&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;flat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nested&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flatMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;List:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flat&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 2, 3, 4, 5]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;map&lt;/code&gt; would give you a stream of streams. &lt;code&gt;flatMap&lt;/code&gt; merges them into one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Streams are lazy
&lt;/h3&gt;

&lt;p&gt;This is the most surprising thing about streams. Intermediate operations &lt;strong&gt;do nothing&lt;/strong&gt; until a terminal operation starts the pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"bb"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"ccc"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"filter "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Nothing printed yet"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"got "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nothing printed yet
filter a
filter bb
got bb
filter ccc
got ccc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two lessons are hidden here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Nothing ran&lt;/strong&gt; when we built the pipeline. The &lt;code&gt;filter&lt;/code&gt; code only ran after &lt;code&gt;forEach&lt;/code&gt;, the terminal operation, started the work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Each item travels through the whole pipeline before the next one starts.&lt;/strong&gt; It's not "filter everything, then print everything." It's item by item:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   "a"    -&amp;gt; filter (fails)  -&amp;gt; stops here
   "bb"   -&amp;gt; filter (passes) -&amp;gt; forEach prints "got bb"
   "ccc"  -&amp;gt; filter (passes) -&amp;gt; forEach prints "got ccc"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Laziness also allows &lt;strong&gt;short-circuiting&lt;/strong&gt;. Operations like &lt;code&gt;findFirst&lt;/code&gt; and &lt;code&gt;limit&lt;/code&gt; can stop early:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"check "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;})&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findFirst&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ifPresent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"first even: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;check 1
check 2
first even: 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It never even looked at 3, 4 or 5.&lt;/p&gt;

&lt;h3&gt;
  
  
  Streams can be used only once
&lt;/h3&gt;

&lt;p&gt;After a terminal operation, the stream is finished:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1
2
3
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need it again, create a new stream from the source.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes
&lt;/h3&gt;

&lt;p&gt;When you chain &lt;code&gt;filter(...)&lt;/code&gt; and &lt;code&gt;map(...)&lt;/code&gt;, Java doesn't process any data. It just builds a &lt;strong&gt;chain of stages&lt;/strong&gt;, like a recipe. Only when the terminal operation runs does it pull items from the source through all the stages. Because of this, the stages can be &lt;strong&gt;fused&lt;/strong&gt; into one pass over the data, and short-circuit operations can stop early. A few operations, like &lt;code&gt;sorted()&lt;/code&gt;, need to see &lt;strong&gt;all&lt;/strong&gt; items before they can pass any on, so they act as a wall in the pipeline.&lt;/p&gt;

&lt;p&gt;Also, the lambdas you write become the standard functional interfaces we learned about: &lt;code&gt;Predicate&lt;/code&gt; for &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;Function&lt;/code&gt; for &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;Consumer&lt;/code&gt; for &lt;code&gt;forEach&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Two rules keep streams safe: &lt;strong&gt;don't change the source&lt;/strong&gt; while a pipeline runs, and &lt;strong&gt;avoid side effects&lt;/strong&gt; inside the lambdas (like adding to an outside list). Use &lt;code&gt;collect&lt;/code&gt; to build results instead.&lt;/p&gt;

&lt;p&gt;You may also see &lt;code&gt;.parallelStream()&lt;/code&gt;, which splits the work across several threads. It can speed up big, CPU-heavy jobs, but for small data it's usually slower, and shared mutable state can cause bugs. Don't reach for it by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part 3: The Optional class
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The problem: null
&lt;/h3&gt;

&lt;p&gt;You've probably met this error many times:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exception in thread "main" java.lang.NullPointerException
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It happens when a method returns &lt;code&gt;null&lt;/code&gt; ("no result") and the caller forgets to check. The method signature &lt;code&gt;String findEmail(String user)&lt;/code&gt; doesn't tell you that &lt;code&gt;null&lt;/code&gt; is possible. You only find out when the program crashes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;Optional&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/strong&gt; fixes this by making "maybe no value" &lt;strong&gt;visible in the type&lt;/strong&gt;. It's a small container that either holds one value or is empty. When you see &lt;code&gt;Optional&amp;lt;String&amp;gt;&lt;/code&gt; as a return type, you know right away: "there might be nothing here, and I must deal with that."&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating an Optional
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;           &lt;span class="c1"&gt;// value must NOT be null&lt;/span&gt;
&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// null becomes "empty"&lt;/span&gt;
&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;empty&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;              &lt;span class="c1"&gt;// explicitly empty&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Optional[Asha]
Optional.empty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;ofNullable&lt;/code&gt; when the value might be null. &lt;code&gt;Optional.of(null)&lt;/code&gt; throws a &lt;code&gt;NullPointerException&lt;/code&gt; immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using an Optional
&lt;/h3&gt;

&lt;p&gt;Don't pull the value out and test it by hand. Use the methods that handle both cases for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;none&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;empty&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;orElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"unknown"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;orElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"unknown"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ifPresent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;none&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ifPresentOrElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No name"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ASHA
unknown
Hello Asha
No name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;map(...)&lt;/code&gt; transforms the value if there is one, and does nothing if empty.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;filter(...)&lt;/code&gt; keeps the value only if it passes a test.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;orElse(default)&lt;/code&gt; gives the value, or a default.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;orElseGet(supplier)&lt;/code&gt; gives the value, or calls a supplier to make a default.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;orElseThrow(...)&lt;/code&gt; gives the value, or throws an exception you choose.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ifPresent(...)&lt;/code&gt; and &lt;code&gt;ifPresentOrElse(...)&lt;/code&gt; run code depending on the case.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;isPresent()&lt;/code&gt; and &lt;code&gt;isEmpty()&lt;/code&gt; check without reading.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get()&lt;/code&gt; returns the value, but throws &lt;code&gt;NoSuchElementException&lt;/code&gt; if empty. Avoid it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A real example: a method that returns Optional
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;emails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"asha@example.com"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;findEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"asha"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;orElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"no email"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;findEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ravi"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;orElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"no email"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="n"&gt;findEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ravi"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;ifPresentOrElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Email: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Missing"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;asha@example.com
no email
Missing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the caller &lt;strong&gt;can't forget&lt;/strong&gt; the empty case. The type forces the question.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chaining instead of nested null checks
&lt;/h3&gt;

&lt;p&gt;Optional shines when you chain steps that each might fail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;trim&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"EMPTY"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"  hi "&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"   "&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HI
EMPTY
EMPTY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same logic with &lt;code&gt;if (input != null) { ... }&lt;/code&gt; would take several nested checks. Here, if any step fails (null, or blank after trimming), the whole chain turns into "empty" and falls to &lt;code&gt;orElse&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  orElse vs orElseGet: a hidden trap
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;expensive&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"computing default"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"default"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;present&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"value"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;present&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expensive&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;present&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseGet&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;expensive&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;computing default
value
value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though the Optional had a value, the first line still ran &lt;code&gt;expensive()&lt;/code&gt;. With &lt;code&gt;orElse&lt;/code&gt;, Java computes the argument &lt;strong&gt;before&lt;/strong&gt; the call, whether it's needed or not. With &lt;code&gt;orElseGet&lt;/code&gt;, you pass a &lt;code&gt;Supplier&lt;/code&gt;, and it runs only if the Optional is empty. For cheap constants, &lt;code&gt;orElse&lt;/code&gt; is fine. For anything that does real work, use &lt;code&gt;orElseGet&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optional and streams
&lt;/h3&gt;

&lt;p&gt;You already met Optional in the stream section: &lt;code&gt;findFirst&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt;, &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt; (the version without a starting value) all return one, because a stream might be empty:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;findFirst&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;mapToInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;intValue&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;average&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;mapToInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;intValue&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;average&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;orElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Optional.empty
OptionalDouble[5.285714285714286]
5.285714285714286
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Primitive streams have their own versions: &lt;code&gt;OptionalInt&lt;/code&gt;, &lt;code&gt;OptionalLong&lt;/code&gt; and &lt;code&gt;OptionalDouble&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Optional&lt;/code&gt; isn't magic. It's a small final class with &lt;strong&gt;one field&lt;/strong&gt; holding the value, which is &lt;code&gt;null&lt;/code&gt; when empty. The empty case is one shared object, so &lt;code&gt;Optional.empty()&lt;/code&gt; doesn't create a new one each time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Optional.of("Asha")   -&amp;gt;  [ Optional | value --&amp;gt; "Asha" ]
   Optional.empty()      -&amp;gt;  the shared EMPTY object [ Optional | value = null ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because it's an extra object, it has a small cost. And it's meant for one job only: &lt;strong&gt;return types that mean "might have no result."&lt;/strong&gt; That leads to a few guidelines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't use &lt;code&gt;Optional&lt;/code&gt; for &lt;strong&gt;fields&lt;/strong&gt;, &lt;strong&gt;method parameters&lt;/strong&gt; or items inside collections. Just use normal types, or overloads.&lt;/li&gt;
&lt;li&gt;Don't return an &lt;code&gt;Optional&lt;/code&gt; of a collection. Return an &lt;strong&gt;empty list&lt;/strong&gt; instead.&lt;/li&gt;
&lt;li&gt;Never return &lt;code&gt;null&lt;/code&gt; from a method whose return type is &lt;code&gt;Optional&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Don't write &lt;code&gt;if (opt.isPresent()) { opt.get() }&lt;/code&gt;. That's just a null check in disguise. Use &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;orElse&lt;/code&gt; or &lt;code&gt;ifPresent&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lambda or method reference?&lt;/strong&gt; Use a method reference when the lambda only calls one method and the result is clearer (&lt;code&gt;String::toUpperCase&lt;/code&gt;). Use a lambda when there's more logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loop or stream?&lt;/strong&gt; Use a stream for transform-filter-collect jobs, since it reads clearly. Keep a loop when you need &lt;code&gt;break&lt;/code&gt;, an index, several changing variables or the simplest possible code. Don't force a stream into a job where it makes the code harder to read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;toList()&lt;/code&gt; or &lt;code&gt;collect(Collectors.toList())&lt;/code&gt;?&lt;/strong&gt; On Java 16 or newer, &lt;code&gt;toList()&lt;/code&gt; is shorter, but the result &lt;strong&gt;can't be modified&lt;/strong&gt;. If you need a changeable list, use &lt;code&gt;collect(Collectors.toCollection(ArrayList::new))&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;map&lt;/code&gt; or &lt;code&gt;mapToInt&lt;/code&gt;?&lt;/strong&gt; For numeric work (sums, averages), &lt;code&gt;mapToInt&lt;/code&gt; avoids boxing and gives you &lt;code&gt;sum()&lt;/code&gt; and &lt;code&gt;average()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;orElse&lt;/code&gt;, &lt;code&gt;orElseGet&lt;/code&gt; or &lt;code&gt;orElseThrow&lt;/code&gt;?&lt;/strong&gt; &lt;code&gt;orElse&lt;/code&gt; for cheap defaults, &lt;code&gt;orElseGet&lt;/code&gt; for computed ones and &lt;code&gt;orElseThrow&lt;/code&gt; when "empty" is truly an error.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optional or null?&lt;/strong&gt; Use &lt;code&gt;Optional&lt;/code&gt; as a return type when "no result" is a normal answer. Don't use it everywhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Forgetting the terminal operation.&lt;/strong&gt; &lt;code&gt;list.stream().filter(...).map(...)&lt;/code&gt; alone does nothing, because the pipeline never starts. Always end with &lt;code&gt;toList()&lt;/code&gt;, &lt;code&gt;collect&lt;/code&gt;, &lt;code&gt;forEach&lt;/code&gt;, &lt;code&gt;count&lt;/code&gt; or similar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusing a stream.&lt;/strong&gt; After a terminal operation, it's closed. You'll get &lt;code&gt;IllegalStateException&lt;/code&gt;. Make a new stream from the source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Changing things from inside a stream.&lt;/strong&gt; Adding to an outside list in &lt;code&gt;forEach&lt;/code&gt;, or modifying the source collection, causes confusing bugs. Let &lt;code&gt;collect&lt;/code&gt; build your result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calling &lt;code&gt;get()&lt;/code&gt; on an Optional without checking, or using &lt;code&gt;Optional.of(null)&lt;/code&gt;.&lt;/strong&gt; Both throw exceptions. Prefer &lt;code&gt;orElse...&lt;/code&gt; and &lt;code&gt;ofNullable&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using &lt;code&gt;orElse&lt;/code&gt; with an expensive call.&lt;/strong&gt; It always runs, even when the value is present. Use &lt;code&gt;orElseGet&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writing huge, unreadable chains, or using &lt;code&gt;parallelStream()&lt;/code&gt; by default.&lt;/strong&gt; If a pipeline needs a comment to explain it, split it into named steps. Parallel streams help only for large, CPU-heavy work.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;method reference&lt;/strong&gt; (&lt;code&gt;Class::method&lt;/code&gt;) is a short lambda. There are four kinds: static, specific object, "any object of a type" and constructor (&lt;code&gt;::new&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;constructor reference&lt;/strong&gt; picks the constructor that matches the functional interface's parameters.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;stream&lt;/strong&gt; is a lazy pipeline: &lt;strong&gt;source → intermediate operations → terminal operation&lt;/strong&gt;. It doesn't store data or change the source, and it can be used only once.&lt;/li&gt;
&lt;li&gt;Nothing runs until the terminal operation starts, and each item flows through the whole pipeline in turn.&lt;/li&gt;
&lt;li&gt;Common tools: &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;flatMap&lt;/code&gt;, &lt;code&gt;sorted&lt;/code&gt;, &lt;code&gt;distinct&lt;/code&gt;, &lt;code&gt;limit&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;, &lt;code&gt;collect&lt;/code&gt; with &lt;code&gt;Collectors&lt;/code&gt; like &lt;code&gt;groupingBy&lt;/code&gt;, &lt;code&gt;counting&lt;/code&gt; and &lt;code&gt;joining&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Optional&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/strong&gt; is a container that holds one value or nothing. It makes "maybe no result" visible in a method's return type.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;orElse&lt;/code&gt;, &lt;code&gt;orElseGet&lt;/code&gt;, &lt;code&gt;orElseThrow&lt;/code&gt; and &lt;code&gt;ifPresent&lt;/code&gt; instead of &lt;code&gt;get()&lt;/code&gt;. Use &lt;code&gt;orElseGet&lt;/code&gt; when the default is expensive.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Optional&lt;/code&gt; for return types, not for fields, parameters or collection items.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: take a list of words, such as the lines of a short paragraph split by spaces. Use a stream to remove blanks, make everything lowercase, count how often each word appears with &lt;code&gt;groupingBy&lt;/code&gt; and &lt;code&gt;counting&lt;/code&gt; into a &lt;code&gt;TreeMap&lt;/code&gt;, and print them sorted. Then write a method &lt;code&gt;Optional&amp;lt;String&amp;gt; longestWord(List&amp;lt;String&amp;gt; words)&lt;/code&gt; that returns the longest word, and print it with &lt;code&gt;orElse("none")&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, add a &lt;code&gt;System.out.println&lt;/code&gt; inside a &lt;code&gt;filter&lt;/code&gt; and a &lt;code&gt;map&lt;/code&gt;, and watch how the items flow one by one. Then add &lt;code&gt;.limit(2)&lt;/code&gt; and see how many items get processed.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

&lt;p&gt;Next in this series: &lt;code&gt;var&lt;/code&gt;, records and sealed classes.&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Java Collections Framework Explained Simply</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Wed, 14 Oct 2026 10:59:42 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/java-collections-framework-explained-simply-28kd</link>
      <guid>https://dev.to/mayur_bodhare/java-collections-framework-explained-simply-28kd</guid>
      <description>&lt;p&gt;When I first saw &lt;code&gt;Collection&lt;/code&gt; and &lt;code&gt;Collections&lt;/code&gt; in the same Java file, I thought one of them was a typo. Then I found &lt;code&gt;Arrays&lt;/code&gt;, &lt;code&gt;Objects&lt;/code&gt; and &lt;code&gt;Collectors&lt;/code&gt; and was sure the Java team had a thing for confusing names.&lt;/p&gt;

&lt;p&gt;On top of that, I had a bigger problem. Arrays were fine until I needed to add an item to the middle, remove one, avoid duplicates or look something up by name. I kept writing the same helper code over and over, and every version had its own bugs.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Collections Framework&lt;/strong&gt; is Java's answer to all of this. It's a ready-made toolbox of data structures and algorithms. In this post, we'll learn the big idea, the &lt;code&gt;Collection&lt;/code&gt; interface, the &lt;code&gt;Collections&lt;/code&gt; class (and why they're different), the built-in algorithms, and the most popular collections you'll use every day. I've drawn the key pictures in text so you can see how things connect.&lt;/p&gt;

&lt;p&gt;All the snippets assume &lt;code&gt;import java.util.*;&lt;/code&gt; at the top, and they go inside a &lt;code&gt;main&lt;/code&gt; method unless I show a full class.&lt;/p&gt;

&lt;h2&gt;
  
  
  The concept: what is the Collections Framework?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;collection&lt;/strong&gt; is an object that holds a group of other objects. The &lt;strong&gt;Collections Framework&lt;/strong&gt; is the set of classes and interfaces in &lt;code&gt;java.util&lt;/code&gt; that gives you the common ways to group objects: lists, sets, queues and maps.&lt;/p&gt;

&lt;p&gt;Why use it instead of plain arrays?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Arrays have a fixed size.&lt;/strong&gt; A collection grows and shrinks as needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ready-made operations.&lt;/strong&gt; Adding, removing, searching, sorting and checking for duplicates are already written, tested and fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Different shapes for different needs.&lt;/strong&gt; Need order? A list. No duplicates? A set. Look up by key? A map.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable parts.&lt;/strong&gt; Code written against an interface works with any implementation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The framework has three parts. This is the most useful way to remember it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   1. INTERFACES        the contracts: what a list, set, queue or map CAN DO
                        (List, Set, Queue, Map ...)

   2. IMPLEMENTATIONS   the real classes that do the work
                        (ArrayList, HashSet, HashMap ...)

   3. ALGORITHMS        ready-made methods that work on any collection
                        (sort, search, shuffle ... in the Collections class)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The family tree
&lt;/h3&gt;

&lt;p&gt;Here's how the main interfaces and classes are related. Spend a minute on this picture, because everything else hangs on it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                      Iterable
                         |
                     Collection                         Map   (separate tree!)
            /------------+-------------\                 |
          List          Set           Queue          +---+----------+
           |             |              |            |   |          |
      ArrayList      HashSet        PriorityQueue  HashMap LinkedHashMap TreeMap
      LinkedList     LinkedHashSet  ArrayDeque
                     TreeSet        (also LinkedList)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two details in this picture trip people up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Map&lt;/code&gt; is not a &lt;code&gt;Collection&lt;/code&gt;.&lt;/strong&gt; A map stores key-value &lt;strong&gt;pairs&lt;/strong&gt;, not single items, so it has its own tree. It's still part of the framework.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Iterable&lt;/code&gt; sits at the very top.&lt;/strong&gt; Anything that is &lt;code&gt;Iterable&lt;/code&gt; can be used in a for-each loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Collection interface
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Collection&amp;lt;E&amp;gt;&lt;/code&gt; is the &lt;strong&gt;root contract&lt;/strong&gt; for groups of single items. Lists, sets and queues all extend it, so they all share the same basic methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;add(item)&lt;/code&gt; and &lt;code&gt;addAll(otherCollection)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;remove(item)&lt;/code&gt; and &lt;code&gt;removeAll(otherCollection)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;contains(item)&lt;/code&gt; and &lt;code&gt;containsAll(otherCollection)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;size()&lt;/code&gt;, &lt;code&gt;isEmpty()&lt;/code&gt; and &lt;code&gt;clear()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;iterator()&lt;/code&gt; to walk through the items&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;removeIf(condition)&lt;/code&gt;, &lt;code&gt;stream()&lt;/code&gt; and &lt;code&gt;toArray()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because they share this contract, you can write code against &lt;code&gt;Collection&lt;/code&gt; and not care which kind you get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3
true
[Ravi, Asha]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;remove("Asha")&lt;/code&gt; removed only the &lt;strong&gt;first&lt;/strong&gt; match. Now change one word, the implementation on the first line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ...the same add calls as above...&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything else stayed the same, but a set ignores the second &lt;code&gt;"Asha"&lt;/code&gt;, so the size is 2. That's the power of programming to an interface: the rest of your code doesn't change when the structure does.&lt;/p&gt;

&lt;h3&gt;
  
  
  Looping and removing safely
&lt;/h3&gt;

&lt;p&gt;Because every &lt;code&gt;Collection&lt;/code&gt; is &lt;code&gt;Iterable&lt;/code&gt;, you can loop with for-each. Behind the scenes, the compiler turns it into an &lt;strong&gt;iterator&lt;/strong&gt; loop, using &lt;code&gt;iterator()&lt;/code&gt;, &lt;code&gt;hasNext()&lt;/code&gt; and &lt;code&gt;next()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's a trap that almost everyone falls into: changing the collection while looping over it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Exception in thread "main" java.util.ConcurrentModificationException
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most collections are &lt;strong&gt;fail-fast&lt;/strong&gt;. They count how many times they've been changed. The iterator remembers that count, and if it sees a different number, it throws this exception, instead of continuing with confusing data.&lt;/p&gt;

&lt;p&gt;There are two safe ways:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;Iterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;iterator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasNext&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;          &lt;span class="c1"&gt;// removes through the iterator: allowed&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, shorter, with &lt;code&gt;removeIf&lt;/code&gt;: &lt;code&gt;nums.removeIf(n -&amp;gt; n % 2 == 0);&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Collections class (with an "s")
&lt;/h2&gt;

&lt;p&gt;Now the name that causes the most confusion. Let's separate them clearly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Collection&lt;/code&gt;&lt;/strong&gt; (no s) is an &lt;strong&gt;interface&lt;/strong&gt;. It's the contract for a group of items.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Collections&lt;/code&gt;&lt;/strong&gt; (with an s) is a &lt;strong&gt;utility class&lt;/strong&gt;. It holds only &lt;strong&gt;static helper methods&lt;/strong&gt; for working on collections. You never create an object of it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple memory trick: the plural-named classes in Java are usually &lt;strong&gt;toolboxes of static methods&lt;/strong&gt;. &lt;code&gt;Collections&lt;/code&gt; works on collections, &lt;code&gt;Arrays&lt;/code&gt; works on arrays, and &lt;code&gt;Objects&lt;/code&gt; works on objects. You call their methods like &lt;code&gt;Collections.sort(list)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Collection&amp;lt;E&amp;gt;       interface   "what a group of items can do"      (you implement/use it)
   Collections         class       "helpers that work on collections"  (you just call its methods)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Algorithms
&lt;/h2&gt;

&lt;p&gt;In the framework, an &lt;strong&gt;algorithm&lt;/strong&gt; is a ready-made, reusable method that works on collections. They're all static methods in the &lt;code&gt;Collections&lt;/code&gt; class, and the nice part is that they work on &lt;strong&gt;any&lt;/strong&gt; &lt;code&gt;List&lt;/code&gt;, whether it's an &lt;code&gt;ArrayList&lt;/code&gt; or a &lt;code&gt;LinkedList&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here are the most useful ones:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;binarySearch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;swap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;frequency&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 2, 5, 7, 9]
3
[9, 7, 5, 2, 1]
9 1
[1, 7, 5, 2, 9]
1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What each one did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sort&lt;/code&gt; put the list in ascending order.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;binarySearch&lt;/code&gt; found &lt;code&gt;7&lt;/code&gt; at index 3. &lt;strong&gt;The list must be sorted first&lt;/strong&gt;, or the result is meaningless.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reverse&lt;/code&gt; flipped the order.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max&lt;/code&gt; and &lt;code&gt;min&lt;/code&gt; found the biggest and smallest.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;swap&lt;/code&gt; exchanged the items at positions 0 and 4.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;frequency&lt;/code&gt; counted how many times &lt;code&gt;5&lt;/code&gt; appears.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Others worth knowing: &lt;code&gt;shuffle&lt;/code&gt; (random order), &lt;code&gt;rotate&lt;/code&gt;, &lt;code&gt;fill&lt;/code&gt;, &lt;code&gt;nCopies&lt;/code&gt;, &lt;code&gt;emptyList&lt;/code&gt; and &lt;code&gt;addAll&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sorting your own way
&lt;/h3&gt;

&lt;p&gt;By default, &lt;code&gt;sort&lt;/code&gt; uses the items' &lt;strong&gt;natural order&lt;/strong&gt; (numbers ascending, strings alphabetical). For anything else, pass a &lt;code&gt;Comparator&lt;/code&gt;, which is a rule for comparing two items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Meera"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Jo"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Comparator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;comparing&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reverseOrder&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Asha, Jo, Meera, Ravi]
[Jo, Asha, Ravi, Meera]
[Ravi, Meera, Jo, Asha]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at the second line. &lt;code&gt;Asha&lt;/code&gt; and &lt;code&gt;Ravi&lt;/code&gt; both have 4 letters, and they kept their earlier order. That's because the sort is &lt;strong&gt;stable&lt;/strong&gt;: equal items don't swap places.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Collections.sort(list)&lt;/code&gt; simply calls &lt;code&gt;list.sort(...)&lt;/code&gt;. For objects, Java uses &lt;strong&gt;TimSort&lt;/strong&gt;, a fast and stable algorithm that takes about &lt;code&gt;n log n&lt;/code&gt; steps. (For arrays of primitives, &lt;code&gt;Arrays.sort&lt;/code&gt; uses a different algorithm, called dual-pivot quicksort.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;binarySearch&lt;/code&gt; repeatedly cuts the search range in half, so it takes about &lt;code&gt;log n&lt;/code&gt; steps. It's very fast on an &lt;code&gt;ArrayList&lt;/code&gt;, but slower on a &lt;code&gt;LinkedList&lt;/code&gt;, which can't jump to the middle.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Read-only views and thread-safe wrappers
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Collections&lt;/code&gt; can also wrap a collection to change its behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;readOnly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unmodifiableList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"c"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;readOnly&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;readOnly&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"d"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;UnsupportedOperationException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Read-only!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[a, b, c]
Read-only!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An unmodifiable list is a &lt;strong&gt;view&lt;/strong&gt;, not a copy. You can't change it through &lt;code&gt;readOnly&lt;/code&gt;, but when someone changes &lt;code&gt;original&lt;/code&gt;, the view shows the change. If you want a real, independent, unchangeable copy, use &lt;code&gt;List.copyOf(original)&lt;/code&gt;. There's also &lt;code&gt;Collections.synchronizedList(...)&lt;/code&gt; to make a list safe for several threads (although for new code, the classes in &lt;code&gt;java.util.concurrent&lt;/code&gt; are usually a better choice).&lt;/p&gt;

&lt;h2&gt;
  
  
  Well-known collections
&lt;/h2&gt;

&lt;p&gt;Now the real workers. Let's visit the four families.&lt;/p&gt;

&lt;h3&gt;
  
  
  List: ordered, with duplicates, accessed by position
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;List&lt;/strong&gt; keeps items in the order you add them, allows duplicates and lets you use an index.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ArrayList&lt;/strong&gt; is the everyday choice. Behind the scenes, it keeps an array. When the array fills up, it creates a bigger one (about 1.5 times larger) and copies everything over.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Apple"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Banana"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Apple"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Mango"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;indexOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Apple"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Apple, Mango, Banana, Apple]
Banana
0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ArrayList is an array inside:

   [ Apple ][ Mango ][ Banana ][ Apple ][  ][  ]     size = 4, capacity = 6
      0        1        2        3
   get(2) jumps straight to slot 2. Adding in the middle shifts the items after it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LinkedList&lt;/strong&gt; stores each item in a small node that points to the previous and next ones:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   head --&amp;gt; [ prev | Apple  | next ] &amp;lt;--&amp;gt; [ prev | Mango | next ] &amp;lt;--&amp;gt; [ prev | Banana | next ] &amp;lt;-- tail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding or removing at the &lt;strong&gt;ends&lt;/strong&gt; is very quick. But &lt;code&gt;get(i)&lt;/code&gt; must walk node by node, so it's slow for big lists.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set: no duplicates
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Set&lt;/strong&gt; never holds the same item twice. &lt;code&gt;add&lt;/code&gt; returns &lt;code&gt;false&lt;/code&gt; if the item was already there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;true
false
1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are three common sets, and the only real difference is the &lt;strong&gt;order&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"pear"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"fig"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LinkedHashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TreeSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[pear, apple, fig]
[apple, fig, pear]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HashSet:&lt;/strong&gt; fastest, but the order is &lt;strong&gt;not guaranteed&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedHashSet:&lt;/strong&gt; keeps the order you inserted (&lt;code&gt;pear, apple, fig&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TreeSet:&lt;/strong&gt; keeps items &lt;strong&gt;sorted&lt;/strong&gt; (&lt;code&gt;apple, fig, pear&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Map: key to value
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Map&lt;/strong&gt; stores pairs. Each &lt;strong&gt;key&lt;/strong&gt; is unique, and it points to a &lt;strong&gt;value&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ravi"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;91&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Asha"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;marks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOrDefault&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Meera"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;91
2
0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Putting &lt;code&gt;"Asha"&lt;/code&gt; a second time &lt;strong&gt;replaced&lt;/strong&gt; her old value. And &lt;code&gt;getOrDefault&lt;/code&gt; gave &lt;code&gt;0&lt;/code&gt; for a missing key, instead of &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A very common job is counting. Here's a word counter that uses &lt;code&gt;merge&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"to be or not to be"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TreeMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;merge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;Integer:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{be=2, not=1, or=1, to=2}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maps come in the same three flavors as sets: &lt;strong&gt;HashMap&lt;/strong&gt; (fastest, no order), &lt;strong&gt;LinkedHashMap&lt;/strong&gt; (insertion order) and &lt;strong&gt;TreeMap&lt;/strong&gt; (sorted by key).&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes: how HashMap finds things
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;HashMap&lt;/code&gt; keeps an array of &lt;strong&gt;buckets&lt;/strong&gt;. When you &lt;code&gt;put&lt;/code&gt; a key, Java calls the key's &lt;code&gt;hashCode()&lt;/code&gt;, turns it into a bucket number and stores the entry there. To find it again, it repeats the same steps, then uses &lt;code&gt;equals()&lt;/code&gt; to pick the right entry if a bucket holds several.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   put("Asha", 91)
        |
   "Asha".hashCode()  --&amp;gt;  a number  --&amp;gt;  bucket index 3

   buckets:   [0] [1] [2] [3: Asha=91 -&amp;gt; Ravi=72] [4] [5] ...
                               ^
                   two keys landed in the same bucket (a "collision"),
                   so equals() decides which one you meant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why lookup is so quick (about one step on average, not a search through everything). A few details:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It starts with 16 buckets, and &lt;strong&gt;doubles&lt;/strong&gt; when it's 75% full.&lt;/li&gt;
&lt;li&gt;Since Java 8, a bucket that gets too crowded switches from a chain to a balanced tree, so even bad cases stay fast.&lt;/li&gt;
&lt;li&gt;If you use &lt;strong&gt;your own class as a key&lt;/strong&gt;, you &lt;strong&gt;must override both &lt;code&gt;equals()&lt;/code&gt; and &lt;code&gt;hashCode()&lt;/code&gt;&lt;/strong&gt;, and keep them consistent. Otherwise, lookups will fail even for identical-looking objects.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;HashSet&lt;/code&gt; is secretly a &lt;code&gt;HashMap&lt;/code&gt; (the items are the keys). In the same way, &lt;code&gt;TreeSet&lt;/code&gt; is backed by a &lt;code&gt;TreeMap&lt;/code&gt;, and &lt;code&gt;LinkedHashSet&lt;/code&gt; by a &lt;code&gt;LinkedHashMap&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Queue and Deque: waiting lines and stacks
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Queue&lt;/strong&gt; processes items in order: first in, first out (FIFO). A &lt;strong&gt;Deque&lt;/strong&gt; (double-ended queue) can add and remove at both ends, so it works as a stack too (last in, first out, LIFO).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Queue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayDeque&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;offer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;offer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;offer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;peek&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="nc"&gt;Deque&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayDeque&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pop&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A
B
3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;offer&lt;/code&gt; adds, &lt;code&gt;poll&lt;/code&gt; removes and returns the front, and &lt;code&gt;peek&lt;/code&gt; looks at the front without removing.&lt;/li&gt;
&lt;li&gt;For a stack, prefer &lt;code&gt;ArrayDeque&lt;/code&gt; over the old &lt;code&gt;Stack&lt;/code&gt; class.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;strong&gt;PriorityQueue&lt;/strong&gt; doesn't use arrival order. It always gives you the &lt;strong&gt;smallest&lt;/strong&gt; item first (or whatever your comparator says is first):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;PriorityQueue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PriorityQueue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pq&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pq&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1
3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't print the whole queue to check the order. Inside, it's a heap, and only the front is guaranteed to be the smallest.&lt;/p&gt;

&lt;h3&gt;
  
  
  How fast is each one?
&lt;/h3&gt;

&lt;p&gt;Here is a rough guide to the speed of the common operations (&lt;code&gt;n&lt;/code&gt; is the number of items):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ArrayList:&lt;/strong&gt; &lt;code&gt;get(i)&lt;/code&gt; is instant (O(1)). Adding at the end is fast (O(1) on average). Inserting or removing in the middle, or searching with &lt;code&gt;contains&lt;/code&gt;, takes O(n).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedList:&lt;/strong&gt; adding or removing at the ends is O(1). &lt;code&gt;get(i)&lt;/code&gt; and &lt;code&gt;contains&lt;/code&gt; are O(n).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HashSet / HashMap:&lt;/strong&gt; add, remove and lookup are O(1) on average.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TreeSet / TreeMap:&lt;/strong&gt; add, remove and lookup are O(log n), and the items stay sorted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ArrayDeque:&lt;/strong&gt; adding and removing at either end is O(1).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PriorityQueue:&lt;/strong&gt; add and poll are O(log n), and peek is O(1).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;p&gt;Start from what you need, and the choice is usually clear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Need to look things up by a KEY?          -&amp;gt; Map
        default: HashMap     sorted keys: TreeMap     insertion order: LinkedHashMap

   Need NO DUPLICATES?                       -&amp;gt; Set
        default: HashSet     sorted: TreeSet          insertion order: LinkedHashSet

   Need first-in-first-out, a stack,
   or "smallest first"?                      -&amp;gt; Queue / Deque
        ArrayDeque  or  PriorityQueue

   Otherwise, an ordered group?              -&amp;gt; List
        default: ArrayList
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some extra advice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Default to &lt;code&gt;ArrayList&lt;/code&gt; and &lt;code&gt;HashMap&lt;/code&gt;.&lt;/strong&gt; They're the best general-purpose choices. In practice, &lt;code&gt;ArrayList&lt;/code&gt; beats &lt;code&gt;LinkedList&lt;/code&gt; in most real cases, even for inserts, because arrays are friendly to the CPU.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Declare variables with the interface:&lt;/strong&gt; &lt;code&gt;List&amp;lt;String&amp;gt; names = new ArrayList&amp;lt;&amp;gt;();&lt;/code&gt;. Then you can swap the implementation by editing one word.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collections hold objects, not primitives.&lt;/strong&gt; Write &lt;code&gt;List&amp;lt;Integer&amp;gt;&lt;/code&gt;, not &lt;code&gt;List&amp;lt;int&amp;gt;&lt;/code&gt;. (This is where wrapper classes and autoboxing come in.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sorted data you keep changing?&lt;/strong&gt; Use a &lt;code&gt;TreeSet&lt;/code&gt; or &lt;code&gt;TreeMap&lt;/code&gt;. &lt;strong&gt;Sorted once?&lt;/strong&gt; Keep an &lt;code&gt;ArrayList&lt;/code&gt; and call &lt;code&gt;Collections.sort&lt;/code&gt; once.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mixing up &lt;code&gt;Collection&lt;/code&gt;, &lt;code&gt;Collections&lt;/code&gt; and &lt;code&gt;Arrays&lt;/code&gt;.&lt;/strong&gt; &lt;code&gt;Collection&lt;/code&gt; is the interface. &lt;code&gt;Collections&lt;/code&gt; and &lt;code&gt;Arrays&lt;/code&gt; are classes of static helper methods.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Changing a collection while looping over it.&lt;/strong&gt; It throws &lt;code&gt;ConcurrentModificationException&lt;/code&gt;. Use an &lt;code&gt;Iterator&lt;/code&gt; with &lt;code&gt;remove()&lt;/code&gt;, or &lt;code&gt;removeIf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using your own class as a key without &lt;code&gt;equals()&lt;/code&gt; and &lt;code&gt;hashCode()&lt;/code&gt;.&lt;/strong&gt; Lookups fail, and duplicates sneak into sets. Also, don't change a key's fields after you've put it into a map or set.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relying on the order of a &lt;code&gt;HashSet&lt;/code&gt; or &lt;code&gt;HashMap&lt;/code&gt;.&lt;/strong&gt; It looks stable in small tests, then changes. If you need an order, choose &lt;code&gt;LinkedHash...&lt;/code&gt; or &lt;code&gt;Tree...&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calling &lt;code&gt;get(i)&lt;/code&gt; in a loop over a &lt;code&gt;LinkedList&lt;/code&gt;.&lt;/strong&gt; Each call walks the list, so the loop becomes slow (O(n²)). Use for-each, or an &lt;code&gt;ArrayList&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forgetting that some lists can't be changed.&lt;/strong&gt; &lt;code&gt;List.of(...)&lt;/code&gt;, &lt;code&gt;List.copyOf(...)&lt;/code&gt; and &lt;code&gt;Collections.unmodifiableList(...)&lt;/code&gt; throw &lt;code&gt;UnsupportedOperationException&lt;/code&gt; on changes. &lt;code&gt;Arrays.asList(1, 2, 3)&lt;/code&gt; has a fixed size, so &lt;code&gt;add&lt;/code&gt; also fails. Wrap it in &lt;code&gt;new ArrayList&amp;lt;&amp;gt;(...)&lt;/code&gt; when you need a normal list.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Also remember &lt;code&gt;Collections.binarySearch&lt;/code&gt; only works on a list that's already sorted in the same order.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Collections Framework&lt;/strong&gt; is Java's ready-made toolbox in &lt;code&gt;java.util&lt;/code&gt;: &lt;strong&gt;interfaces&lt;/strong&gt;, &lt;strong&gt;implementations&lt;/strong&gt; and &lt;strong&gt;algorithms&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Collection&lt;/code&gt; is the root interface for groups of items (&lt;code&gt;List&lt;/code&gt;, &lt;code&gt;Set&lt;/code&gt;, &lt;code&gt;Queue&lt;/code&gt;). &lt;code&gt;Map&lt;/code&gt; is separate, because it stores pairs.&lt;/li&gt;
&lt;li&gt;Every &lt;code&gt;Collection&lt;/code&gt; is &lt;code&gt;Iterable&lt;/code&gt;, so for-each works, but don't change a collection while looping over it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Collections&lt;/code&gt;&lt;/strong&gt; (with an s) is a utility class of static methods: &lt;code&gt;sort&lt;/code&gt;, &lt;code&gt;binarySearch&lt;/code&gt;, &lt;code&gt;reverse&lt;/code&gt;, &lt;code&gt;shuffle&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt;, &lt;code&gt;min&lt;/code&gt;, &lt;code&gt;frequency&lt;/code&gt;, &lt;code&gt;swap&lt;/code&gt; and wrappers like &lt;code&gt;unmodifiableList&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;List:&lt;/strong&gt; &lt;code&gt;ArrayList&lt;/code&gt; (array inside, the default) and &lt;code&gt;LinkedList&lt;/code&gt; (nodes). &lt;strong&gt;Set:&lt;/strong&gt; &lt;code&gt;HashSet&lt;/code&gt;, &lt;code&gt;LinkedHashSet&lt;/code&gt;, &lt;code&gt;TreeSet&lt;/code&gt;. &lt;strong&gt;Map:&lt;/strong&gt; &lt;code&gt;HashMap&lt;/code&gt;, &lt;code&gt;LinkedHashMap&lt;/code&gt;, &lt;code&gt;TreeMap&lt;/code&gt;. &lt;strong&gt;Queue/Deque:&lt;/strong&gt; &lt;code&gt;ArrayDeque&lt;/code&gt;, &lt;code&gt;PriorityQueue&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HashMap&lt;/code&gt; uses &lt;code&gt;hashCode()&lt;/code&gt; to find a bucket and &lt;code&gt;equals()&lt;/code&gt; to pick the entry, so your key classes need both.&lt;/li&gt;
&lt;li&gt;Choose by need: key lookup, no duplicates, queue behavior or an ordered list. When unsure, start with &lt;code&gt;ArrayList&lt;/code&gt; and &lt;code&gt;HashMap&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: build a tiny contact book. Store contacts in a &lt;code&gt;Map&amp;lt;String, String&amp;gt;&lt;/code&gt; (name to phone number) and print them sorted by name using a &lt;code&gt;TreeMap&lt;/code&gt;. Then add every name to a &lt;code&gt;List&lt;/code&gt;, sort it with &lt;code&gt;Collections.sort&lt;/code&gt; by name length, and use &lt;code&gt;Collections.binarySearch&lt;/code&gt; to find one name.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, create a &lt;code&gt;Student&lt;/code&gt; class without &lt;code&gt;equals()&lt;/code&gt; and &lt;code&gt;hashCode()&lt;/code&gt;, and add two students with the same data to a &lt;code&gt;HashSet&lt;/code&gt;. Notice that both get in. Then add the two methods and watch the duplicate disappear.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>datastructures</category>
      <category>programming</category>
    </item>
    <item>
      <title>Java Threads Explained: Scheduler, sleep and synchronized</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Tue, 13 Oct 2026 17:28:35 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/java-threads-explained-scheduler-sleep-and-synchronized-4ack</link>
      <guid>https://dev.to/mayur_bodhare/java-threads-explained-scheduler-sleep-and-synchronized-4ack</guid>
      <description>&lt;p&gt;My first multithreaded program printed its lines in a different order every time I ran it. My second one had a counter that should have ended at 200,000 and ended at 143,267. I ran it again and got 151,880. Same code, different answers.&lt;/p&gt;

&lt;p&gt;I was sure my computer was broken. It wasn't. I had just met threads, and with them, two ideas that change how you think about programs: the order isn't guaranteed, and shared data can get corrupted.&lt;/p&gt;

&lt;p&gt;In this post, we'll learn what threads are, how to create them, what the scheduler does, how priority and &lt;code&gt;sleep&lt;/code&gt; work, the six states of a thread, and how &lt;code&gt;synchronized&lt;/code&gt; fixes the counter bug. I've drawn the important pictures in text, and every claim comes with code you can run.&lt;/p&gt;

&lt;p&gt;Unless I show a full class, the snippets go inside a &lt;code&gt;main&lt;/code&gt; method that declares &lt;code&gt;throws InterruptedException&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a thread?
&lt;/h2&gt;

&lt;p&gt;A normal program does one thing at a time. If it downloads a file, the rest of the program waits. A &lt;strong&gt;thread&lt;/strong&gt; is a separate path of execution inside your program, so several things can happen &lt;strong&gt;at the same time&lt;/strong&gt; (or at least look like it).&lt;/p&gt;

&lt;p&gt;Two words are worth separating:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;process&lt;/strong&gt; is a running program, like your Java app. It has its own memory.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;thread&lt;/strong&gt; lives inside a process. A process can have many threads, and they &lt;strong&gt;share&lt;/strong&gt; the process's memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every Java program starts with one thread called &lt;strong&gt;&lt;code&gt;main&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The JVM also starts a few background threads of its own, like the garbage collector, but &lt;code&gt;main&lt;/code&gt; is the one that runs your code.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes: what threads share
&lt;/h3&gt;

&lt;p&gt;Threads share the &lt;strong&gt;heap&lt;/strong&gt;, where all objects live. But each thread gets its &lt;strong&gt;own stack&lt;/strong&gt;, which holds its method calls and local variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   PROCESS (your running Java program)
  +----------------------------------------------------+
  |  HEAP: shared by all threads (objects live here)   |
  |                                                    |
  |   Thread "main"     Thread-0         Thread-1      |
  |   +-----------+     +-----------+    +-----------+ |
  |   | own stack |     | own stack |    | own stack | |
  |   | own PC    |     | own PC    |    | own PC    | |
  |   +-----------+     +-----------+    +-----------+ |
  +----------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(PC is the "program counter", which remembers which instruction the thread is on.)&lt;/p&gt;

&lt;p&gt;This design is the source of both the benefit and the danger. Sharing the heap makes it easy for threads to cooperate. But when two threads change the same object at once, things can go wrong, as we'll see.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating threads
&lt;/h2&gt;

&lt;p&gt;There are three common ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  Way 1: extend &lt;code&gt;Thread&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello from "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello from Thread-0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You put the work inside &lt;code&gt;run()&lt;/code&gt;, and you launch the thread with &lt;code&gt;start()&lt;/code&gt;. Unnamed threads get names like &lt;code&gt;Thread-0&lt;/code&gt;, &lt;code&gt;Thread-1&lt;/code&gt; and so on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Way 2: implement &lt;code&gt;Runnable&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Runnable&lt;/code&gt; is a functional interface with one method, &lt;code&gt;run()&lt;/code&gt;. You hand it to a &lt;code&gt;Thread&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello from "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"worker-1"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hello from worker-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the lambda is the &lt;code&gt;Runnable&lt;/code&gt;, and &lt;code&gt;"worker-1"&lt;/code&gt; is a name we picked.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which way is better?
&lt;/h3&gt;

&lt;p&gt;Prefer &lt;strong&gt;&lt;code&gt;Runnable&lt;/code&gt;&lt;/strong&gt; (or a lambda). It separates &lt;strong&gt;what to do&lt;/strong&gt; (the task) from &lt;strong&gt;how to run it&lt;/strong&gt; (the thread). It also leaves your class free to extend something else, since Java allows only one parent class.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;start()&lt;/code&gt; vs &lt;code&gt;run()&lt;/code&gt;: the classic mix-up
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Running in "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()),&lt;/span&gt;
    &lt;span class="s"&gt;"worker"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Running in main
Running in worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calling &lt;code&gt;run()&lt;/code&gt; directly is just a &lt;strong&gt;normal method call&lt;/strong&gt;, so it ran on the &lt;code&gt;main&lt;/code&gt; thread. Only &lt;code&gt;start()&lt;/code&gt; creates a new thread. If you want concurrency, always call &lt;code&gt;start()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also, a thread can be started only &lt;strong&gt;once&lt;/strong&gt;. Calling &lt;code&gt;start()&lt;/code&gt; a second time throws an &lt;code&gt;IllegalThreadStateException&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes: what start() does
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;start()&lt;/code&gt; asks the JVM to create a real operating-system thread. When that thread is ready, it calls your &lt;code&gt;run()&lt;/code&gt; method. When &lt;code&gt;run()&lt;/code&gt; ends, the thread ends. (Java 21 also added lightweight &lt;strong&gt;virtual threads&lt;/strong&gt;, which are managed by the JVM instead of the OS. For a beginner's first steps, the ordinary threads above are what matter.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Waiting for a thread with join()
&lt;/h3&gt;

&lt;p&gt;Often &lt;code&gt;main&lt;/code&gt; needs to wait until a worker finishes. That's what &lt;code&gt;join()&lt;/code&gt; is for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Worker done"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Main continues"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Worker done
Main continues
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without &lt;code&gt;join()&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt; might print first. &lt;code&gt;join()&lt;/code&gt; makes the calling thread wait until &lt;code&gt;t&lt;/code&gt; is finished. It throws &lt;code&gt;InterruptedException&lt;/code&gt;, which is why our examples declare &lt;code&gt;throws InterruptedException&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thread scheduler
&lt;/h2&gt;

&lt;p&gt;Here's the question that confused me most: if I start two threads, who decides which one runs first?&lt;/p&gt;

&lt;p&gt;The answer is the &lt;strong&gt;thread scheduler&lt;/strong&gt;. It's the part of the JVM and the operating system that decides &lt;strong&gt;which thread gets the CPU, and for how long&lt;/strong&gt;. Most systems use &lt;strong&gt;time slicing&lt;/strong&gt;: each runnable thread gets a short turn, then the scheduler may switch to another one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Time ------------------------------------------------&amp;gt;

   One CPU core:    | A | B | A | C | B | A | C |
                      each box = a short time slice

   Two CPU cores:   core 1:  | A | A | C | A |
                    core 2:  | B | B | B | C |
                      (A and B can truly run at the same time)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key point: &lt;strong&gt;you don't control the scheduler&lt;/strong&gt;, and the order isn't guaranteed. Let's prove it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" step "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One possible output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A step 1
B step 1
A step 2
A step 3
B step 2
B step 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it several times. Each thread's own steps stay in order (A1, A2, A3), but how A and B &lt;strong&gt;interleave&lt;/strong&gt; changes from run to run. Sometimes A finishes entirely before B begins, and sometimes they alternate.&lt;/p&gt;

&lt;p&gt;Two related words are often mixed up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency&lt;/strong&gt; means several tasks making progress during the same period, possibly by switching on one core.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallelism&lt;/strong&gt; means several tasks running at the exact same moment on different cores.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  States of a thread
&lt;/h2&gt;

&lt;p&gt;During its life, a thread moves through several &lt;strong&gt;states&lt;/strong&gt;. Java defines six of them in the &lt;code&gt;Thread.State&lt;/code&gt; enum:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;NEW&lt;/code&gt;:&lt;/strong&gt; the &lt;code&gt;Thread&lt;/code&gt; object exists, but &lt;code&gt;start()&lt;/code&gt; hasn't been called yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;RUNNABLE&lt;/code&gt;:&lt;/strong&gt; the thread is running, or ready to run and waiting for the scheduler to give it a turn.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;BLOCKED&lt;/code&gt;:&lt;/strong&gt; the thread is waiting to get a lock held by another thread (we'll see this with &lt;code&gt;synchronized&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;WAITING&lt;/code&gt;:&lt;/strong&gt; the thread waits &lt;strong&gt;indefinitely&lt;/strong&gt; for another thread to do something, such as &lt;code&gt;join()&lt;/code&gt; or &lt;code&gt;wait()&lt;/code&gt; with no timeout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;TIMED_WAITING&lt;/code&gt;:&lt;/strong&gt; the thread waits for a &lt;strong&gt;fixed time&lt;/strong&gt;, such as &lt;code&gt;sleep(1000)&lt;/code&gt; or &lt;code&gt;join(1000)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;TERMINATED&lt;/code&gt;:&lt;/strong&gt; the thread has finished its &lt;code&gt;run()&lt;/code&gt; method.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's how a thread moves between them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                      start()
      NEW  ----------------------------&amp;gt;  RUNNABLE  &amp;lt;----------------------+
                                           |  |  |                         |
                                           |  |  |                         |
        waiting for a lock  &amp;lt;--------------+  |  +---------&amp;gt;  TIMED_WAITING|
              BLOCKED  ----- lock acquired ---+   sleep(ms), |  join(ms)   |
                                           |      wait(ms)    +--- time up -+
                                           |
                       wait(), join()      |
                  +--- WAITING &amp;lt;-----------+
                  |       |
                  |       +--- notified / joined thread ends ---&amp;gt; back to RUNNABLE
                  |
                  +---------   run() ends   -----------------&amp;gt;  TERMINATED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can watch a thread change state with &lt;code&gt;getState()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ignore for this demo&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getState&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getState&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getState&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getState&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output (in most runs, since it depends on timing):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEW
RUNNABLE
TIMED_WAITING
TERMINATED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice there's no &lt;code&gt;RUNNING&lt;/code&gt; state in Java. Many textbooks describe five states (new, runnable, running, blocked, dead), where "running" means "currently on the CPU." In Java, both "on the CPU" and "ready for the CPU" are just &lt;code&gt;RUNNABLE&lt;/code&gt;, because the scheduler, not Java, decides that.&lt;/p&gt;

&lt;h2&gt;
  
  
  sleep()
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Thread.sleep(milliseconds)&lt;/code&gt; makes the &lt;strong&gt;current thread pause&lt;/strong&gt; for at least that long.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Go!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output (with about one second between lines):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3
2
1
Go!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some important facts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It pauses the &lt;strong&gt;current&lt;/strong&gt; thread. &lt;code&gt;sleep&lt;/code&gt; is a &lt;strong&gt;static&lt;/strong&gt; method, so &lt;code&gt;t.sleep(1000)&lt;/code&gt; also pauses the thread that calls it, not &lt;code&gt;t&lt;/code&gt;. That's a common surprise.&lt;/li&gt;
&lt;li&gt;While sleeping, the thread is in the &lt;strong&gt;&lt;code&gt;TIMED_WAITING&lt;/code&gt;&lt;/strong&gt; state and &lt;strong&gt;doesn't use the CPU&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It sleeps for &lt;strong&gt;at least&lt;/strong&gt; the time given. The exact wake-up depends on the scheduler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A sleeping thread keeps any locks it holds.&lt;/strong&gt; This matters for &lt;code&gt;synchronized&lt;/code&gt;, and it's the main difference from &lt;code&gt;wait()&lt;/code&gt;, which releases the lock.&lt;/li&gt;
&lt;li&gt;It throws the &lt;strong&gt;checked&lt;/strong&gt; exception &lt;code&gt;InterruptedException&lt;/code&gt;, so you must catch or declare it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Interrupting a sleeping thread
&lt;/h3&gt;

&lt;p&gt;Another thread can wake a sleeper early by calling &lt;code&gt;interrupt()&lt;/code&gt;. The sleeping thread then gets an &lt;code&gt;InterruptedException&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Woke up normally"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Interrupted!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;interrupt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Interrupted!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Treat an interrupt as a polite request to stop. A good habit: &lt;strong&gt;don't swallow it silently.&lt;/strong&gt; Either stop the work or restore the signal with &lt;code&gt;Thread.currentThread().interrupt();&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thread priority
&lt;/h2&gt;

&lt;p&gt;Every thread has a &lt;strong&gt;priority&lt;/strong&gt; from &lt;strong&gt;1 to 10&lt;/strong&gt;. The constants are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Thread.MIN_PRIORITY&lt;/code&gt; = 1&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Thread.NORM_PRIORITY&lt;/code&gt; = 5 (the default)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Thread.MAX_PRIORITY&lt;/code&gt; = 10
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPriority&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPriority&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MAX_PRIORITY&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPriority&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getPriority&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5
10
5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A new thread &lt;strong&gt;inherits&lt;/strong&gt; the priority of the thread that created it. Here &lt;code&gt;t&lt;/code&gt; started at 5 because &lt;code&gt;main&lt;/code&gt; is at 5. Setting a value outside 1 to 10 throws an &lt;code&gt;IllegalArgumentException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The important truth is that priority is only a &lt;strong&gt;hint&lt;/strong&gt; to the scheduler. A higher priority means "please prefer this thread," not "run this first." Java priorities are mapped onto the operating system's own priorities, and on many systems the effect is small or none. So:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Never rely on priority for correctness.&lt;/strong&gt; If your program works only when thread A runs before thread B, use &lt;code&gt;join()&lt;/code&gt; or proper coordination.&lt;/li&gt;
&lt;li&gt;Use priority only as a mild tuning hint, if at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The problem: race conditions
&lt;/h2&gt;

&lt;p&gt;Now the bug that gave me 143,267 instead of 200,000. We'll make two threads add to the same counter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RaceDemo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;};&lt;/span&gt;

        &lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Count: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output (it will be different every time):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Count: 143267
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We expected 200,000. Where did the missing increments go?&lt;/p&gt;

&lt;p&gt;The culprit is &lt;code&gt;count++&lt;/code&gt;. It looks like one step, but it's really &lt;strong&gt;three&lt;/strong&gt;: read the value, add one, write it back. Two threads can mix those steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   count = 5

   Thread A:  read count (5)
   Thread B:  read count (5)
   Thread A:  add 1, write 6
   Thread B:  add 1, write 6        &amp;lt;-- B overwrote A's work!

   Two increments happened, but count went from 5 to 6 instead of 7.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is called a &lt;strong&gt;race condition&lt;/strong&gt;: the result depends on the exact timing of the threads. The code that touches the shared data, called the &lt;strong&gt;critical section&lt;/strong&gt;, needs protection.&lt;/p&gt;

&lt;h2&gt;
  
  
  synchronized
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;synchronized&lt;/code&gt; keyword makes sure that &lt;strong&gt;only one thread at a time&lt;/strong&gt; can run a piece of code. Just add it to the method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the same program again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Count: 200000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every time, exactly 200,000.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works: the lock (monitor)
&lt;/h3&gt;

&lt;p&gt;Every Java object has a hidden &lt;strong&gt;lock&lt;/strong&gt;, also called a &lt;strong&gt;monitor&lt;/strong&gt;. When a thread enters a &lt;code&gt;synchronized&lt;/code&gt; method, it takes the lock of the object (&lt;code&gt;this&lt;/code&gt;). Any other thread that tries to enter a synchronized method of that &lt;strong&gt;same object&lt;/strong&gt; has to wait until the lock is released.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   counter object  (has one lock)

   Thread A  --&amp;gt; enters increment()  --&amp;gt; HOLDS the lock   --&amp;gt; runs count++  --&amp;gt; releases
   Thread B  --&amp;gt; tries increment()   --&amp;gt; BLOCKED, waiting for the lock ..........&amp;gt; then runs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the lock is free, a waiting thread gets it and continues.&lt;/p&gt;

&lt;h3&gt;
  
  
  synchronized blocks
&lt;/h3&gt;

&lt;p&gt;Locking a whole method can be too much. A &lt;strong&gt;synchronized block&lt;/strong&gt; protects only the lines that need it, using any object as the lock:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// other work that doesn't need the lock could go here&lt;/span&gt;
        &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the locked section as &lt;strong&gt;small&lt;/strong&gt; as possible, because while one thread holds the lock, the others are stuck waiting.&lt;/p&gt;

&lt;p&gt;There's also a version for static methods. A &lt;code&gt;static synchronized&lt;/code&gt; method locks the &lt;strong&gt;class object&lt;/strong&gt; (&lt;code&gt;Counter.class&lt;/code&gt;), since there's no &lt;code&gt;this&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Seeing the BLOCKED state
&lt;/h3&gt;

&lt;p&gt;Now we can finally see the &lt;code&gt;BLOCKED&lt;/code&gt; state in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;holder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="nc"&gt;Thread&lt;/span&gt; &lt;span class="n"&gt;waiter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Got the lock"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="n"&gt;holder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;waiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;waiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getState&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BLOCKED
Got the lock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;holder&lt;/code&gt; grabbed the lock and went to sleep &lt;strong&gt;while still holding it&lt;/strong&gt; (remember, &lt;code&gt;sleep&lt;/code&gt; doesn't release locks). &lt;code&gt;waiter&lt;/code&gt; then arrived and found the lock taken, so it sat in the &lt;code&gt;BLOCKED&lt;/code&gt; state. About a second later, &lt;code&gt;holder&lt;/code&gt; finished, &lt;code&gt;waiter&lt;/code&gt; got the lock, and "Got the lock" printed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;For a &lt;code&gt;synchronized&lt;/code&gt; &lt;strong&gt;block&lt;/strong&gt;, the compiler writes two bytecode instructions, &lt;code&gt;monitorenter&lt;/code&gt; and &lt;code&gt;monitorexit&lt;/code&gt;, around your code. It also adds a hidden exception handler, so the lock is &lt;strong&gt;always released&lt;/strong&gt;, even if your code throws an exception.&lt;/li&gt;
&lt;li&gt;For a &lt;code&gt;synchronized&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt;, the method is simply marked with a flag in the &lt;code&gt;.class&lt;/code&gt; file, and the JVM takes and releases the lock around the call.&lt;/li&gt;
&lt;li&gt;The lock is &lt;strong&gt;reentrant&lt;/strong&gt;: a thread that already holds a lock can enter other synchronized code on the same object without blocking itself.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;synchronized&lt;/code&gt; does two jobs. It gives &lt;strong&gt;mutual exclusion&lt;/strong&gt; (one thread at a time), and it guarantees &lt;strong&gt;visibility&lt;/strong&gt; (when a thread releases a lock, its changes are visible to the next thread that takes it).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A word on deadlock
&lt;/h3&gt;

&lt;p&gt;If thread A holds lock 1 and waits for lock 2, while thread B holds lock 2 and waits for lock 1, both wait forever. That's a &lt;strong&gt;deadlock&lt;/strong&gt;. The simplest defense is to always take multiple locks &lt;strong&gt;in the same order&lt;/strong&gt; in every thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Thread&lt;/code&gt; or &lt;code&gt;Runnable&lt;/code&gt;?&lt;/strong&gt; Use &lt;code&gt;Runnable&lt;/code&gt; (or a lambda). It keeps the task separate from the thread, and your class stays free to extend another class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Raw threads or an &lt;code&gt;ExecutorService&lt;/code&gt;?&lt;/strong&gt; In real applications, prefer an &lt;strong&gt;executor&lt;/strong&gt; (a thread pool), because creating threads is expensive and a pool reuses them. Raw threads are good for learning and for very simple cases. For huge numbers of blocking tasks, newer Java versions offer virtual threads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;synchronized&lt;/code&gt; method or block?&lt;/strong&gt; Use a &lt;strong&gt;block&lt;/strong&gt; when only part of the method needs protection. It keeps the locked time short.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;synchronized&lt;/code&gt; or &lt;code&gt;AtomicInteger&lt;/code&gt;?&lt;/strong&gt; For a single counter, &lt;code&gt;AtomicInteger&lt;/code&gt; and its &lt;code&gt;incrementAndGet()&lt;/code&gt; method are simpler and often faster. Use &lt;code&gt;synchronized&lt;/code&gt; when several variables must change together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;sleep&lt;/code&gt; or something smarter?&lt;/strong&gt; &lt;code&gt;sleep&lt;/code&gt; is fine for pauses and demos. To wait for a condition or for another thread, use &lt;code&gt;join()&lt;/code&gt;, &lt;code&gt;wait()/notify()&lt;/code&gt; or tools like &lt;code&gt;CountDownLatch&lt;/code&gt;, instead of sleeping and hoping.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Priority?&lt;/strong&gt; Leave it at the default. Never make correctness depend on it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Calling &lt;code&gt;run()&lt;/code&gt; instead of &lt;code&gt;start()&lt;/code&gt;.&lt;/strong&gt; The code runs on the current thread, and no new thread is created.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Starting the same thread twice.&lt;/strong&gt; The second &lt;code&gt;start()&lt;/code&gt; throws &lt;code&gt;IllegalThreadStateException&lt;/code&gt;. Create a new &lt;code&gt;Thread&lt;/code&gt; object instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming a thread order.&lt;/strong&gt; The scheduler decides, and the order changes between runs. Don't use &lt;code&gt;sleep&lt;/code&gt; or priority to force an order. Use &lt;code&gt;join()&lt;/code&gt; or proper coordination.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharing changeable data without protection.&lt;/strong&gt; The result is a race condition like our counter. Also check that all threads use the &lt;strong&gt;same lock object&lt;/strong&gt;. Locking on a new object each time, like &lt;code&gt;synchronized (new Object())&lt;/code&gt;, protects nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swallowing &lt;code&gt;InterruptedException&lt;/code&gt;.&lt;/strong&gt; An empty &lt;code&gt;catch&lt;/code&gt; hides the stop request. Either stop the work, or restore the flag with &lt;code&gt;Thread.currentThread().interrupt()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Holding a lock for too long.&lt;/strong&gt; Calling &lt;code&gt;sleep&lt;/code&gt; or doing slow work inside &lt;code&gt;synchronized&lt;/code&gt; makes every other thread wait. Also watch out for deadlock, and take locks in a fixed order.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;thread&lt;/strong&gt; is an independent path of execution inside a process. Threads share the &lt;strong&gt;heap&lt;/strong&gt;, and each has its own &lt;strong&gt;stack&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Create threads with &lt;code&gt;Runnable&lt;/code&gt; (or a lambda) and &lt;code&gt;Thread&lt;/code&gt;, and launch them with &lt;strong&gt;&lt;code&gt;start()&lt;/code&gt;&lt;/strong&gt;, not &lt;code&gt;run()&lt;/code&gt;. Use &lt;strong&gt;&lt;code&gt;join()&lt;/code&gt;&lt;/strong&gt; to wait for one to finish.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;thread scheduler&lt;/strong&gt; (JVM plus OS) decides who runs and for how long. The order isn't guaranteed.&lt;/li&gt;
&lt;li&gt;A thread's &lt;strong&gt;states&lt;/strong&gt;: &lt;code&gt;NEW&lt;/code&gt;, &lt;code&gt;RUNNABLE&lt;/code&gt;, &lt;code&gt;BLOCKED&lt;/code&gt;, &lt;code&gt;WAITING&lt;/code&gt;, &lt;code&gt;TIMED_WAITING&lt;/code&gt;, &lt;code&gt;TERMINATED&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;sleep(ms)&lt;/code&gt;&lt;/strong&gt; pauses the current thread without releasing locks, and it can be interrupted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Priority&lt;/strong&gt; (1 to 10, default 5) is only a hint, so don't depend on it.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;race condition&lt;/strong&gt; happens when threads change shared data at the same time. &lt;code&gt;count++&lt;/code&gt; is three steps, not one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;synchronized&lt;/code&gt;&lt;/strong&gt; lets one thread at a time into a critical section by using the object's lock, and it also makes changes visible to other threads. Keep locked sections small.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: build a &lt;code&gt;BankAccount&lt;/code&gt; with a &lt;code&gt;balance&lt;/code&gt; and a &lt;code&gt;deposit&lt;/code&gt; method. Start two threads that each deposit 1 rupee 100,000 times, and print the final balance. Run it a few times to see the wrong answers, then add &lt;code&gt;synchronized&lt;/code&gt; and see it become correct every time.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, print &lt;code&gt;getState()&lt;/code&gt; for a thread at each stage: before &lt;code&gt;start()&lt;/code&gt;, while sleeping, while blocked on a lock, and after it finishes. Then try giving two threads different priorities and see whether the output on your machine changes at all.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>concurrency</category>
      <category>programming</category>
    </item>
    <item>
      <title>throw vs throws in Java, and What “Ducking” Means</title>
      <dc:creator>Mayur Bodhare</dc:creator>
      <pubDate>Tue, 13 Oct 2026 17:27:40 +0000</pubDate>
      <link>https://dev.to/mayur_bodhare/throw-vs-throws-in-java-and-what-ducking-means-5f8h</link>
      <guid>https://dev.to/mayur_bodhare/throw-vs-throws-in-java-and-what-ducking-means-5f8h</guid>
      <description>&lt;p&gt;The first time one of my Java programs crashed, I got a wall of red text that ended with something like &lt;code&gt;Exception in thread "main"&lt;/code&gt;. I had no idea what it meant, which line to look at or how to stop it from happening again.&lt;/p&gt;

&lt;p&gt;Later I learned &lt;code&gt;try&lt;/code&gt; and &lt;code&gt;catch&lt;/code&gt;, and I thought I understood. Then more questions showed up. What's the difference between &lt;code&gt;throw&lt;/code&gt; and &lt;code&gt;throws&lt;/code&gt;? What does "ducking an exception" mean? Why does my &lt;code&gt;Scanner&lt;/code&gt; crash when the user types a word instead of a number? And why do people say &lt;code&gt;finally&lt;/code&gt; isn't enough anymore?&lt;/p&gt;

&lt;p&gt;In this post, we'll answer all of that in one place: exceptions, the exception hierarchy, &lt;code&gt;try&lt;/code&gt;, &lt;code&gt;catch&lt;/code&gt;, &lt;code&gt;finally&lt;/code&gt;, &lt;code&gt;throw&lt;/code&gt;, &lt;code&gt;throws&lt;/code&gt;, ducking, the &lt;code&gt;Scanner&lt;/code&gt; class and &lt;code&gt;try-with-resources&lt;/code&gt;. I've drawn the key pictures in text so you can see how things flow.&lt;/p&gt;

&lt;p&gt;Unless I show a full class, the snippets go inside a &lt;code&gt;main&lt;/code&gt; method.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an exception?
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;exception&lt;/strong&gt; is an unexpected event that happens while a program is running and disrupts its normal flow. Dividing by zero, reading a file that doesn't exist or calling a method on &lt;code&gt;null&lt;/code&gt; are all examples.&lt;/p&gt;

&lt;p&gt;Let's see what happens when nobody handles one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Demo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Before"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"After"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before
Exception in thread "main" java.lang.ArithmeticException: / by zero
    at Demo.main(Demo.java:5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things to notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"Before"&lt;/code&gt; printed, but &lt;code&gt;"After"&lt;/code&gt; &lt;strong&gt;never did&lt;/strong&gt;. The program stopped at the problem.&lt;/li&gt;
&lt;li&gt;The first line tells you the &lt;strong&gt;type&lt;/strong&gt; (&lt;code&gt;ArithmeticException&lt;/code&gt;) and a &lt;strong&gt;message&lt;/strong&gt; (&lt;code&gt;/ by zero&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;at Demo.main(Demo.java:5)&lt;/code&gt; line is the &lt;strong&gt;stack trace&lt;/strong&gt;. It tells you where it happened: file &lt;code&gt;Demo.java&lt;/code&gt;, line 5. When you read a crash, start at the top and look for the first line that points to your own code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Behind the scenes: what the JVM does
&lt;/h3&gt;

&lt;p&gt;When something goes wrong, the JVM creates an &lt;strong&gt;exception object&lt;/strong&gt;, fills it with the details (type, message and the call stack) and &lt;strong&gt;throws&lt;/strong&gt; it. The current method stops immediately. Then the JVM goes looking for code that can handle it, first in the current method, then in the method that called it, then the one that called that, moving up the call stack.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   main()  calls  process()  calls  divide()      &amp;lt;-- exception happens here
     ^               ^                 |
     |               |                 |
     +---------------+-----------------+
        the JVM unwinds UP the call stack, looking for a matching catch

   Nobody catches it?  The thread ends and the stack trace is printed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exception handling is simply the art of &lt;strong&gt;catching it on the way up&lt;/strong&gt; so the program can continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  The exception hierarchy
&lt;/h2&gt;

&lt;p&gt;Exceptions are objects, so they're organized into a family tree of classes. Knowing this tree tells you which exceptions you must handle and which you can ignore.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                          Throwable
                         /         \
                    Error           Exception
        (OutOfMemoryError,         /          \
         StackOverflowError)   IOException      RuntimeException
                               SQLException      ArithmeticException
                               FileNotFound-     NullPointerException
                                 Exception       ArrayIndexOutOfBounds-
                               InterruptedException   Exception
                                                 IllegalArgumentException
                               (CHECKED)            NumberFormatException
                                                 InputMismatchException
                                                    (UNCHECKED)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what each branch means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Throwable&lt;/code&gt;&lt;/strong&gt; is the root. Only objects of this class (or its children) can be thrown. It gives you &lt;code&gt;getMessage()&lt;/code&gt;, &lt;code&gt;printStackTrace()&lt;/code&gt; and &lt;code&gt;getCause()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Error&lt;/code&gt;&lt;/strong&gt; means a serious problem in the JVM itself, like running out of memory (&lt;code&gt;OutOfMemoryError&lt;/code&gt;) or endless recursion (&lt;code&gt;StackOverflowError&lt;/code&gt;). You normally &lt;strong&gt;don't catch&lt;/strong&gt; these, because your program can't repair them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Exception&lt;/code&gt;&lt;/strong&gt; is for problems your program can reasonably handle. It splits into two kinds:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Checked exceptions&lt;/strong&gt; are everything under &lt;code&gt;Exception&lt;/code&gt; &lt;strong&gt;except&lt;/strong&gt; &lt;code&gt;RuntimeException&lt;/code&gt;. They're for things outside your program's control, like missing files or network failures (&lt;code&gt;IOException&lt;/code&gt;, &lt;code&gt;SQLException&lt;/code&gt;). The compiler &lt;strong&gt;forces you&lt;/strong&gt; to handle them or declare them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileReader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.txt"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unreported exception FileNotFoundException; must be caught or declared to be thrown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Unchecked exceptions&lt;/strong&gt; are &lt;code&gt;RuntimeException&lt;/code&gt; and its children. They usually mean a &lt;strong&gt;bug in your code&lt;/strong&gt; (a bad index, a null reference, a bad argument). The compiler does &lt;strong&gt;not&lt;/strong&gt; force you to handle them, although you still can.&lt;/p&gt;

&lt;p&gt;A simple way to remember it: &lt;strong&gt;checked&lt;/strong&gt; means "the compiler checks that you dealt with it," and &lt;strong&gt;unchecked&lt;/strong&gt; means "the compiler leaves it to you."&lt;/p&gt;

&lt;h2&gt;
  
  
  try and catch
&lt;/h2&gt;

&lt;p&gt;To handle an exception, wrap the risky code in &lt;code&gt;try&lt;/code&gt; and write the response in &lt;code&gt;catch&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Result: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ArithmeticException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cannot divide by zero: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Program continues"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cannot divide by zero: / by zero
Program continues
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happened:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Java ran the &lt;code&gt;try&lt;/code&gt; block until the exception happened.&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;skipped the rest&lt;/strong&gt; of the &lt;code&gt;try&lt;/code&gt; block (so &lt;code&gt;"Result: ..."&lt;/code&gt; never printed).&lt;/li&gt;
&lt;li&gt;It jumped to the &lt;strong&gt;matching &lt;code&gt;catch&lt;/code&gt;&lt;/strong&gt; and ran it.&lt;/li&gt;
&lt;li&gt;The program &lt;strong&gt;continued normally&lt;/strong&gt; after the &lt;code&gt;try-catch&lt;/code&gt;. No crash.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The variable &lt;code&gt;e&lt;/code&gt; is the exception object. Printing it directly gives the type and message together: &lt;code&gt;java.lang.ArithmeticException: / by zero&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiple catch blocks
&lt;/h3&gt;

&lt;p&gt;One &lt;code&gt;try&lt;/code&gt; can have several &lt;code&gt;catch&lt;/code&gt; blocks for different problems. Java runs &lt;strong&gt;only the first one that matches&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"abc"&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]);&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;NumberFormatException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not a number: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ArithmeticException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Math problem"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Something else: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Not a number: For input string: "abc"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Order matters.&lt;/strong&gt; Put the &lt;strong&gt;most specific&lt;/strong&gt; exceptions first and the &lt;strong&gt;most general&lt;/strong&gt; last. If you put &lt;code&gt;Exception&lt;/code&gt; first, it would catch everything, and the later blocks could never run. The compiler notices and stops you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exception ArithmeticException has already been caught
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If two exceptions need the same handling, you can combine them with &lt;code&gt;|&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;NumberFormatException&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;ArithmeticException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bad input: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The two types can't be parent and child of each other.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes
&lt;/h3&gt;

&lt;p&gt;The compiler doesn't turn &lt;code&gt;try-catch&lt;/code&gt; into extra checks that run on every line. Instead, it writes an &lt;strong&gt;exception table&lt;/strong&gt; next to your bytecode. Each row says: "if an exception of this type happens between instruction A and instruction B, jump to the handler at instruction C." When nothing goes wrong, the table is never used, so a &lt;code&gt;try&lt;/code&gt; block costs almost nothing. The real cost comes when an exception is created, because the JVM has to record the stack trace.&lt;/p&gt;

&lt;h2&gt;
  
  
  finally
&lt;/h2&gt;

&lt;p&gt;Sometimes you need code that runs &lt;strong&gt;no matter what&lt;/strong&gt;, like closing a file or releasing a lock. That's what &lt;code&gt;finally&lt;/code&gt; is for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;divisor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;divisor&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ArithmeticException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Caught"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cleanup"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5
Cleanup
Caught
Cleanup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;finally&lt;/code&gt; block ran in &lt;strong&gt;both&lt;/strong&gt; cases: when everything went fine, and when an exception happened. Here is the flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        try block
           |
     exception happened?
      /              \
    no               yes
     |                |
     |         matching catch? -- yes --&amp;gt; run the catch block
     |                |                          |
     |                no                         |
     |       (exception will keep going up)      |
     v                v                          v
   +--------------------------------------------------+
   |        finally block ALWAYS runs here            |
   +--------------------------------------------------+
           |
           v
   continue the program, or keep propagating the exception
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  try-catch-finally, try-finally
&lt;/h3&gt;

&lt;p&gt;The combinations you can write:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;try&lt;/code&gt; + &lt;code&gt;catch&lt;/code&gt; (one or more)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;try&lt;/code&gt; + &lt;code&gt;catch&lt;/code&gt; + &lt;code&gt;finally&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;try&lt;/code&gt; + &lt;code&gt;finally&lt;/code&gt; (&lt;strong&gt;no catch at all&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last one is valid, and it's useful when you want to clean up but let the exception continue to the caller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"working"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"boom"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cleanup"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;working
cleanup
Exception in thread "main" java.lang.RuntimeException: boom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cleanup ran &lt;strong&gt;first&lt;/strong&gt;, and then the exception continued upward and crashed the program, because nobody caught it.&lt;/p&gt;

&lt;h3&gt;
  
  
  When does finally NOT run?
&lt;/h3&gt;

&lt;p&gt;Almost never. It runs even if the &lt;code&gt;try&lt;/code&gt; block has a &lt;code&gt;return&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"finally runs"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;finally runs
1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will not run if the JVM stops (for example &lt;code&gt;System.exit(0)&lt;/code&gt;), if the machine crashes or if the &lt;code&gt;try&lt;/code&gt; block never ends (an infinite loop).&lt;/p&gt;

&lt;p&gt;One warning: &lt;strong&gt;never write &lt;code&gt;return&lt;/code&gt; or &lt;code&gt;throw&lt;/code&gt; inside &lt;code&gt;finally&lt;/code&gt;.&lt;/strong&gt; It can silently replace the real result or hide an exception.&lt;/p&gt;

&lt;h3&gt;
  
  
  Behind the scenes
&lt;/h3&gt;

&lt;p&gt;The compiler &lt;strong&gt;copies the &lt;code&gt;finally&lt;/code&gt; code to every exit path&lt;/strong&gt;: the normal end of &lt;code&gt;try&lt;/code&gt;, the end of each &lt;code&gt;catch&lt;/code&gt;, and every &lt;code&gt;return&lt;/code&gt;. It also adds an "any exception" handler that runs the &lt;code&gt;finally&lt;/code&gt; code and then rethrows. That's how Java promises it always runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  throw vs throws
&lt;/h2&gt;

&lt;p&gt;These two look almost the same and trip up everyone, but they do different jobs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;throw&lt;/code&gt;&lt;/strong&gt; is a &lt;strong&gt;statement&lt;/strong&gt; that actually throws an exception &lt;strong&gt;object&lt;/strong&gt;. You use it inside a method body when you detect a problem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setAge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Age cannot be negative"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Age set to "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;setAge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;setAge&lt;/span&gt;&lt;span class="o"&gt;(-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IllegalArgumentException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Age set to 25
Error: Age cannot be negative
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;throws&lt;/code&gt;&lt;/strong&gt; is part of a &lt;strong&gt;method's signature&lt;/strong&gt;. It &lt;strong&gt;warns callers&lt;/strong&gt; that this method might throw certain exceptions, so they must be ready.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SQLException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the difference in short:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;throw&lt;/code&gt;&lt;/strong&gt; throws one exception object, and it's written &lt;strong&gt;inside&lt;/strong&gt; the method body, followed by &lt;code&gt;new SomeException(...)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;throws&lt;/code&gt;&lt;/strong&gt; declares possible exceptions, and it's written &lt;strong&gt;after the parameter list&lt;/strong&gt;, followed by &lt;strong&gt;class names&lt;/strong&gt; (one or more, separated by commas).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;throw&lt;/code&gt;&lt;/strong&gt; is the action. &lt;strong&gt;&lt;code&gt;throws&lt;/code&gt;&lt;/strong&gt; is the warning label.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;throws&lt;/code&gt; is required for checked exceptions&lt;/strong&gt; (otherwise the compiler complains). For unchecked ones it's optional.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A trick to remember it: &lt;strong&gt;throw&lt;/strong&gt;, singular, is one throw. &lt;strong&gt;throws&lt;/strong&gt;, plural, can list many.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom exceptions
&lt;/h3&gt;

&lt;p&gt;You can write your own exception by extending &lt;code&gt;Exception&lt;/code&gt; (checked) or &lt;code&gt;RuntimeException&lt;/code&gt; (unchecked). Let's make a checked one for a bank account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InsufficientFundsException&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;InsufficientFundsException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InsufficientFundsException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;InsufficientFundsException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"Balance "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" is less than "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Withdrawn "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Account&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withdraw&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;withdraw&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InsufficientFundsException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Withdrawn 200.0
Failed: Balance 300.0 is less than 600.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because &lt;code&gt;InsufficientFundsException&lt;/code&gt; is checked, the compiler forced two things: &lt;code&gt;withdraw&lt;/code&gt; had to declare &lt;code&gt;throws&lt;/code&gt;, and the caller had to catch it (or declare it too).&lt;/p&gt;

&lt;h2&gt;
  
  
  Ducking an exception
&lt;/h2&gt;

&lt;p&gt;Now the funny word. &lt;strong&gt;Ducking&lt;/strong&gt; an exception means &lt;strong&gt;not handling it in this method&lt;/strong&gt;, and passing it on to the caller by declaring it with &lt;code&gt;throws&lt;/code&gt;. The method "ducks" out of the way, and the problem flies over its head to whoever called it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;level3&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Problem in level3"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;level2&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;level3&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;                  &lt;span class="c1"&gt;// no try-catch here: level2 ducks it&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;level1&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;level2&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Handled in level1: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;level1&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Handled in level1: Problem in level3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   level1()  --calls--&amp;gt;  level2()  --calls--&amp;gt;  level3()
      ^                     ^                     |
      |                     |                     | throw new Exception(...)
      |                     +----- DUCKS ---------+  (just declares "throws")
      |                                           
      +------- CATCHES it and handles the problem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When should you catch, and when should you duck?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Catch&lt;/strong&gt; where you can &lt;strong&gt;do something useful&lt;/strong&gt;: show a message, retry, use a default value or clean up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Duck&lt;/strong&gt; when this method &lt;strong&gt;can't decide what to do&lt;/strong&gt;, and a higher-level method is in a better position. A low-level file reader doesn't know whether to show a popup or write a log, but the code that called it does.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be careful with one case: if &lt;code&gt;main&lt;/code&gt; ducks (&lt;code&gt;public static void main(String[] args) throws Exception&lt;/code&gt;), the exception goes to the JVM, and your program crashes. That's fine for quick experiments, but not for real programs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Scanner class
&lt;/h2&gt;

&lt;p&gt;Now let's apply this to something you'll use constantly. The &lt;strong&gt;&lt;code&gt;Scanner&lt;/code&gt;&lt;/strong&gt; class (in &lt;code&gt;java.util&lt;/code&gt;) reads input: from the keyboard, from a file or from a string. It splits the input into pieces called &lt;strong&gt;tokens&lt;/strong&gt;, separated by whitespace by default.&lt;/p&gt;

&lt;p&gt;The most-used methods are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;nextInt()&lt;/code&gt;, &lt;code&gt;nextDouble()&lt;/code&gt;, &lt;code&gt;nextBoolean()&lt;/code&gt; read the next token as that type.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;next()&lt;/code&gt; reads the next &lt;strong&gt;word&lt;/strong&gt; (one token).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nextLine()&lt;/code&gt; reads the &lt;strong&gt;whole rest of the line&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hasNextInt()&lt;/code&gt;, &lt;code&gt;hasNext()&lt;/code&gt; check whether the next token exists or has the right type, without reading it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;close()&lt;/code&gt; releases the resource.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Scanner&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Greeting&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Scanner&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;in&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter your name: "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter your age: "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", next year you will be "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A sample run (the second part of each line is what the user types):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter your name: Asha
Enter your age: 25
Hello Asha, next year you will be 26
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Behind the scenes
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;System.in&lt;/code&gt; is a stream of raw bytes from the keyboard. The &lt;code&gt;Scanner&lt;/code&gt; wraps it, reads the bytes into a &lt;strong&gt;buffer&lt;/strong&gt;, and hands them to you one token at a time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   keyboard --&amp;gt; System.in (bytes) --&amp;gt; Scanner's buffer --&amp;gt; tokens --&amp;gt; your variables

   You type:   25 [Enter]
   Buffer:     2 5 \n
               ^^^^
               nextInt() takes the token "25" and checks it looks like an int
               The "\n" (the Enter key) stays behind in the buffer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two details here matter for everything that follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;nextInt()&lt;/code&gt; takes the token, but it &lt;strong&gt;leaves the newline&lt;/strong&gt; (&lt;code&gt;\n&lt;/code&gt;) in the buffer.&lt;/li&gt;
&lt;li&gt;If the token &lt;strong&gt;isn't&lt;/strong&gt; a valid number, &lt;code&gt;nextInt()&lt;/code&gt; throws an &lt;code&gt;InputMismatchException&lt;/code&gt; and &lt;strong&gt;leaves the bad token in the buffer&lt;/strong&gt; (it does not consume it).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The famous nextLine trap
&lt;/h3&gt;

&lt;p&gt;Let's flip the order of our program and read the age first, then the name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter age: "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter name: "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Age: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", Name: ["&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"]"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A sample run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter age: 25
Enter name: Age: 25, Name: []
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The program never waited for the name! After &lt;code&gt;nextInt()&lt;/code&gt;, the buffer still held &lt;code&gt;\n&lt;/code&gt;. Then &lt;code&gt;nextLine()&lt;/code&gt; read from the current position to the end of the line, which is &lt;strong&gt;nothing&lt;/strong&gt;, so it returned an empty string right away.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Buffer after nextInt():     \n
                               ^^
   nextLine() reads "everything up to the newline", which is an empty text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fix is to eat the leftover newline with an extra &lt;code&gt;nextLine()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;                 &lt;span class="c1"&gt;// consume the leftover newline&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// now this waits for the real name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another safe option is to read &lt;strong&gt;everything&lt;/strong&gt; with &lt;code&gt;nextLine()&lt;/code&gt; and convert yourself: &lt;code&gt;int age = Integer.parseInt(sc.nextLine());&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exceptions that Scanner can throw
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;InputMismatchException&lt;/code&gt;&lt;/strong&gt; (unchecked): the token isn't the right type, like "abc" for &lt;code&gt;nextInt()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;NoSuchElementException&lt;/code&gt;&lt;/strong&gt; (unchecked): there's no more input to read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;IllegalStateException&lt;/code&gt;&lt;/strong&gt; (unchecked): you used the scanner after closing it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;FileNotFoundException&lt;/code&gt;&lt;/strong&gt; (checked): when creating a &lt;code&gt;Scanner&lt;/code&gt; from a &lt;code&gt;File&lt;/code&gt; that doesn't exist.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scanner with exception handling
&lt;/h2&gt;

&lt;p&gt;Here's the classic job: keep asking until the user types a valid age.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.InputMismatchException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Scanner&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SafeInput&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Scanner&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;in&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;valid&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter your age: "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Age must be between 0 and 120"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InputMismatchException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Please enter digits only."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;                    &lt;span class="c1"&gt;// throw away the bad input&lt;/span&gt;

            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IllegalArgumentException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Age accepted: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A sample run, where the user types &lt;code&gt;abc&lt;/code&gt;, then &lt;code&gt;-5&lt;/code&gt;, then &lt;code&gt;25&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter your age: abc
Please enter digits only.
Enter your age: -5
Age must be between 0 and 120
Enter your age: 25
Age accepted: 25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at how our new tools work together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;nextInt()&lt;/code&gt; throws &lt;code&gt;InputMismatchException&lt;/code&gt; for &lt;code&gt;abc&lt;/code&gt;, and the &lt;code&gt;catch&lt;/code&gt; handles it.&lt;/li&gt;
&lt;li&gt;We used &lt;code&gt;throw&lt;/code&gt; ourselves for a value that is a valid number but makes no sense (&lt;code&gt;-5&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;sc.nextLine()&lt;/code&gt; inside the first &lt;code&gt;catch&lt;/code&gt; is &lt;strong&gt;essential&lt;/strong&gt;. Remember: the bad token stays in the buffer. Without that line, the next &lt;code&gt;nextInt()&lt;/code&gt; would see &lt;code&gt;abc&lt;/code&gt; again, throw again, and the loop would repeat &lt;strong&gt;forever&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  An alternative without exceptions
&lt;/h3&gt;

&lt;p&gt;When bad input is expected (users make typos all the time), you can &lt;strong&gt;check first&lt;/strong&gt; instead of catching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Scanner&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;in&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter a number: "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasNextInt&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Digits only, please."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;                      &lt;span class="c1"&gt;// discard the bad token&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Enter a number: "&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"You entered "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A sample run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter a number: hello
Digits only, please.
Enter a number: 7
You entered 7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both approaches are fine. The &lt;code&gt;hasNextInt()&lt;/code&gt; style treats bad input as normal, so it needs no exception at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  try-with-resources
&lt;/h2&gt;

&lt;p&gt;Many things you use must be &lt;strong&gt;closed&lt;/strong&gt; when you're done: a &lt;code&gt;Scanner&lt;/code&gt;, files, network connections, database connections. If you forget, they leak. The old way was a &lt;code&gt;finally&lt;/code&gt; block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Scanner&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.txt"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FileNotFoundException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File not found"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sc&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a lot of code just to close something, and it's easy to get wrong. &lt;strong&gt;&lt;code&gt;try-with-resources&lt;/code&gt;&lt;/strong&gt; does it for you. You open the resource &lt;strong&gt;inside parentheses after &lt;code&gt;try&lt;/code&gt;&lt;/strong&gt;, and Java closes it automatically at the end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Scanner&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.txt"&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FileNotFoundException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File not found"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;finally&lt;/code&gt;, no null check, no &lt;code&gt;close()&lt;/code&gt; call. The rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The resource's class must implement &lt;strong&gt;&lt;code&gt;AutoCloseable&lt;/code&gt;&lt;/strong&gt; (or &lt;code&gt;Closeable&lt;/code&gt;, which extends it). &lt;code&gt;Scanner&lt;/code&gt; does.&lt;/li&gt;
&lt;li&gt;The resource variable is &lt;strong&gt;implicitly &lt;code&gt;final&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You can open &lt;strong&gt;several&lt;/strong&gt; resources, separated by semicolons.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;catch&lt;/code&gt; and &lt;code&gt;finally&lt;/code&gt; blocks are &lt;strong&gt;optional&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Since Java 9, you can use an existing effectively final variable: &lt;code&gt;try (sc) { ... }&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What happens in what order?
&lt;/h3&gt;

&lt;p&gt;Let's use a custom resource to see the exact order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Resource&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;AutoCloseable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Open "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Using "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Close "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Resource&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="nc"&gt;Resource&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RuntimeException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Oops"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RuntimeException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Caught "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finally"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open A
Open B
Using A
Using B
Close B
Close A
Caught Oops
Finally
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two rules are visible here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resources are closed in &lt;strong&gt;reverse order&lt;/strong&gt; of opening (B before A), like unstacking plates.&lt;/li&gt;
&lt;li&gt;They're closed &lt;strong&gt;before&lt;/strong&gt; the &lt;code&gt;catch&lt;/code&gt; and &lt;code&gt;finally&lt;/code&gt; blocks run. So by the time your &lt;code&gt;catch&lt;/code&gt; executes, the resources are already safely closed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Behind the scenes
&lt;/h3&gt;

&lt;p&gt;The compiler rewrites &lt;code&gt;try-with-resources&lt;/code&gt; into a &lt;code&gt;try-finally&lt;/code&gt;, roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   try (Resource r = new Resource()) {          Resource r = new Resource();
       use(r);                          ==&amp;gt;     Throwable primary = null;
   }                                            try {
                                                    use(r);
                                                } catch (Throwable t) {
                                                    primary = t;  throw t;
                                                } finally {
                                                    if (r != null) {
                                                        if (primary != null) {
                                                            try { r.close(); }
                                                            catch (Throwable s) { primary.addSuppressed(s); }
                                                        } else {
                                                            r.close();
                                                        }
                                                    }
                                                }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't need to memorize this. The key part is the &lt;strong&gt;suppressed exception&lt;/strong&gt; handling. What if your code throws an exception &lt;strong&gt;and&lt;/strong&gt; &lt;code&gt;close()&lt;/code&gt; also throws? With a hand-written &lt;code&gt;finally&lt;/code&gt;, the second exception would &lt;strong&gt;replace&lt;/strong&gt; the first one, and you'd lose the real cause. With &lt;code&gt;try-with-resources&lt;/code&gt;, the original exception stays as the main one, and the close failure is attached to it as a &lt;strong&gt;suppressed&lt;/strong&gt; exception that you can read with &lt;code&gt;e.getSuppressed()&lt;/code&gt;. That's one more reason it's better than a manual &lt;code&gt;finally&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's the earlier idea with a &lt;code&gt;Scanner&lt;/code&gt;, fully contained, with no files and no keyboard, so you can run it right now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Scanner&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"10 20 abc"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasNext&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextInt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InputMismatchException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bad number found"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bad number found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;Scanner&lt;/code&gt; can read from a plain &lt;code&gt;String&lt;/code&gt;, so &lt;code&gt;"10 20 abc"&lt;/code&gt; is our fake input. It added 10 and 20, then hit &lt;code&gt;abc&lt;/code&gt; and threw. The scanner was closed automatically, and the &lt;code&gt;catch&lt;/code&gt; handled the problem.&lt;/p&gt;

&lt;p&gt;One note about the keyboard: if you wrap &lt;code&gt;new Scanner(System.in)&lt;/code&gt; in &lt;code&gt;try-with-resources&lt;/code&gt;, closing it &lt;strong&gt;also closes &lt;code&gt;System.in&lt;/code&gt;&lt;/strong&gt;, and you can't read from the keyboard again later in the same program. For a console program that finishes right after, that's fine. Just don't create and close several scanners on &lt;code&gt;System.in&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one should I use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;try-catch or just let it crash?&lt;/strong&gt; Catch an exception when you can do something useful about it (retry, use a default, show a clear message). If you can't, let it travel up, or duck it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Catch or duck?&lt;/strong&gt; Catch it in the method that knows &lt;strong&gt;what to do&lt;/strong&gt;. Duck it when a higher level is in a better position to decide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;try-catch-finally or try-with-resources?&lt;/strong&gt; If the thing you're closing implements &lt;code&gt;AutoCloseable&lt;/code&gt; (files, scanners, connections), use &lt;strong&gt;try-with-resources&lt;/strong&gt;. Use a plain &lt;code&gt;finally&lt;/code&gt; only for cleanup that isn't a closeable resource, like resetting a flag or unlocking a lock.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checked or unchecked for my own exceptions?&lt;/strong&gt; Make it &lt;strong&gt;checked&lt;/strong&gt; when the caller can realistically recover from it (like &lt;code&gt;InsufficientFundsException&lt;/code&gt;). Make it &lt;strong&gt;unchecked&lt;/strong&gt; for programming mistakes (like a bad argument). Modern code leans toward unchecked, because checked ones force a lot of boilerplate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scanner: &lt;code&gt;hasNextInt()&lt;/code&gt; or try-catch?&lt;/strong&gt; Use &lt;code&gt;hasNextInt()&lt;/code&gt; when bad input is a normal, expected thing. Use try-catch when you read many values and want a single place to handle failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Empty catch blocks.&lt;/strong&gt; &lt;code&gt;catch (Exception e) { }&lt;/code&gt; hides the problem completely. At the very least, print or log the exception.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Catching &lt;code&gt;Exception&lt;/code&gt; or &lt;code&gt;Throwable&lt;/code&gt; everywhere.&lt;/strong&gt; It also swallows bugs you wanted to see, and &lt;code&gt;Throwable&lt;/code&gt; even catches serious &lt;code&gt;Error&lt;/code&gt;s. Catch the most specific type you can handle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Putting a general catch before a specific one.&lt;/strong&gt; The compiler says the specific exception "has already been caught." Specific first, general last.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forgetting to close resources.&lt;/strong&gt; Use try-with-resources so you never have to remember.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Falling into the Scanner traps.&lt;/strong&gt; Using &lt;code&gt;nextLine()&lt;/code&gt; right after &lt;code&gt;nextInt()&lt;/code&gt; without consuming the newline, and not clearing a bad token after &lt;code&gt;InputMismatchException&lt;/code&gt; (which causes an infinite loop).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mixing up &lt;code&gt;throw&lt;/code&gt; and &lt;code&gt;throws&lt;/code&gt;.&lt;/strong&gt; &lt;code&gt;throw&lt;/code&gt; goes in the body with an object (&lt;code&gt;throw new X()&lt;/code&gt;). &lt;code&gt;throws&lt;/code&gt; goes on the method signature with class names. Writing &lt;code&gt;throws new X()&lt;/code&gt; or &lt;code&gt;throw X&lt;/code&gt; is a compile error.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Another habit to avoid is using exceptions for normal flow, like looping until an exception happens. Exceptions are for exceptional situations, and they're slower than a simple &lt;code&gt;if&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;exception&lt;/strong&gt; is an object that represents a problem at run time. If nobody handles it, the program stops with a stack trace.&lt;/li&gt;
&lt;li&gt;The tree: &lt;code&gt;Throwable&lt;/code&gt; splits into &lt;code&gt;Error&lt;/code&gt; (don't catch) and &lt;code&gt;Exception&lt;/code&gt;. Under &lt;code&gt;Exception&lt;/code&gt;, &lt;strong&gt;checked&lt;/strong&gt; exceptions must be handled or declared, and &lt;strong&gt;unchecked&lt;/strong&gt; ones (&lt;code&gt;RuntimeException&lt;/code&gt; and children) are optional.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;try&lt;/code&gt;&lt;/strong&gt; wraps risky code, &lt;strong&gt;&lt;code&gt;catch&lt;/code&gt;&lt;/strong&gt; handles it (specific first, general last), and &lt;strong&gt;&lt;code&gt;finally&lt;/code&gt;&lt;/strong&gt; always runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;throw&lt;/code&gt;&lt;/strong&gt; throws one exception object inside a method. &lt;strong&gt;&lt;code&gt;throws&lt;/code&gt;&lt;/strong&gt; declares what a method might throw.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ducking&lt;/strong&gt; means declaring &lt;code&gt;throws&lt;/code&gt; instead of catching, so the caller deals with it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Scanner&lt;/code&gt;&lt;/strong&gt; reads tokens from the keyboard, files or strings. &lt;code&gt;nextInt()&lt;/code&gt; leaves the newline behind, and a bad token stays in the buffer.&lt;/li&gt;
&lt;li&gt;Handle bad input with &lt;code&gt;try-catch&lt;/code&gt; plus &lt;code&gt;sc.nextLine()&lt;/code&gt; to clear it, or check ahead with &lt;code&gt;hasNextInt()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;try-with-resources&lt;/strong&gt; closes &lt;code&gt;AutoCloseable&lt;/code&gt; resources automatically, in reverse order, before &lt;code&gt;catch&lt;/code&gt; and &lt;code&gt;finally&lt;/code&gt;, and it keeps the original exception safe.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;Here's a small practice idea: build a console calculator. Ask the user for two numbers and an operator (&lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;) using &lt;code&gt;Scanner&lt;/code&gt;. Keep asking until the numbers are valid. Handle division by zero with &lt;code&gt;try-catch&lt;/code&gt;, and throw your own &lt;code&gt;InvalidOperatorException&lt;/code&gt; (a custom checked exception) if the operator isn't one of the four. Wrap the whole &lt;code&gt;Scanner&lt;/code&gt; in try-with-resources.&lt;/p&gt;

&lt;p&gt;For a bonus experiment, create a text file with a few numbers and read it using &lt;code&gt;new Scanner(new File("numbers.txt"))&lt;/code&gt;. Handle the &lt;code&gt;FileNotFoundException&lt;/code&gt;, then try renaming the file to see the exception in action.&lt;/p&gt;

&lt;p&gt;If this helped, or if you spotted something I should fix, tell me in the comments. I'm still learning too.&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
