
Overview of Java 21 Features
Get a quick Overview of Java 21 Features, including virtual threads, string templates, and performance upgrades. Ideal for developers and Java learners in 2025.
The Following are the Features of Java 21
1. Pattern Matching for switch
Objective: Permit switch statements to match patterns with types and conditions.
Explanation: Introduced in Java 21 (finalized in JEP 441), Pattern Matching for Switch improves on the conventional switch statement by enabling you to match values by type patterns in addition to constant values. Guard conditions, scoped variable declarations, and type-based case labels are all supported. Multiple instanceof checks and casting are no longer necessary thanks to this functionality, which also makes the text easier to read.
Example:
public class SwitchPatternMatchingDemo {
public static void main(String[] args) {
Object obj1 = 1234;
String result = switch (obj1) {
case Integer i -> "It's an Integer: " + i;
case String s -> "It's a String: " + s;
default -> "Unknown type";
};
System.out.println(result);
}
}
2. Record Pattern
Objective: Use pattern matching to streamline the process of extracting values from record classes.
Explanation: Finalized in Java 21 (JEP 440), Record Patterns improve pattern matching by enabling record object deconstruction straight within instanceof or switch. By safely and succinctly extracting fields from records, this feature reduces boilerplate and streamlines code.
Example:
record MyPoint(int x, int y) {}
public class RecordPatternDemoExample {
public static void main(String[] args) {
MyPoint point = new MyPoint(30, 40);
if (point instanceof MyPoint(int x, int y)) {
System.out.println("X: " + x + ", Y: " + y);
}
}
}
3. Virtual Thread
Objective: To achieve high concurrency, create lightweight threads.
Explanation: As a last-minute addition to Java 21, Virtual Threads transform the way we develop concurrent programs by offering high-throughput, lightweight threads that are controlled by the Java Virtual Machine (JVM) rather than the operating system.
Example:
import java.util.concurrent.Executors;
public class VirtualThreadsDemoExample {
public static void main(String[] args) {
try (var executor1 = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 5; i++) {
int finalI = i;
executor1.submit(() -> {
System.out.println("Virtual thread " + finalI + " - " + Thread.currentThread());
});
}
}
}
}
Explore Other Demanding Courses
No courses available for the selected domain.
4. Sequence Collection
Objective: Give collection ordering guarantees.
Explanation: Java 21 introduces a new set of interfaces called Sequenced Collections, which give collections like List, LinkedHashSet, and LinkedHashMap that preserve a specified order (sequence) of components, for consistency and clarity.
Prior to Java 21:
- List and LinkedHashSet were among the collections you had ordered.
- However, there was no shared interface for reversing collections or accessing elements from the front or rear.
Java now has Sequenced Collections:
- provides excellent assistance for handling ordered data.
- permits items to be accessed, added, or removed from both ends.
- Easily supports collections in reverse views.
Example:
Key Methods
public interface SequencedCollection<E> extends Collection<E> {
SequencedCollection<E> reversed();
E getFirst();
E getLast();
void addFirst(E e);
void addLast(E e);
E removeFirst();
E removeLast();
}
List is a SequencedCollection
List<String> names = new ArrayList<>();
names.add("A");
names.add("B");
names.add("C");
System.out.println(((SequencedCollection<String>) names).getFirst()); // A
System.out.println(((SequencedCollection<String>) names).getLast()); // C
SequencedMap Interface: Key Methods
public interface SequencedMap<K,V> extends Map<K,V> {
SequencedMap<K,V> reversed();
Entry<K,V> firstEntry();
Entry<K,V> lastEntry();
V putFirst(K key, V value);
V putLast(K key, V value);
V removeFirst();
V removeLast();
}
LinkedHashMap is a SequencedMap
LinkedHashMap<Integer, String> map = new LinkedHashMap<>();
map.put(1, "One");
map.put(2, "Two");
map.put(3, "Three");
SequencedMap<Integer, String> seqMap = map;
System.out.println(seqMap.firstEntry()); // 1=One
System.out.println(seqMap.lastEntry()); // 3=Three
SequencedSet Interface
public interface SequencedSet<E> extends SequencedCollection<E>, Set<E> {
SequencedSet<E> reversed();
}
LinkedHashSet<String> set1 = new LinkedHashSet<>();
set1.add("Red");
set1.add("Green");
set1.add("Blue");
SequencedSet<String> seqSet1 = (SequencedSet<String>) set1;
System.out.println(seqSet1.getFirst()); // Red
System.out.println(seqSet1.getLast()); // Blue
5. Key Encapsulation Mechanism (KEM)
Objective: Using public key cryptography, two parties can safely agree on a shared secret key by utilizing a cryptographic technique called a Key Encapsulation Mechanism (KEM).
It's commonly used in:
- TLS (Transport Layer Security)
- Post-quantum cryptography
- Hybrid encryption systems
Explanation: A public-key cryptography approach called a Key Encapsulation Mechanism (KEM) is used to safely communicate a secret (symmetric) key.
KEM encapsulates a randomly generated symmetric key and transmits it to the recipient, who can decrypt it using their private key, as opposed to immediately encrypting data using the public key.
Example:
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.KeyEncapsulation;
import javax.crypto.KeyEncapsulationResult;
import java.security.*;
public class KEMExampleDemo {
public static void main(String[] args) throws Exception {
// Generate RSA key pair
KeyPairGenerator keyPairGen1 = KeyPairGenerator.getInstance("RSA");
keyPairGen1.initialize(2048);
KeyPair keyPair1 = keyPairGen1.generateKeyPair();
// Get KeyEncapsulation instance (RSA-KEM)
KeyEncapsulation kem1 = KeyEncapsulation.getInstance("RSA-KEM");
// Encapsulate (sender side)
KeyEncapsulationResult result1 = kem.encapsulate(keyPair1.getPublic(), null);
byte[] encapsulatedKey1 = result1.getEncapsulation();
SecretKey secretKey1 = result1.getSecretKey();
System.out.println("Encapsulated Key: " + java.util.Base64.getEncoder().encodeToString(encapsulatedKey1));
System.out.println("Shared Secret (Sender): " + java.util.Base64.getEncoder().encodeToString(secretKey1.getEncoded()));
// Decapsulate (receiver side)
SecretKey receivedSecret1 = kem1.decapsulate(keyPair1.getPrivate(), encapsulatedKey1, null);
System.out.println("Shared Secret (Receiver): " + java.util.Base64.getEncoder().encodeToString(receivedSecret.getEncoded()));
}
}
Do visit our channel to learn more: SevenMentor