Java Tutorial
- Java - Home
- Java - Overview
- Java - History
- Java - Features
- Java vs C++
- Java Virtual Machine (JVM)
- Java - JDK vs JRE vs JVM
- Java - Hello World Program
- Java - Environment Setup
- Java - Basic Syntax
- Java - Variable Types
- Java - Data Types
- Java - Type Casting
- Java - Unicode System
- Java - Basic Operators
- Java - Comments
Java Control Statements
- Java - Loop Control
- Java - Decision Making
- Java - If-else
- Java - Switch
- Java - For Loops
- Java - For-Each Loops
- Java - While Loops
- Java - do-while Loops
- Java - Break
- Java - Continue
Object Oriented Programming
- Java - OOPs Concepts
- Java - Object & Classes
- Java - Class Attributes
- Java - Class Methods
- Java - Methods
- Java - Variables Scope
- Java - Constructors
- Java - Access Modifiers
- Java - Inheritance
- Java - Aggregation
- Java - Polymorphism
- Java - Overriding
- Java - Method Overloading
- Java - Dynamic Binding
- Java - Static Binding
- Java - Instance Initializer Block
- Java - Abstraction
- Java - Encapsulation
- Java - Interfaces
- Java - Packages
- Java - Inner Classes
- Java - Static Class
- Java - Anonymous Class
- Java - Singleton Class
- Java - Wrapper Classes
- Java - Enums
- Java - Enum Constructor
- Java - Enum Strings
Java Built-in Classes
Java File Handling
- Java - Files
- Java - Create a File
- Java - Write to File
- Java - Read Files
- Java - Delete Files
- Java - Directories
- Java - I/O Streams
Java Error & Exceptions
- Java - Exceptions
- Java - try-catch Block
- Java - try-with-resources
- Java - Multi-catch Block
- Java - Nested try Block
- Java - Finally Block
- Java - throw Exception
- Java - Exception Propagation
- Java - Built-in Exceptions
- Java - Custom Exception
Java Multithreading
- Java - Multithreading
- Java - Thread Life Cycle
- Java - Creating a Thread
- Java - Starting a Thread
- Java - Joining Threads
- Java - Naming Thread
- Java - Thread Scheduler
- Java - Thread Pools
- Java - Main Thread
- Java - Thread Priority
- Java - Daemon Threads
- Java - Thread Group
- Java - Shutdown Hook
Java Synchronization
- Java - Synchronization
- Java - Block Synchronization
- Java - Static Synchronization
- Java - Inter-thread Communication
- Java - Thread Deadlock
- Java - Interrupting a Thread
- Java - Thread Control
- Java - Reentrant Monitor
Java Networking
- Java - Networking
- Java - Socket Programming
- Java - URL Processing
- Java - URL Class
- Java - URLConnection Class
- Java - HttpURLConnection Class
- Java - Socket Class
- Java - Generics
Java Collections
Java Interfaces
- Java - List Interface
- Java - Queue Interface
- Java - Map Interface
- Java - SortedMap Interface
- Java - Set Interface
- Java - SortedSet Interface
Java Data Structures
Java Collections Algorithms
Advanced Java
- Java - Command-Line Arguments
- Java - Lambda Expressions
- Java - Sending Email
- Java - Applet Basics
- Java - Javadoc Comments
- Java - Autoboxing and Unboxing
- Java - File Mismatch Method
- Java - REPL (JShell)
- Java - Multi-Release Jar Files
- Java - Private Interface Methods
- Java - Inner Class Diamond Operator
- Java - Multiresolution Image API
- Java - Collection Factory Methods
- Java - Module System
- Java - Nashorn JavaScript
- Java - Optional Class
- Java - Method References
- Java - Functional Interfaces
- Java - Default Methods
- Java - Base64 Encode Decode
- Java - Switch Expressions
- Java - Teeing Collectors
- Java - Microbenchmark
- Java - Text Blocks
- Java - Dynamic CDS archive
- Java - Z Garbage Collector (ZGC)
- Java - Null Pointer Exception
- Java - Packaging Tools
- Java - Sealed Classes
- Java - Record Classes
- Java - Hidden Classes
- Java - Pattern Matching
- Java - Compact Number Formatting
- Java - Garbage Collection
- Java - JIT Compiler
Java Miscellaneous
- Java - Recursion
- Java - Regular Expressions
- Java - Serialization
- Java - Strings
- Java - Process API Improvements
- Java - Stream API Improvements
- Java - Enhanced @Deprecated Annotation
- Java - CompletableFuture API Improvements
- Java - Streams
- Java - Datetime Api
- Java 8 - New Features
- Java 9 - New Features
- Java 10 - New Features
- Java 11 - New Features
- Java 12 - New Features
- Java 13 - New Features
- Java 14 - New Features
- Java 15 - New Features
- Java 16 - New Features
Java APIs & Frameworks
Java Class References
- Java - Scanner Class
- Java - Arrays Class
- Java - Strings
- Java - Date & Time
- Java - ArrayList
- Java - Vector Class
- Java - Stack Class
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - The IdentityHashMap Class
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet Class
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection Interface
- Java - Array Methods
Java Useful Resources
Java - Sealed Classes and Interfaces
Java 15 introduced a sealed class as a preview feature which provides a fine-grained control over inheritance. Java 16 provides some minor enhancements and keeps this feature as a Preview. With Java 17, sealed class and interface a standard features. A sealed class/interface feature is added to Java to provide developers a fine fine-grained control over inheritance. A sealed class can define the subtypes that are permitted to extend it while other classes cannot extend it.
The following are salient points to consider for a sealed class −
- A sealed class is declared using a sealed keyword.
- Sealed classes allow to declaration of which class can be a subtype using the permits keyword.
- A class extending sealed class must be declared as either sealed, non-sealed, or final.
- Sealed classes help in creating a finite and determinable hierarchy of classes in inheritance.
Sealed Interface
An interface can be marked as sealed interface using sealed keyword and then using permits keywords, we can add the interfaces which can extend this interface.
public sealed interface Person permits Employee, Manager { }
Sealed Interface Example
In this example, we've created a sealed interface Person which permits Employee and Manager interfaces to extend it. Employee and Manager interfaces have different methods to get the ID of a person. Now in order to get ID of a person, we're using instanceof operator to check an instance being of Employee or Manager and get the corresponding ID. Thus we can see, that knowing the permissible interfaces upfront helps in development for such scenarios.
package com.tutorialspoint; public class Tester { public static void main(String[] args) { // create an instance of Manager Person manager = new CorpManager(23, "Robert"); // get the id System.out.println("Id: " + getId(manager)); } public static int getId(Person person) { // check if person is employee then return employee id if (person instanceof Employee) { return ((Employee) person).getEmployeeId(); } // if person is manager then return manager id else if (person instanceof Manager) { return ((Manager) person).getManagerId(); } return -1; } } // a sealed interface Person which is to be inherited by Employee // and Manager interfaces sealed interface Person permits Employee, Manager { String getName(); } // Employee and Manager interfaces have to extend Person and can be sealed or non-sealed non-sealed interface Employee extends Person { int getEmployeeId(); } non-sealed interface Manager extends Person { int getManagerId(); } class CorpEmployee implements Employee { String name; int id; public CorpEmployee(int id,String name) { this.name = name; this.id = id; } public String getName() { return name; } public int getEmployeeId() { return id; } } class CorpManager implements Manager { String name; int id; public CorpManager(int id,String name) { this.name = name; this.id = id; } public String getName() { return name; } public int getManagerId() { return id; } }
Let us compile and run the above program, this will produce the following result −
Id: 23
Sealed Class
Similar to sealed interface, a class can be marked as sealed class as well using sealed keyword and then using permits keywords, we can add the subclasses which can extend this class.
public abstract sealed class Person permits Employee, Manager { }
A subclass needs to have a modifier as sealed/final or non-sealed.
public final class Manager extends Person { }
A subclass with non-sealed is open for all classes to extend.
public non-sealed class Employee extends Person { }
Constraints
There are few constraint on usage of sealed classes which we should notice while extending a sealed class.
Permitted subclass should be part of same module as of sealed class.
Permitted subclass has to extend the sealed class.
A permitted subclass has to use any one of final, sealed, or non-sealed modifier.
Sealed Class Example
In this example, we've created a sealed abstract class Person which permits Employee and Manager classes to extend it. Employee and Manager classes have different methods to get the ID of a person. Now in order to get ID of a person, we're using instanceof operator to check an instance being of Employee or Manager and get the corresponding ID. Thus we can see, that knowing the permissible SubClasses upfront helps in development for such scenarios.
package com.tutorialspoint; public class Tester { public static void main(String[] args) { // create an instance of Manager Person manager = new Manager(23, "Robert"); // get the id System.out.println("Id: " + getId(manager)); } public static int getId(Person person) { // check if person is employee then return employee id if (person instanceof Employee) { return ((Employee) person).getEmployeeId(); } // if person is manager then return manager id else if (person instanceof Manager) { return ((Manager) person).getManagerId(); } return -1; } } // a sealed class Person which is to be inherited by Employee // and Manager classes abstract sealed class Person permits Employee, Manager { String name; String getName() { return name; } } // Employee class has to extend Person and should have a modifier final class Employee extends Person { String name; int id; Employee(int id, String name){ this.id = id; this.name = name; } int getEmployeeId() { return id; } } // We can mark a sub-class as non-sealed, so that it can be extended if required non-sealed class Manager extends Person { int id; Manager(int id, String name){ this.id = id; this.name = name; } int getManagerId() { return id; } }
Let us compile and run the above program, this will produce the following result −
Id: 23