Introduction
Imagine you're at a zoo with different animal enclosures. You see an animal and wonder: "Is that a lion? Is it a bird? Can it fly?" The instanceof operator in Java is like asking these questions - it helps you determine what type of object you're dealing with at runtime!
The instanceof operator is used to test whether an object is an instance of a specific class, subclass, or interface. It's essential for type checking, safe casting, and polymorphic behavior.
What is the instanceof Operator?
The instanceof operator is a binary operator that returns true if the object on the left is an instance of the type on the right, otherwise it returns false.
Basic Syntax:
object instanceof Type
Returns:
trueif object is an instance of the specified typefalseif object is not an instance, or isnull
Code Explanation with Examples
Example 1: Basic instanceof Usage
// π― BASE CLASS AND SUBCLASSES
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println(name + " is eating...");
}
}
class Mammal extends Animal {
public Mammal(String name) {
super(name);
}
public void giveBirth() {
System.out.println(name + " is giving birth to live young");
}
}
class Bird extends Animal {
public Bird(String name) {
super(name);
}
public void fly() {
System.out.println(name + " is flying! ποΈ");
}
}
class Fish extends Animal {
public Fish(String name) {
super(name);
}
public void swim() {
System.out.println(name + " is swimming! π ");
}
}
// π― INTERFACES
interface Flyable {
void fly();
}
interface Swimmable {
void swim();
}
class Duck extends Bird implements Flyable, Swimmable {
public Duck(String name) {
super(name);
}
@Override
public void fly() {
System.out.println(name + " the duck is flying gracefully");
}
@Override
public void swim() {
System.out.println(name + " the duck is paddling in water");
}
public void quack() {
System.out.println(name + " says: Quack! Quack!");
}
}
public class BasicInstanceOf {
public static void main(String[] args) {
System.out.println("=== BASIC instanceof OPERATOR DEMONSTRATION ===");
// π― CREATING DIFFERENT ANIMALS
Animal lion = new Mammal("Simba");
Animal eagle = new Bird("Eddie");
Animal salmon = new Fish("Sammy");
Animal donald = new Duck("Donald");
// π― BASIC instanceof CHECKS
System.out.println("\n1. BASIC instanceof CHECKS:");
System.out.println("lion instanceof Animal: " + (lion instanceof Animal));
System.out.println("lion instanceof Mammal: " + (lion instanceof Mammal));
System.out.println("lion instanceof Bird: " + (lion instanceof Bird));
System.out.println("eagle instanceof Animal: " + (eagle instanceof Animal));
System.out.println("eagle instanceof Bird: " + (eagle instanceof Bird));
System.out.println("eagle instanceof Mammal: " + (eagle instanceof Mammal));
// π― instanceof WITH INTERFACES
System.out.println("\n2. instanceof WITH INTERFACES:");
System.out.println("donald instanceof Flyable: " + (donald instanceof Flyable));
System.out.println("donald instanceof Swimmable: " + (donald instanceof Swimmable));
System.out.println("eagle instanceof Flyable: " + (eagle instanceof Flyable)); // false - Bird doesn't implement Flyable
System.out.println("salmon instanceof Swimmable: " + (salmon instanceof Swimmable)); // false - Fish doesn't implement Swimmable
// π― NULL CHECKS WITH instanceof
System.out.println("\n3. NULL CHECKS WITH instanceof:");
Animal nullAnimal = null;
System.out.println("nullAnimal instanceof Animal: " + (nullAnimal instanceof Animal));
System.out.println("null instanceof Object: " + (null instanceof Object));
// π― INHERITANCE CHAIN CHECKS
System.out.println("\n4. INHERITANCE CHAIN CHECKS:");
System.out.println("donald instanceof Animal: " + (donald instanceof Animal));
System.out.println("donald instanceof Bird: " + (donald instanceof Bird));
System.out.println("donald instanceof Duck: " + (donald instanceof Duck));
System.out.println("donald instanceof Object: " + (donald instanceof Object));
// π― ARRAY OF ANIMALS - POLYMORPHIC PROCESSING
System.out.println("\n5. POLYMORPHIC PROCESSING WITH instanceof:");
Animal[] animals = {lion, eagle, salmon, donald};
for (Animal animal : animals) {
System.out.println("\n--- Processing " + animal.name + " ---");
animal.eat();
// π― TYPE CHECKING AND SAFE CASTING
if (animal instanceof Mammal) {
Mammal mammal = (Mammal) animal; // Safe cast
mammal.giveBirth();
}
if (animal instanceof Bird) {
Bird bird = (Bird) animal; // Safe cast
bird.fly();
}
if (animal instanceof Fish) {
Fish fish = (Fish) animal; // Safe cast
fish.swim();
}
if (animal instanceof Duck) {
Duck duck = (Duck) animal; // Safe cast
duck.quack();
duck.swim(); // Duck-specific method
}
// π― INTERFACE CHECKS
if (animal instanceof Flyable) {
Flyable flyable = (Flyable) animal;
flyable.fly();
}
if (animal instanceof Swimmable) {
Swimmable swimmable = (Swimmable) animal;
swimmable.swim();
}
}
// π― BENEFITS OF instanceof
System.out.println("\n6. BENEFITS OF instanceof OPERATOR:");
System.out.println("β
Runtime Type Checking: Determine actual type at runtime");
System.out.println("β
Safe Casting: Avoid ClassCastException");
System.out.println("β
Polymorphic Behavior: Different actions based on type");
System.out.println("β
Interface Implementation Checks: Verify capability");
}
}
Output:
=== BASIC instanceof OPERATOR DEMONSTRATION === 1. BASIC instanceof CHECKS: lion instanceof Animal: true lion instanceof Mammal: true lion instanceof Bird: false eagle instanceof Animal: true eagle instanceof Bird: true eagle instanceof Mammal: false 2. instanceof WITH INTERFACES: donald instanceof Flyable: true donald instanceof Swimmable: true eagle instanceof Flyable: false salmon instanceof Swimmable: false 3. NULL CHECKS WITH instanceof: nullAnimal instanceof Animal: false null instanceof Object: false 4. INHERITANCE CHAIN CHECKS: donald instanceof Animal: true donald instanceof Bird: true donald instanceof Duck: true donald instanceof Object: true 5. POLYMORPHIC PROCESSING WITH instanceof: --- Processing Simba --- Simba is eating... Simba is giving birth to live young --- Processing Eddie --- Eddie is eating... Eddie is flying! ποΈ --- Processing Sammy --- Sammy is eating... Sammy is swimming! π --- Processing Donald --- Donald is eating... Donald the duck is flying gracefully Donald the duck is paddling in water Donald says: Quack! Quack! Donald the duck is flying gracefully Donald the duck is paddling in water 6. BENEFITS OF instanceof OPERATOR: β Runtime Type Checking: Determine actual type at runtime β Safe Casting: Avoid ClassCastException β Polymorphic Behavior: Different actions based on type β Interface Implementation Checks: Verify capability
Example 2: Real-World Payment System
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
// π― PAYMENT INTERFACE
interface Payment {
void processPayment(double amount);
String getPaymentId();
boolean isSuccessful();
LocalDateTime getTimestamp();
}
// π― CREDIT CARD PAYMENT
class CreditCardPayment implements Payment {
private String paymentId;
private String cardNumber;
private String cardHolder;
private boolean successful;
private LocalDateTime timestamp;
public CreditCardPayment(String cardNumber, String cardHolder) {
this.paymentId = "CC-" + System.currentTimeMillis();
this.cardNumber = maskCardNumber(cardNumber);
this.cardHolder = cardHolder;
this.timestamp = LocalDateTime.now();
}
private String maskCardNumber(String cardNumber) {
return "****-****-****-" + cardNumber.substring(cardNumber.length() - 4);
}
@Override
public void processPayment(double amount) {
System.out.println("π³ Processing credit card payment of $" + amount);
System.out.println(" Card: " + cardNumber);
System.out.println(" Holder: " + cardHolder);
// Simulate processing
this.successful = Math.random() > 0.1; // 90% success rate
if (successful) {
System.out.println(" β
Payment successful!");
} else {
System.out.println(" β Payment declined!");
}
}
@Override
public String getPaymentId() { return paymentId; }
@Override
public boolean isSuccessful() { return successful; }
@Override
public LocalDateTime getTimestamp() { return timestamp; }
// π― CREDIT CARD SPECIFIC METHOD
public void refundToCard() {
System.out.println("π³ Refunding to credit card: " + cardNumber);
}
}
// π― PAYPAL PAYMENT
class PayPalPayment implements Payment {
private String paymentId;
private String email;
private boolean successful;
private LocalDateTime timestamp;
public PayPalPayment(String email) {
this.paymentId = "PP-" + System.currentTimeMillis();
this.email = email;
this.timestamp = LocalDateTime.now();
}
@Override
public void processPayment(double amount) {
System.out.println("π§ Processing PayPal payment of $" + amount);
System.out.println(" Email: " + email);
// Simulate processing
this.successful = Math.random() > 0.05; // 95% success rate
if (successful) {
System.out.println(" β
Payment successful!");
} else {
System.out.println(" β Payment failed!");
}
}
@Override
public String getPaymentId() { return paymentId; }
@Override
public boolean isSuccessful() { return successful; }
@Override
public LocalDateTime getTimestamp() { return timestamp; }
// π― PAYPAL SPECIFIC METHOD
public void sendPaymentConfirmation() {
System.out.println("π§ Sending confirmation email to: " + email);
}
}
// π― CRYPTOCURRENCY PAYMENT
class CryptoPayment implements Payment {
private String paymentId;
private String walletAddress;
private String cryptocurrency;
private boolean successful;
private LocalDateTime timestamp;
public CryptoPayment(String walletAddress, String cryptocurrency) {
this.paymentId = "CRYPTO-" + System.currentTimeMillis();
this.walletAddress = maskWalletAddress(walletAddress);
this.cryptocurrency = cryptocurrency;
this.timestamp = LocalDateTime.now();
}
private String maskWalletAddress(String address) {
return address.substring(0, 8) + "..." + address.substring(address.length() - 8);
}
@Override
public void processPayment(double amount) {
System.out.println("βΏ Processing " + cryptocurrency + " payment of $" + amount);
System.out.println(" Wallet: " + walletAddress);
// Simulate processing
this.successful = Math.random() > 0.2; // 80% success rate
if (successful) {
System.out.println(" β
Payment confirmed on blockchain!");
} else {
System.out.println(" β Transaction failed!");
}
}
@Override
public String getPaymentId() { return paymentId; }
@Override
public boolean isSuccessful() { return successful; }
@Override
public LocalDateTime getTimestamp() { return timestamp; }
// π― CRYPTO SPECIFIC METHOD
public void confirmBlockchainTransaction() {
System.out.println("βΏ Confirming transaction on " + cryptocurrency + " blockchain...");
}
}
// π― BANK TRANSFER PAYMENT
class BankTransferPayment implements Payment {
private String paymentId;
private String accountNumber;
private String bankName;
private boolean successful;
private LocalDateTime timestamp;
public BankTransferPayment(String accountNumber, String bankName) {
this.paymentId = "BANK-" + System.currentTimeMillis();
this.accountNumber = maskAccountNumber(accountNumber);
this.bankName = bankName;
this.timestamp = LocalDateTime.now();
}
private String maskAccountNumber(String accountNumber) {
return "***" + accountNumber.substring(accountNumber.length() - 4);
}
@Override
public void processPayment(double amount) {
System.out.println("π¦ Processing bank transfer of $" + amount);
System.out.println(" Bank: " + bankName);
System.out.println(" Account: " + accountNumber);
// Simulate processing
this.successful = Math.random() > 0.02; // 98% success rate
if (successful) {
System.out.println(" β
Transfer initiated!");
} else {
System.out.println(" β Transfer failed!");
}
}
@Override
public String getPaymentId() { return paymentId; }
@Override
public boolean isSuccessful() { return successful; }
@Override
public LocalDateTime getTimestamp() { return timestamp; }
// π― BANK TRANSFER SPECIFIC METHOD
public void generateBankStatement() {
System.out.println("π¦ Generating bank statement for account: " + accountNumber);
}
}
// π― PAYMENT PROCESSOR
class PaymentProcessor {
private List<Payment> paymentHistory;
public PaymentProcessor() {
this.paymentHistory = new ArrayList<>();
}
public void processPayment(Payment payment, double amount) {
System.out.println("\n" + "=".repeat(50));
System.out.println("π PROCESSING PAYMENT: " + payment.getPaymentId());
payment.processPayment(amount);
paymentHistory.add(payment);
// π― POST-PROCESSING BASED ON PAYMENT TYPE
handlePostProcessing(payment);
System.out.println("=".repeat(50));
}
// π― USING instanceof FOR TYPE-SPECIFIC PROCESSING
private void handlePostProcessing(Payment payment) {
System.out.println("\nπ POST-PROCESSING:");
if (payment instanceof CreditCardPayment) {
CreditCardPayment ccPayment = (CreditCardPayment) payment;
if (ccPayment.isSuccessful()) {
System.out.println(" π³ Credit card payment completed");
} else {
System.out.println(" π³ Credit card payment failed - notifying card holder");
}
}
else if (payment instanceof PayPalPayment) {
PayPalPayment ppPayment = (PayPalPayment) payment;
if (ppPayment.isSuccessful()) {
ppPayment.sendPaymentConfirmation();
} else {
System.out.println(" π§ PayPal payment failed - check email for details");
}
}
else if (payment instanceof CryptoPayment) {
CryptoPayment cryptoPayment = (CryptoPayment) payment;
if (cryptoPayment.isSuccessful()) {
cryptoPayment.confirmBlockchainTransaction();
System.out.println(" βΏ Crypto payment confirmed - irreversible");
} else {
System.out.println(" βΏ Crypto transaction failed - may take time to refund");
}
}
else if (payment instanceof BankTransferPayment) {
BankTransferPayment bankPayment = (BankTransferPayment) payment;
if (bankPayment.isSuccessful()) {
bankPayment.generateBankStatement();
System.out.println(" π¦ Bank transfer initiated - may take 1-3 business days");
} else {
System.out.println(" π¦ Bank transfer failed - insufficient funds or invalid account");
}
}
else {
System.out.println(" βΉοΈ Unknown payment type");
}
}
public void generatePaymentReport() {
System.out.println("\nπ PAYMENT PROCESSING REPORT");
System.out.println("=".repeat(40));
int total = paymentHistory.size();
int successful = 0;
// π― COUNT BY PAYMENT TYPE USING instanceof
int creditCardCount = 0;
int paypalCount = 0;
int cryptoCount = 0;
int bankCount = 0;
for (Payment payment : paymentHistory) {
if (payment.isSuccessful()) {
successful++;
}
if (payment instanceof CreditCardPayment) {
creditCardCount++;
} else if (payment instanceof PayPalPayment) {
paypalCount++;
} else if (payment instanceof CryptoPayment) {
cryptoCount++;
} else if (payment instanceof BankTransferPayment) {
bankCount++;
}
}
System.out.println("Total Payments: " + total);
System.out.println("Successful: " + successful);
System.out.println("Failed: " + (total - successful));
System.out.println("Success Rate: " + (total > 0 ? (successful * 100 / total) : 0) + "%");
System.out.println("\n--- Breakdown by Payment Method ---");
System.out.println("Credit Cards: " + creditCardCount);
System.out.println("PayPal: " + paypalCount);
System.out.println("Cryptocurrency: " + cryptoCount);
System.out.println("Bank Transfer: " + bankCount);
}
public void refundPayment(Payment payment) {
System.out.println("\nπ PROCESSING REFUND: " + payment.getPaymentId());
if (!payment.isSuccessful()) {
System.out.println("β Cannot refund failed payment");
return;
}
// π― TYPE-SPECIFIC REFUND PROCESSING
if (payment instanceof CreditCardPayment) {
CreditCardPayment ccPayment = (CreditCardPayment) payment;
ccPayment.refundToCard();
System.out.println("π³ Refund processed to credit card");
}
else if (payment instanceof PayPalPayment) {
PayPalPayment ppPayment = (PayPalPayment) payment;
ppPayment.sendPaymentConfirmation();
System.out.println("π§ Refund processed via PayPal");
}
else if (payment instanceof CryptoPayment) {
System.out.println("βΏ Crypto refunds require manual processing");
System.out.println(" Contact support for assistance");
}
else if (payment instanceof BankTransferPayment) {
System.out.println("π¦ Bank transfer refund initiated");
System.out.println(" Will be processed in 3-5 business days");
}
else {
System.out.println("β Unknown payment type - cannot process refund");
}
}
}
public class PaymentSystemDemo {
public static void main(String[] args) {
System.out.println("=== REAL-WORLD PAYMENT SYSTEM WITH instanceof ===");
// π― CREATE PAYMENT PROCESSOR
PaymentProcessor processor = new PaymentProcessor();
// π― CREATE DIFFERENT PAYMENT METHODS
CreditCardPayment creditCard = new CreditCardPayment("1234567812345678", "John Doe");
PayPalPayment paypal = new PayPalPayment("[email protected]");
CryptoPayment crypto = new CryptoPayment("1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", "Bitcoin");
BankTransferPayment bankTransfer = new BankTransferPayment("1234567890", "City Bank");
// π― PROCESS PAYMENTS
System.out.println("\n1. PROCESSING PAYMENTS:");
processor.processPayment(creditCard, 150.0);
processor.processPayment(paypal, 75.50);
processor.processPayment(crypto, 200.0);
processor.processPayment(bankTransfer, 500.0);
// π― GENERATE REPORT
processor.generatePaymentReport();
// π― DEMONSTRATE REFUNDS
System.out.println("\n2. REFUND DEMONSTRATION:");
Payment[] payments = {creditCard, paypal, crypto, bankTransfer};
for (Payment payment : payments) {
if (payment.isSuccessful()) {
processor.refundPayment(payment);
System.out.println("---");
}
}
// π― ADVANCED instanceof USAGE
System.out.println("\n3. ADVANCED instanceof PATTERNS:");
// π― CHECKING MULTIPLE TYPES
Object[] objects = {
creditCard,
paypal,
crypto,
bankTransfer,
"This is a string",
42,
new ArrayList<>()
};
for (Object obj : objects) {
System.out.print("\n" + obj.getClass().getSimpleName() + ": ");
if (obj instanceof Payment) {
Payment p = (Payment) obj;
System.out.print("Payment ID: " + p.getPaymentId());
// π― COMBINED CHECKS
if (obj instanceof CreditCardPayment && p.isSuccessful()) {
System.out.print(" (Successful Credit Card)");
}
} else if (obj instanceof String) {
System.out.print("String: " + obj);
} else if (obj instanceof Integer) {
System.out.print("Integer: " + obj);
} else if (obj instanceof List) {
System.out.print("List with " + ((List<?>) obj).size() + " elements");
} else {
System.out.print("Unknown type");
}
}
System.out.println("\n\n4. BENEFITS IN PAYMENT SYSTEMS:");
System.out.println("β
Type-Specific Processing: Different logic for each payment method");
System.out.println("β
Safe Casting: Avoid ClassCastException in financial operations");
System.out.println("β
Flexible Extensibility: Easy to add new payment methods");
System.out.println("β
Runtime Decisions: Process based on actual payment type");
System.out.println("β
Error Handling: Specific error messages for each type");
}
}
Output:
=== REAL-WORLD PAYMENT SYSTEM WITH instanceof === 1. PROCESSING PAYMENTS: ================================================== π PROCESSING PAYMENT: CC-1701234567890 π³ Processing credit card payment of $150.0 Card: ****-****-****-5678 Holder: John Doe β Payment successful! π POST-PROCESSING: π³ Credit card payment completed ================================================== ================================================== π PROCESSING PAYMENT: PP-1701234567891 π§ Processing PayPal payment of $75.5 Email: [email protected] β Payment successful! π POST-PROCESSING: π§ Sending confirmation email to: [email protected] ================================================== ================================================== π PROCESSING PAYMENT: CRYPTO-1701234567892 βΏ Processing Bitcoin payment of $200.0 Wallet: 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa β Payment confirmed on blockchain! π POST-PROCESSING: βΏ Confirming transaction on Bitcoin blockchain... βΏ Crypto payment confirmed - irreversible ================================================== ================================================== π PROCESSING PAYMENT: BANK-1701234567893 π¦ Processing bank transfer of $500.0 Bank: City Bank Account: ***7890 β Transfer initiated! π POST-PROCESSING: π¦ Generating bank statement for account: ***7890 π¦ Bank transfer initiated - may take 1-3 business days ================================================== π PAYMENT PROCESSING REPORT ======================================== Total Payments: 4 Successful: 4 Failed: 0 Success Rate: 100% --- Breakdown by Payment Method --- Credit Cards: 1 PayPal: 1 Cryptocurrency: 1 Bank Transfer: 1 2. REFUND DEMONSTRATION: π PROCESSING REFUND: CC-1701234567890 π³ Refunding to credit card: ****-****-****-5678 π³ Refund processed to credit card --- π PROCESSING REFUND: PP-1701234567891 π§ Sending confirmation email to: [email protected] π§ Refund processed via PayPal --- π PROCESSING REFUND: CRYPTO-1701234567892 βΏ Crypto refunds require manual processing Contact support for assistance --- π PROCESSING REFUND: BANK-1701234567893 π¦ Bank transfer refund initiated Will be processed in 3-5 business days --- 3. ADVANCED instanceof PATTERNS: CreditCardPayment: Payment ID: CC-1701234567890 (Successful Credit Card) PayPalPayment: Payment ID: PP-1701234567891 CryptoPayment: Payment ID: CRYPTO-1701234567892 BankTransferPayment: Payment ID: BANK-1701234567893 String: String: This is a string Integer: Integer: 42 ArrayList: List with 0 elements 4. BENEFITS IN PAYMENT SYSTEMS: β Type-Specific Processing: Different logic for each payment method β Safe Casting: Avoid ClassCastException in financial operations β Flexible Extensibility: Easy to add new payment methods β Runtime Decisions: Process based on actual payment type β Error Handling: Specific error messages for each type
Example 3: Advanced Patterns and Java 14+ Features
```java
import java.util.*;
// π― SHAPE HIERARCHY
interface Shape {
double area();
double perimeter();
String getName();
}
class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
@Override
public double perimeter() {
return 2 * Math.PI * radius;
}
@Override
public String getName() {
return "Circle";
}
public double getRadius() {
return radius;
}
}
class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double area() {
return width * height;
}
@Override
public double perimeter() {
return 2 * (width + height);
}
@Override
public String getName() {
return "Rectangle";
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
public boolean isSquare() {
return width == height;
}
}
class Triangle implements Shape {
private double side1;
private double side2;
private double side3;
public Triangle(double side1, double side2, double side3) {
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
}
@Override
public double area() {
// Heron's formula
double s = perimeter() / 2;
return Math.sqrt(s * (s - side1) * (s - side2) * (s - side3));
}
@Override
public double perimeter() {
return side1 + side2 + side3;
}
@Override
public String getName() {
return "Triangle";
}
public boolean isEquilateral() {
return side1 == side2 && side2 == side3;
}
public boolean isRightAngled() {
double[] sides = {side1, side2, side3};
Arrays.sort(sides);
return Math.abs((sides[0] * sides[0] + sides[1] * sides[1]) - (sides[2] * sides[2])) < 0.0001;
}
}
// π― 3D SHAPES
interface ThreeDimensional {
double volume();
double surfaceArea();
}
class Sphere extends Circle implements ThreeDimensional {
public Sphere(double radius) {
super(radius);
}
@Override
public double volume() {
return (4.0 / 3.0) * Math.PI * Math.pow(getRadius(), 3);
}
@Override
public double surfaceArea() {
return 4 * Math.PI * Math.pow(getRadius(), 2);
}
@Override
public String getName() {
return "Sphere";
}
}
class Cube extends Rectangle implements ThreeDimensional {
public Cube(double side) {
super(side, side);
}
@Override
public double volume() {
return Math.pow(getWidth(), 3);
}
@Override
public double surfaceArea() {
return 6 * Math.pow(getWidth(), 2);
}
@Override
public String getName() {
return "Cube";
}
@Override
public double area() {
return surfaceArea(); // For 3D shapes, area means surface area
}
@Override
public double perimeter() {
return 12 * getWidth(); // Sum of all edges
}
}
public class AdvancedInstanceOfPatterns {
public static void main(String[] args) {
System.out.println("=== ADVANCED instanceof PATTERNS ===");
// π― CREATE SHAPES
List<Object> shapes = Arrays.asList(
new Circle(5.0),
new Rectangle(4.0, 6.0),
new Triangle(3.0, 4.0, 5.0),
new Sphere(3.0),
new Cube(4.0),
"This is a string",
42,
new ArrayList<String>()
);
// π― TRADITIONAL instanceof WITH CASTING
System.out.println("\n1. TRADITIONAL instanceof PATTERN:");
for (Object obj : shapes) {
if (obj instanceof Shape) {
Shape shape = (Shape) obj;
System.out.printf("%s: Area=%.2f, Perimeter=%.2f%n",
shape.getName(), shape.area(), shape.perimeter());
// π― ADDITIONAL TYPE-SPECIFIC CHECKS
if (obj instanceof Circle && !(obj instanceof Sphere)) {
Circle circle = (Circle) obj;
System.out.println(" β³ Radius: " + circle.getRadius());
}
else if (obj instanceof Rectangle && !(obj instanceof Cube)) {
Rectangle rect = (Rectangle) obj;
System.out.println(" β³ " + (rect.isSquare() ? "Square" : "Rectangle") +
" " + rect.getWidth() + "x" + rect.getHeight());
}
else if (obj instanceof Triangle) {
Triangle triangle = (Triangle) obj;
System.out.println(" β³ " +
(triangle.isEquilateral() ? "Equilateral" :
triangle.isRightAngled() ? "Right-angled" : "Scalene") + " triangle");
}
}
}
// π― JAVA 14+ PATTERN MATCHING FOR instanceof
System.out.println("\n2. JAVA 14+ PATTERN MATCHING (SIMULATED):");
for (Object obj : shapes) {
// π― PATTERN: obj instanceof Type variable
if (obj instanceof Shape shape) {
System.out.printf("π %s: Area=%.2f%n", shape.getName(), shape.area());
// π― NESTED PATTERN MATCHING
if (shape instanceof Circle circle && !(shape instanceof Sphere)) {
System.out.println(" β Circle with radius: " + circle.getRadius());
} else if (shape instanceof Rectangle rect && !(shape instanceof Cube)) {
System.out.println(" β Rectangle " + rect.getWidth() + "x" + rect.getHeight());
} else if (shape instanceof Triangle triangle) {
System.out.println(" β³ Triangle with sides: " + triangle.perimeter());
}
}
}
// π― 3D SHAPES PROCESSING
System.out.println("\n3. 3D SHAPES PROCESSING:");
for (Object obj : shapes) {
if (obj instanceof ThreeDimensional threeD) {
System.out.printf("π§ %s: Volume=%.2f, Surface Area=%.2f%n",
((Shape) obj).getName(), threeD.volume(), threeD.surfaceArea());
}
}
// π― COMBINED CHECKS
System.out.println("\n4. COMBINED TYPE CHECKS:");
for (Object obj : shapes) {
System.out.print(obj.getClass().getSimpleName() + ": ");
if (obj instanceof Shape && obj instanceof ThreeDimensional) {
System.out.print("3D Shape");
} else if (obj instanceof Shape) {
System.out.print("2D Shape");
} else if (obj instanceof String) {
System.out.print("String");
} else if (obj instanceof Number) {
System.out.print("Number");
} else if (obj instanceof Collection) {
System.out.print("Collection");
} else {
System.out.print("Unknown");
}
System.out.println();
}
// π― NULL SAFETY WITH instanceof
System.out.println("\n5. NULL SAFETY:");
Object nullObj = null;
Object stringObj = "Hello";
Object numberObj = 123;
System.out.println("nullObj instanceof String: " + (nullObj instanceof String));
System.out.println("stringObj instanceof String: " + (stringObj instanceof String));
System.out.println("numberObj instanceof Number: " + (numberObj instanceof Number));
System.out.println("numberObj instanceof Integer: " + (numberObj instanceof Integer));
// π― COMPLEX CONDITIONS
System.out.println("\n6. COMPLEX instanceof CONDITIONS:");
for (Object obj : shapes) {
boolean isShape = obj instanceof Shape;
boolean is3D = obj instanceof ThreeDimensional;
boolean isCircleFamily = obj instanceof Circle;
boolean isRectangleFamily = obj instanceof Rectangle;
if (isShape) {
String type = "2D Shape";
if (is3D) type = "3D Shape";
if (isCircleFamily) type += " (Circle Family)";
if (isRectangleFamily) type += " (Rectangle Family)";
System.out.println(((Shape) obj).getName() + " β " + type);
}
}
// π― PERFORMANCE CONSIDERATIONS
System.out.println("\n7. instanceof PERFORMANCE TIPS:");
System.out.println("β
Check most specific type first");
System.out.println("β
Use else-if for mutually exclusive types");
System.out.println("β
Consider polymorphism over instanceof when possible");
System.out.println("β
Use pattern matching (Java 14+) for cleaner code");
// π― ALTERNATIVES TO instanceof
System.out.println("\n8. ALTERNATIVES TO instanceof:");
System.out.println("πΉ Polymorphism: Override methods in subclasses");
System.out.println("πΉ Visitor Pattern: Separate algorithm from object structure");
System.out.println("πΉ Strategy Pattern: Different behaviors via composition");
System.out.println("πΉ Factory Pattern: Type-specific object creation");
}
// π― UTILITY METHOD DEMONSTRATING instanceof BEST PRACTICES
public static void processShape(Shape shape) {
// π― MOST SPECIFIC CHECKS FIRST
if (shape instanceof Sphere sphere) {
System.out.println("Processing Sphere with volume: " + sphere.volume());
} else if (shape instanceof Cube cube) {
System.out.println("Processing Cube with volume: " + cube.volume());
} else if (shape instanceof Circle circle) {
System.out.println("Processing Circle with radius: " + circle.getRadius());
} else if (shape instanceof Rectangle rectangle) {
System.out.println("Processing Rectangle: " + rectangle.getWidth() + "x" + rectangle