<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Java on dplabs — Software Engineering &amp; Technology Consultancy</title>
		<link>https://dplabs.tech/tags/java/</link>
		<description>Recent content in Java on dplabs — Software Engineering &amp; Technology Consultancy</description>
		<generator>Hugo</generator>
		<language>en-us</language>
		
		
		
		
			<lastBuildDate>Mon, 23 Jun 2025 00:00:00 +0000</lastBuildDate>
		
			<atom:link href="https://dplabs.tech/tags/java/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>Java Performance: Stop Guessing, Start Measuring</title>
				<link>https://dplabs.tech/blog/java-performance-stop-guessing/</link>
				<pubDate>Mon, 23 Jun 2025 00:00:00 +0000</pubDate>
				<guid>https://dplabs.tech/blog/java-performance-stop-guessing/</guid>
				<description>&lt;p&gt;Most Java performance work starts in the wrong place. An engineer identifies &amp;ldquo;the application is slow,&amp;rdquo; forms a hypothesis based on code familiarity, and makes changes based on intuition. Sometimes it works. More often, the actual bottleneck was elsewhere and the optimized code is now more complex with no performance benefit.&lt;/p&gt;&#xA;&lt;p&gt;The methodology matters: &lt;strong&gt;measure, identify the bottleneck, optimize, measure again&lt;/strong&gt;. In that order. Not &amp;ldquo;optimize the thing that looks suspicious, then measure.&amp;rdquo;&lt;/p&gt;</description>
			</item>
			<item>
				<title>Structured Concurrency in Java: Fixing Unstructured Concurrent Code</title>
				<link>https://dplabs.tech/blog/structured-concurrency-java/</link>
				<pubDate>Mon, 28 Apr 2025 00:00:00 +0000</pubDate>
				<guid>https://dplabs.tech/blog/structured-concurrency-java/</guid>
				<description>&lt;p&gt;Java&amp;rsquo;s concurrency model has been functional for decades. &lt;code&gt;ExecutorService&lt;/code&gt;, &lt;code&gt;Future&lt;/code&gt;, &lt;code&gt;CompletableFuture&lt;/code&gt; — these tools work. They also have a persistent problem: when you submit tasks to an executor, the relationship between the spawning thread and the spawned tasks is not represented in the code. Errors are easy to lose. Cancellation doesn&amp;rsquo;t propagate automatically. Resources leak when tasks outlive their intended scope.&lt;/p&gt;&#xA;&lt;p&gt;Structured concurrency, finalized in Java 24 (JEP 505 after multiple preview rounds), fixes this. The core principle: &lt;strong&gt;concurrent tasks should have lifetimes that are scoped to the block of code that spawned them&lt;/strong&gt;, just as &lt;code&gt;try-with-resources&lt;/code&gt; scopes resource lifetimes.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Records and Sealed Classes: Better Domain Models in Java</title>
				<link>https://dplabs.tech/blog/records-sealed-classes-domain-models/</link>
				<pubDate>Mon, 27 Jan 2025 00:00:00 +0000</pubDate>
				<guid>https://dplabs.tech/blog/records-sealed-classes-domain-models/</guid>
				<description>&lt;p&gt;Java domain modeling has historically been verbose and error-prone. Entity classes with dozens of getter/setter pairs, boolean fields that encode state (&lt;code&gt;isActive&lt;/code&gt;, &lt;code&gt;isCancelled&lt;/code&gt;, &lt;code&gt;isPending&lt;/code&gt;), and null fields used to represent the absence of a value all create code that&amp;rsquo;s hard to understand and easy to misuse.&lt;/p&gt;&#xA;&lt;p&gt;Records and sealed classes address this. They&amp;rsquo;re not cosmetic improvements — they change what kinds of mistakes the compiler can catch for you.&lt;/p&gt;&#xA;&lt;h2 id=&#34;records-immutable-data-carriers&#34;&gt;Records: Immutable Data Carriers&lt;/h2&gt;&#xA;&lt;p&gt;A record is a class defined by its components. The compiler generates the constructor, accessors, &lt;code&gt;equals&lt;/code&gt;, &lt;code&gt;hashCode&lt;/code&gt;, and &lt;code&gt;toString&lt;/code&gt; automatically:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Pattern Matching in Modern Java: Records, Switch, and Exhaustiveness</title>
				<link>https://dplabs.tech/blog/pattern-matching-modern-java/</link>
				<pubDate>Mon, 20 Jan 2025 00:00:00 +0000</pubDate>
				<guid>https://dplabs.tech/blog/pattern-matching-modern-java/</guid>
				<description>&lt;p&gt;Pattern matching in Java 21 is the culmination of several interconnected features: &lt;code&gt;instanceof&lt;/code&gt; patterns (Java 16), sealed classes (Java 17), switch expressions (Java 14), and switch patterns (Java 21). Understanding them individually is useful. Understanding how they compose is where the real power is.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-baseline-pattern-matching-for-instanceof&#34;&gt;The Baseline: Pattern Matching for instanceof&lt;/h2&gt;&#xA;&lt;p&gt;Before Java 16, checking and casting looked like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Object&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;shape&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getShape&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;shape&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;instanceof&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Circle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Circle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Circle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;shape&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// Redundant cast&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;area&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;shape&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;instanceof&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Rectangle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Rectangle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Rectangle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;shape&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;area&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Java 16 introduced pattern variables in &lt;code&gt;instanceof&lt;/code&gt;:&lt;/p&gt;</description>
			</item>
			<item>
				<title>Java 17 to 21: Modern Java Is a Different Language</title>
				<link>https://dplabs.tech/blog/java-17-to-21-modern-java/</link>
				<pubDate>Mon, 16 Dec 2024 00:00:00 +0000</pubDate>
				<guid>https://dplabs.tech/blog/java-17-to-21-modern-java/</guid>
				<description>&lt;p&gt;Java 21 is the current long-term support release as of late 2024, and it represents something unusual: a Java that looks substantively different from Java 8. Not just faster or more convenient — different in how you model domains and reason about concurrency.&lt;/p&gt;&#xA;&lt;p&gt;This article focuses on the features that arrived between Java 17 and Java 21 (covered separately) and the cohesive picture they form together.&lt;/p&gt;&#xA;&lt;h2 id=&#34;pattern-matching-for-switch-finalized-java-21&#34;&gt;Pattern Matching for Switch (Finalized Java 21)&lt;/h2&gt;&#xA;&lt;p&gt;Pattern matching for &lt;code&gt;instanceof&lt;/code&gt; arrived in Java 16. Java 21 extended pattern matching to &lt;code&gt;switch&lt;/code&gt; — and this is where the power becomes apparent.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Modern Spring Boot Architecture: Beyond the Three-Layer Application</title>
				<link>https://dplabs.tech/blog/modern-spring-boot-architecture/</link>
				<pubDate>Mon, 02 Dec 2024 00:00:00 +0000</pubDate>
				<guid>https://dplabs.tech/blog/modern-spring-boot-architecture/</guid>
				<description>&lt;p&gt;The three-layer architecture — controllers, services, repositories — is how most Spring Boot tutorials present application structure. It&amp;rsquo;s a reasonable starting point. It&amp;rsquo;s also a pattern that breaks down as applications grow.&lt;/p&gt;&#xA;&lt;p&gt;The problems are predictable: services become God classes with hundreds of methods, repository calls leak into controllers, domain logic spreads across multiple layers, and changing anything requires understanding the entire application at once. The layered architecture doesn&amp;rsquo;t enforce boundaries — it suggests them. Suggestions decay under deadline pressure.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Virtual Threads in Java 21: What They Solve and What They Don&#39;t</title>
				<link>https://dplabs.tech/blog/virtual-threads-java-21/</link>
				<pubDate>Mon, 04 Nov 2024 00:00:00 +0000</pubDate>
				<guid>https://dplabs.tech/blog/virtual-threads-java-21/</guid>
				<description>&lt;p&gt;Virtual threads were the most anticipated Java feature in years. Project Loom&amp;rsquo;s promise was simple: write blocking code that scales like non-blocking code. Java 21 delivered them as a finalized, production-ready feature. They work. The caveats matter.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-problem-virtual-threads-solve&#34;&gt;The Problem Virtual Threads Solve&lt;/h2&gt;&#xA;&lt;p&gt;Traditional Java concurrency has a fundamental constraint: &lt;strong&gt;platform threads are expensive&lt;/strong&gt;. Each platform thread maps 1:1 to an OS thread. OS threads consume roughly 1MB of stack space by default and are expensive to create and context-switch.&lt;/p&gt;</description>
			</item>
			<item>
				<title>Java 9 to 17: The Language Features You Should Actually Be Using</title>
				<link>https://dplabs.tech/blog/java-9-to-17-features/</link>
				<pubDate>Mon, 07 Oct 2024 00:00:00 +0000</pubDate>
				<guid>https://dplabs.tech/blog/java-9-to-17-features/</guid>
				<description>&lt;p&gt;Java 8 was a turning point. Lambdas and streams changed the language substantially. Then came a long stretch where each release felt like maintenance work — modules in 9 were important but painful, and the subsequent releases improved the language incrementally without a clear headline.&lt;/p&gt;&#xA;&lt;p&gt;That changed with Java 14–17. The features that landed in this window — records, sealed classes, pattern matching for &lt;code&gt;instanceof&lt;/code&gt;, text blocks, switch expressions — are not conveniences. They change how you model domains and reason about code.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
