'Why is pattern matching ok in scala but using instanceof is a sign of bad code in Java

There is an aspect of the pattern matching I don't understand.

In the documentation of the pattern matching they show an example such as :

https://docs.scala-lang.org/tour/pattern-matching.html

abstract class Notification

case class Email(sender: String, title: String, body: String) extends Notification

case class SMS(caller: String, message: String) extends Notification

case class VoiceRecording(contactName: String, link: String) extends Notification

def showNotification(notification: Notification): String = {
  notification match {
    case Email(sender, title, _) =>
      s"You got an email from $sender with title: $title"
    case SMS(number, message) =>
      s"You got an SMS from $number! Message: $message"
    case VoiceRecording(name, link) =>
      s"You received a Voice Recording from $name! Click the link to hear it: $link"
  }
}
val someSms = SMS("12345", "Are you there?")
val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")

Which could be somewhat recoded in java such as :

Notification notification = /* Init a notification instance */

if(notification instanceof Email) {
    Email currentEmail = (Email) notification;
    currentEmail.doSomething();
} else if (notification instanceof SMS) {
    SMS currentSMS = (SMS) notification;
    currentSMS.doSomething();
} else if {
    /* ... */
}

Pattern matching seems to be very positively seen but on the opposite the java equivalent is seen as a "code smell" or a bad pattern.

From my understand they are doing the same thing and maybe technically as well, it's just hidden for the scala pattern matching.

Yet such a double standard wouldn't stay unseen so I guess there is something wrong with my understanding.



Solution 1:[1]

The "smell" has been historic. Object oriented design suggests you should be able to let the type hierarchy dispatch your method call to the appropriate subtype, rather than checking for actual instances at the call site. There had been some bad designs related to overuse of inheritance, which had lead to such instanceof usage. The instanceof usage wasn't the bad thing, but it hinted at the type hierarchy possibly being bad.

On the other hand, Java 17 now has Scala's pattern matching, too (as a preview feature, soon to be finalised), so you can't really say that using instanceof is a bad thing in Java.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Lukas Eder