0% found this document useful (0 votes)
10 views38 pages

Java Unit 3 CodeWithSubhsam

The document provides a comprehensive overview of key Java concepts including Functional Interfaces, Lambda Expressions, Default and Static Methods in Interfaces, Base64 encoding, the forEach method, Try-with-Resources, and Annotations. It explains their definitions, uses, syntax, and benefits, along with examples of Java code demonstrating each concept. Additionally, it touches on the Java Module System introduced in Java 9 for improved application structure and encapsulation.

Uploaded by

12pcm.deepak
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views38 pages

Java Unit 3 CodeWithSubhsam

The document provides a comprehensive overview of key Java concepts including Functional Interfaces, Lambda Expressions, Default and Static Methods in Interfaces, Base64 encoding, the forEach method, Try-with-Resources, and Annotations. It explains their definitions, uses, syntax, and benefits, along with examples of Java code demonstrating each concept. Additionally, it touches on the Java Module System introduced in Java 9 for improved application structure and encapsulation.

Uploaded by

12pcm.deepak
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

CodeWithSubhsam

■ Click here to access the resource

🔷 What is a Functional Interface?


A Functional Interface is an interface that contains exactly one abstract method.​
These interfaces are used primarily in lambda expressions and method references.

✅ Key Characteristics:
Feature Detail

Abstract Method Only one (can have multiple default or static


methods)

@FunctionalInterfa Annotation to ensure interface is functional


ce

Used With Lambda expressions, method references

🧪 Example:
@FunctionalInterface

interface MyFunctionalInterface {

​ void show(); // Single abstract method

✅ Used with Lambda:


public class Main {

​ public static void main(String[] args) {

​ MyFunctionalInterface obj = () -> System.out.println("Hello from Lambda!");

​ obj.show(); // Output: Hello from Lambda!


CodeWithSubhsam
■ Click here to access the resource

​ }

🧠 Benefits of Functional Interfaces


●​ Enables cleaner and readable code using lambda.
●​ Reduces boilerplate code.
●​ Supports functional programming style in Java.

🔒 Why use @FunctionalInterface?


●​ It's optional but recommended.
●​ It gives a compile-time error if you accidentally add another abstract method.

@FunctionalInterface

interface InvalidInterface {

​ void method1();

​ void method2(); // ❌ Compile-time error


}

✅ What is an Anonymous Inner Class? = not in syllabus but for Lamda


expression

An Anonymous Inner Class is a class without a name that is used to instantiate a class or
interface immediately for one-time use.

✅ Why use Anonymous Inner Class?


CodeWithSubhsam
■ Click here to access the resource

Reason Explanation

✂️ Less code No need to create a separate subclass

🧠 One-time use Used when object is needed only once

🚀 Useful with Especially with functional interfaces like Runnable,


interfaces ActionListener, etc.

🔑 Rules of Anonymous Inner Class


Rule Description

No constructor You can’t define a constructor (no class


name)

One-time use Used where the object is created

Can override methods Yes, can override superclass/interface


methods

✅ Java Code: Abstract Class + Anonymous Inner Class


abstract class A {

​ public abstract void show(); // abstract method

}
CodeWithSubhsam
■ Click here to access the resource

// class B extends A{

// ​ @override

// ​ public void show(){

// ​ System.out.print(“Heyy”) ;

// ​ }

//}

public class Demo {

​ public static void main(String[] args) {

​ A obj = new A() {

​ public void show() {

​ System.out.println("in new Show");

​ }

​ };

​ obj.show(); // Output: in new Show

​ }

✅ Explanation:
1.​ A is an abstract class with one abstract method show().
2.​ You cannot instantiate an abstract class directly.
3.​ Instead, we use an anonymous inner class to:
○​ Create a subclass of A
○​ Provide implementation for show()
○​ Use the object immediately
CodeWithSubhsam
■ Click here to access the resource

🔍 Key Point:
●​ This avoids creating a separate class like:

class B extends A {

​ public void show() {

​ ...

​ }

✅ What is a Lambda Expression?


A Lambda Expression is a short block of code which takes in parameters and returns a value.​
It is a way to represent functional interfaces (interfaces with a single abstract method).

🔷 Key Points of Lambda Expression


Feature Description

🎯 Target Only works with functional interfaces

🧠 Syntax (parameters) -> { body }

🚫 No class No need to define a separate class


name

✅ Used for Cleaner, shorter code especially with interfaces like Runnable,
Comparator, etc.
CodeWithSubhsam
■ Click here to access the resource

✅ Syntax:
(parameter1, parameter2) -> {

​ // body

Simplified versions:

●​ No parameter: () -> System.out.println("Hello")


●​ One parameter: x -> x*x
●​ One line body: No braces needed

🔁 Now, Convert This Code:


@FunctionalInterface

Interface class A {

​ public abstract void show();

public class Demo {

​ public static void main(String[] args) {

​ A obj = new A() {

​ public void show() {

System.out.println("in new Show");

​ }

​ };

​ obj.show();

​ }

}
CodeWithSubhsam
■ Click here to access the resource

✅ Final Lambda Version (Full Code):


@FunctionalInterface

interface A {

​ void show();

public class Demo {

​ public static void main(String[] args) {

​ A obj = () -> System.out.println("in new Show");

​ obj.show();

​ }

✅ What is a Default Method in Java?


Introduced in Java 8, a default method is a method in an interface that:

●​ Has a body
●​ Is marked with the default keyword
●​ Is used to provide backward compatibility to interfaces

🔷 Why Default Methods?


Before Java 8, interfaces could only have abstract methods.​
This caused problems when you wanted to add new methods to interfaces without breaking
the existing implementing classes.

✅ Default methods solve this problem by allowing methods with a body inside interfaces.
✅ Syntax:
CodeWithSubhsam
■ Click here to access the resource

interface Demo {

​ void abc(); // abstract method

​ default void show() {

System.out.println("in show");

​ }

✅ Key Points:
Feature Description

🎯 Must use default keyword Otherwise it’s abstract


🧱 Has method body Unlike traditional interface methods

🔁 Can be overridden In implementing class


🚫 Not abstract It's concrete (has implementation)

🔥 If a class implements the interface, it:


●​ Must override abstract methods (like abc())
●​ May override default methods (like show())

✅ Code from Screenshot (Complete)


@FunctionalInterface

interface Demo {
CodeWithSubhsam
■ Click here to access the resource

​ void abc(); // abstract method

​ default void show() {

System.out.println("in show");

​ }

class DemoImp implements Demo {

​ public void abc() {

System.out.println("in abc");

​ }

​ public void show() {

System.out.println("in New Show");

​ }

public class InterfaceDemo {

​ public static void main(String[] args) {

​ Demo d = new DemoImp();

​ d.abc();​ // Output: in abc

​ d.show(); // Output: in New Show

​ }

}
CodeWithSubhsam
■ Click here to access the resource

✅ Output:
in abc

in New Show

🧠 What if show() wasn’t overridden?


If DemoImp didn’t override show(), then still the interface’s default method run:

✅ Static Method in Interface (Super Simple):


A static method in an interface is a method you can call without creating an object, by using
the interface name.

✅ Syntax:
interface InterfaceName {

​ static void methodName() {

​ // method body

​ }

🔍 Important Rules:
Rule Description
CodeWithSubhsam
■ Click here to access the resource

❌ Cannot be overridden Static methods belong to the interface, not to


implementing classes

✅ Must be called using InterfaceName.method()


interface name

🚫 Not inherited Implementing classes do not inherit static methods

✅ Example Code:
interface Demo {

​ static void greet() {

System.out.println("Hello from interface static method!");

​ }

​ void abc(); // abstract method

class DemoImp implements Demo {

​ public void abc() {

System.out.println("in abc");

​ }

public class InterfaceStaticMethodExample {

​ public static void main(String[] args) {

​ Demo d = new DemoImp();


CodeWithSubhsam
■ Click here to access the resource

​ d.abc();

​ // Call static method using interface name

​ Demo.greet();

​ }

✅ Output:
in abc

Hello from interface static method!

✅ Summary Table: Default vs Static Method in Interface


Feature default Method static Method

Has body? ✅ Yes ✅ Yes


Overridable? ✅ Yes (in class) ❌ No
Call via Object / Interface Interface
Ref Name

Inherited? ✅ Yes ❌ No
Introduced in Java 8 Java 8
CodeWithSubhsam
■ Click here to access the resource

✅ What is Base64?
Base64 is a way to encode binary data (like files, images, or text) into a text format using
only letters, numbers, and symbols.

It is commonly used to:

●​ Send data over the internet


●​ Encode passwords, images, or JSON

✅ Java Code: Base64 Encoding & Decoding


Java provides Base64 utility in java.util package.

🔷 1. ✅ Encode String to Base64


import java.util.Base64;

public class EncodeExample {

​ public static void main(String[] args) {

​ String text = "HelloJava";

​ String encoded = Base64.getEncoder().encodeToString(text.getBytes());

System.out.println("Encoded: " + encoded);

​ }

🧾 Output:
CodeWithSubhsam
■ Click here to access the resource

Encoded: SGVsbG9KYXZh

🔷 2. ✅ Decode Base64 to Original String


import java.util.Base64;

public class DecodeExample {

​ public static void main(String[] args) {

​ String encoded = "SGVsbG9KYXZh";

​ byte[] decodedBytes = Base64.getDecoder().decode(encoded);

​ String original = new String(decodedBytes);

System.out.println("Decoded: " + original);

​ }

🧾 Output:
Decoded: HelloJava

✅ Summary:
Operation Code

Encode Base64.getEncoder().encodeToString(byte
s)

Decode Base64.getDecoder().decode(string)
CodeWithSubhsam
■ Click here to access the resource

✅ What is forEach Method?


forEach is a default method introduced in Java 8 for iterating over collections (like List, Set,
etc.) in a simple way using lambda expressions.

✅ Syntax:
collection.forEach(element -> {

​ // your code using element

});

✅ Example with List


import java.util.*;

public class ForEachExample {

​ public static void main(String[] args) {

List<String> names = Arrays.asList("Amit", "Saurabh", "Ravi");

names.forEach(name -> System.out.println("Name: " + name));

​ }

🧾 Output:
Name: Amit

Name: Saurabh

Name: Ravi
CodeWithSubhsam
■ Click here to access the resource

ONLY FOR KNOWLEDGE

✅ What does Arrays.asList() do?


Arrays.asList() is a method in Java that converts an array into a fixed-size List.

🔷 Example:
List<String> names = Arrays.asList("Amit", "Saurabh", "Ravi");

Here:

●​ "Amit", "Saurabh", "Ravi" is a String array


●​ Arrays.asList(...) converts it into a List<String>

🧠 Key Points:
Feature Behavior

🔁 Fixed size You can't add or remove


elements

✅ Can change You can update existing values


elements

✅ What is Try-with-Resources in Java?


Try-with-resources is a feature in Java (since Java 7) that automatically closes resources
like files, sockets, streams, or DB connections — no need to close them manually.
CodeWithSubhsam
■ Click here to access the resource

🔷 Simple Definition:
Try-with-resources is used to auto-close any object that implements the AutoCloseable
interface.

✅ Syntax:
try (ResourceType resource = new ResourceType()) {

// use the resource

} catch (Exception e) {

System.out.println(e.getmessge);

✅ Example: Reading a File using Try-with-Resources


import java.io.*;

public class TryWithResourcesExample {

public static void main(String[] args) {

​ try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {

​ String line;

​ while ((line = br.readLine()) != null) {

​ System.out.println(line);

​ }

​ } catch (IOException e) {

​ e.printStackTrace();

​ }
CodeWithSubhsam
■ Click here to access the resource

🔍 What happens here?


●​ BufferedReader is a resource.
●​ It implements AutoCloseable.
●​ Java automatically closes it when try block finishes — even if an exception occurs.

✅ Benefits:
Feature Description

🧹 Auto-clean No need to write close() manually


❌ Less error No forgetting to close a resource
💡 Cleaner code Less boilerplate and safer
handling

🔸 What are Annotations in Java?


Annotations are metadata (information) added to Java code. They do not change the action
of the code but give instructions to the compiler, tools, or frameworks.
CodeWithSubhsam
■ Click here to access the resource

They start with @ and are used above classes, methods, variables, parameters, etc.

🔸 Uses of Annotations:
●​ Provide instructions to the compiler (e.g., @Override)
●​ Help in runtime processing (e.g., in frameworks like Spring, Hibernate)
●​ Used for code analysis or documentation
●​ Used for type checking (from Java 8)

🔸 Types of Annotations in Java


1. Built-in (Predefined) Annotations

Annotation Description

@Override Confirms that a method overrides a superclass method

@Deprecated Marks the method/class as outdated

@SuppressWarnings Tells the compiler to ignore warnings

@SafeVarargs Suppresses unsafe operation warnings for varargs

@FunctionalInterface Marks interface as a functional interface (one abstract


method)

2. Meta Annotations

These are used to define custom annotations.

Annotation Description
CodeWithSubhsam
■ Click here to access the resource

@Retention Defines how long the annotation is retained (SOURCE, CLASS,


RUNTIME)

@Target Specifies where the annotation can be used (method, field, etc.)

@Inherited Lets subclasses inherit the annotation

@Documente Makes annotation visible in Javadoc


d

3. Custom/User-Defined Annotations

You can create your own annotations using:

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

@interface MyAnnotation {

​ String value();

Then use it like:

@MyAnnotation("Hello")

public void show() {}

4. Type Annotations (Java 8+)

These annotations are used with types (variables, generics, casts).

@NonNull String name;

List<@NonNull String> names;


CodeWithSubhsam
■ Click here to access the resource

Repeating Annotations in Java


Repeating annotations are a feature introduced in Java 8 that allow you to apply the
same annotation type multiple times to the same declaration or type use.

Before Java 8

Prior to Java 8, you couldn't use the same annotation more than once on a single
element. To work around this limitation, you had to use container annotations:

@Schedules({

​ @Schedule(dayOfMonth="last"),

​ @Schedule(dayOfWeek="Fri", hour="23")

})

​ public void doPeriodicCleanup() { ... }

With Repeating Annotations

​ Java 8 introduced a cleaner way to do this:

✅ Steps in Simple Words:


1.​ Create a main annotation with @Repeatable.
2.​ Create a container annotation to hold multiple values.
3.​ Use it multiple times on the same class.

🔸 Example:
// Step 1: Create repeating annotation

@Repeatable(Hints.class)

@interface Hint {

​ String value();

// Step 2: Create container annotation


CodeWithSubhsam
■ Click here to access the resource

@interface Hints {

​ Hint[] value();

// Step 3: Use multiple annotations

@Hint("Java")

@Hint("Spring")

class Demo {}

📦Java Module System (JPMS - Java Platform


Module System)
The Java Module System, introduced in Java 9 (Jigsaw project), is a fundamental change to
how Java applications are structured and deployed. It provides better encapsulation, more
reliable configuration, and improved performance.

Benefits

1.​ Strong Encapsulation:


○​ Packages are no longer accessible by default
○​ Explicit exports required for public API
2.​ Reliable Configuration:
○​ Dependencies are declared and verified at startup
○​ Avoids classpath issues like "NoClassDefFoundError"
3.​ Improved Performance:
○​ The JVM can optimize module-aware code better
○​ Faster startup with module graph verification
4.​ Scalability:
○​ Enables building smaller runtime images (via jlink)
○​ Better support for large applications

✅ Basic Structure:
CodeWithSubhsam
■ Click here to access the resource

module mymodule {

​ requires java.sql; ​ // uses other module

​ exports com.example.util; // makes this package public

🔸 Example:
module-info.java

module calculator {

​ exports com.calc;

💠 What is Diamond Syntax (<>)?


Diamond Operator (<>) with Anonymous Inner Classes in Java

The diamond operator (<>), introduced in Java 7, allows for type inference(You didn't
write String in <>, but Java figured it out on its own — that's type inference.) when
instantiating generic classes. However, its behavior with anonymous inner classes has
some special considerations.

Basic Diamond Operator Usage

Before Java 7:

List<String> list = new ArrayList<String>();

With diamond operator (Java 7+):

List<String> list = new ArrayList<>(); // Type inferred from declaration

Lambda Expression (Java 8+ preferred solution)


CodeWithSubhsam
■ Click here to access the resource

Comparator<String> comp = (a, b) -> a.length() - b.length();

Why This Matters

· Reduces Verbosity: Eliminates redundant type specifications

· Maintains Type Safety: Still provides compile-time type checking

· Improves Readability: Cleaner code, especially with complex generic types

❌ Why Diamond Fails with Anonymous Classes?


🔸 Theory:
The diamond operator (<>) allows the compiler to infer generic types.​
But when we use an anonymous class, the compiler creates a new unnamed class.

➡️ In this case, type inference is not enough because:


●​ The anonymous class may override methods
●​ It may add new behavior
●​ Compiler needs exact type information

Thus, Java disallows the diamond operator <> with anonymous inner classes.

🔴 Example (Fails):
Comparator<String> comp = new Comparator<>() { // ❌ error
public int compare(String a, String b) {

​ return a.length() - b.length();

};
CodeWithSubhsam
■ Click here to access the resource

✅ Correct Code (without diamond):


Comparator<String> comp = new Comparator<String>() {

public int compare(String a, String b) {

​ return a.length() - b.length();

};

✅ Simple Summary:
Feature Works with Diamond <>?

Normal class ✅ Yes


Anonymous ❌ No
class

📌 What is Local Variable Type Inference?


Introduced in Java 10, the var keyword lets the compiler infer the type of a local variable from
the right-hand side.

✅ Syntax:
var name = "Saurabh"; ​ // inferred as String

var number = 10; ​ // inferred as int

var list = new ArrayList<String>(); // inferred as ArrayList<String>


CodeWithSubhsam
■ Click here to access the resource

You didn't write String, but Java figured it out on its own — that's type inference.

🧠 How does inference work?


●​ var tells Java: "you guess the type."
●​ Java looks at the value on the right-hand side (RHS) of =
●​ Based on that value, it infers the correct data type

📌 Rules:
Rule Explanation

var is not a keyword It's a reserved type name, not a keyword

Only for local variables Inside methods, loops, etc.

Must be initialized You must assign a value when


declaring

Cannot be used for Only inside methods, not class fields


fields

Improves readability When RHS makes the type obvious

❌ Invalid Examples:
var x; ​ //❌ Error: no initializer
var nullVar = null; // ❌ Error: cannot infer type from null

✅ Valid Examples:
CodeWithSubhsam
■ Click here to access the resource

var str = "Hello"; ​ // String

var count = 100; ​ // int

var list = List.of(1, 2, 3); // List<Integer>

⚠️ Caution:
Don't overuse var when the type is not obvious:

​ var data = get(); // ❌ unclear what 'data' is


z

🔄 What Are Switch Expressions?


Switch expressions were introduced as a preview feature in Java 12 and became standardized
in Java 14. They provide a more concise and less error-prone alternative to traditional switch
statements.

Key Features

1. Expression (not just statement): Returns a value

2. Arrow syntax (->): Cleaner than colon syntax

3. No fall-through: Eliminates accidental bugs

4. Multiple case labels: Combine cases easily

5. Exhaustiveness checking: For enums/sealed types

✅ Traditional switch (old style):

int day = 2;
CodeWithSubhsam
■ Click here to access the resource

switch (day) {

​ case 1:

​ System.out.println("Monday");

​ break;

​ case 2:

System.out.println("Tuesday");

​ break;

​ case 3:

System.out.println("Wednesday");

​ break;

​ case 4:

System.out.println("Thursday");

​ break;

​ case 5:

System.out.println("Friday");

​ break;

​ case 6:

System.out.println("Saturday");

​ break;

​ case 7:

System.out.println("Sunday");

​ break;

​ default:

System.out.println("Invalid Day");
CodeWithSubhsam
■ Click here to access the resource

✅ Using switch expression to print directly:


int day = 3;

switch (day) {

​ case 1 -> System.out.println("Monday");

​ case 2 -> System.out.println("Tuesday");

​ case 3 -> System.out.println("Wednesday");

​ case 4 -> System.out.println("Thursday");

​ case 5 -> System.out.println("Friday");

​ case 6 -> System.out.println("Saturday");

​ case 7 -> System.out.println("Sunday");

​ default -> System.out.println("Invalid Day");

🔹 Benefits of Switch Expressions:


Feature Benefit

Arrow (->) syntax Clear & short

Returns value No need for separate result


assignment

No fall-through Avoids bugs (no need for break)

Multi-label support Combine multiple cases easily


CodeWithSubhsam
■ Click here to access the resource

yield keyword Return value from block case

📌 Summary:
Feature Old Switch New Switch
Expression

Syntax case: + case ->


break

Return ❌ No ✅ Yes
value

Fall-through✅ Yes ❌ No
Multi-label ❌ No ✅ Yes
yield usage ❌ No ✅ Yes (inside block)

🔑 What is yield in Java?


The yield keyword is used inside switch expressions (Java 14+) to return a value from a
case block when using {} braces.

🧠 Why is yield needed?


When a case uses a code block {} (to perform multiple statements), you must use yield to
return a value from that block.
CodeWithSubhsam
■ Click here to access the resource

✅ Example with yield:


int marks = 80;

String grade = switch (marks / 10) {

​ case 10, 9 -> "A";

​ case 8 -> {

System.out.println("Good job");

​ yield "B";

​ }

​ case 7 -> "C";

​ default -> "Fail";

};

System.out.println("Grade: " + grade);

🟡 Here, the case 8 block prints a message and then yields "B" as the return value of the
switch.

⚠️ Without yield → Compile Error:


case 8 -> {

System.out.println("Good job");

​ return "B"; // ❌ Error: 'return' not allowed here


}

📌 Summary Table
CodeWithSubhsam
■ Click here to access the resource

Feature Value

Introduced in Java 14

Used in switch expressions with block {}

Replaces return inside switch expressions

Must be followed by A value (e.g. yield "Passed";)

🧾 What are Text Blocks?


Text Blocks in Java

Text blocks, introduced in Java 13 (as a preview feature) and finalized in Java 15, provide a
cleaner way to work with multi-line strings in Java code. They help eliminate the need for most
escape sequences and offer better readability for strings spanning multiple lines.

Basic Syntax

Text blocks are delimited by triple quotes ("""):

String html = """

<html>

<body>

<p>Hello, World!</p>

</body>

</html>

​ """;

Key Features
CodeWithSubhsam
■ Click here to access the resource

1.​ Automatic Line Termination:


○​ Each new line in the source becomes a \n in the string
○​ No need for explicit \n characters
2.​ Incidental White Space Handling:
○​ Leading white space is automatically removed based on the closing delimiter
position
○​ Relative indentation within the block is preserved
3.​ Escape Sequence Reduction:
○​ Most quotes don't need escaping
○​ New lines don't require \n

🔹 Why Use Text Blocks?


Problem with Old Way Solved by Text Blocks

Need to write \n for new lines Auto handles line breaks

Need to use \" for quotes No escape needed in most


cases

Messy formatting Keeps source code readable

✅ Traditional vs Text Block


Old way (messy):

String json = "{\n" +

​ " \"name\": \"Saurabh\",\n" +

​ " \"age\": 22\n" +

​ "}";

Using Text Block (clean):

String json = """

​ {
CodeWithSubhsam
■ Click here to access the resource

"name": "Saurabh",

"age": 22

​ }

""";

📌 Key Points:
Feature Support

Triple quotes """

Multi-line ✅ Yes
Auto line breaks ✅ Yes
Tabs/spaces Preserved

Escaping needed? Rarely (only for """)

📋 What are Records in Java?


Records, introduced in Java 14 as a preview feature and finalized in Java 16, are a new kind of
class type that provides a concise way to model immutable data carriers. They are designed to
reduce boilerplate code for simple data-holding classes.

They are like compact classes that:

●​ Automatically create constructor, getters, toString(), equals(), and hashCode().


●​ Are immutable by default (values can't be changed).

✅ Syntax:
CodeWithSubhsam
■ Click here to access the resource

​ record Person(String name, int age) {}

✅ Auto-Generated Getters in Records


​ For a record like:

record Person(String name, int age) {}

Java automatically creates these getter methods:

String name()​ // acts like getName()

int age() ​ // acts like getAge()

So you can use:

Person p = new Person("Saurabh", 22);

System.out.println(p.name()); // "Saurabh"

System.out.println(p.age()); // 22

🔐 Key Features of Records


Feature Value

Immutable fields ✅ Yes (all fields are final)


Constructor ✅ Auto-generated
Getters ✅ Yes (name(), age())
toString(), equals() ✅ Yes
Can’t extend class ✅ Yes (records are final)
CodeWithSubhsam
■ Click here to access the resource

Can implement ✅ Yes


interfaces

❌ What Records Can’t Do:


●​ Can’t extend other classes (because they are final)
●​ Can’t define setters (immutable)
●​ Fields are always private final

🔐 What are Sealed Classes?


Sealed classes, introduced as a preview feature in Java 15 and finalized in Java 17, provide a
mechanism to control which classes can extend or implement a given class or interface. This
powerful feature enables more precise modeling of domain hierarchies while maintaining type
safety.

✅ Syntax:
public sealed class Vehicle

​ permits Car, Bike {

​ // common code

Here, only Car and Bike can extend Vehicle. No one else is allowed.

🔑 Rules for Subclasses:


Every class that extends a sealed class must use one of:

Keyword Meaning
CodeWithSubhsam
■ Click here to access the resource

final Cannot be extended


further

sealed Can restrict further children

non-seale Open for any subclassing


d

✅ Example:
public sealed class Vehicle permits Car, Bike {}

final class Car extends Vehicle {} ​ // No more subclassing because of final class

non-sealed class Bike extends Vehicle {} // Anyone can extend Bike

📌 Why Use Sealed Classes?


Benefit Description

Security Only allowed subclasses can be


used

Exhaustiveness Useful in switch (pattern matching)

Better design No one can misuse your base class


control

❌ If You Break the Rules:


class Truck extends Vehicle {} // ❌ Error: Not permitted because in side vehicle truck not
define

You must declare permitted classes in permits, and the subclass must follow the rule.
CodeWithSubhsam
■ Click here to access the resource

​ PLZ FOLLOW MY CHANNEL CodeWithSubhsam Thanks

📲 Join our WhatsApp Group – Click Here


✅ One Shot Video​
✅ PYQ​
✅ Most Weightage Topic
​ ​ ​ ​

You might also like