You can extend a Java class from a Scala class, and vice versa. For the most part, this should just work. As discussed earlier, if your methods accept function values as parameters, you’ll have trouble overriding them. Exceptions are also a problem.
Scala doesn’t have the throws clause. In Scala you can throw any exception from any method without having to explicitly declare that as part of the method signature. However, if you override such a method in Java, you’ll run into trouble when you try to throw an exception. Let’s look at an example. Suppose we have a Bird class defined in Scala:
| abstract class Bird { |
| def fly() |
| //... |
| } |
We also have another class, Ostrich:
Intermixing/Ostrich.scala | |
| class Ostrich extends Bird { |
| override def fly() { |
| throw new NoFlyException |
| } |
| //... |
| } |
where NoFlyException is defined like this:
Intermixing/NoFlyException.scala | |
| class NoFlyException extends Exception {} |
In the previous code, Ostrich’s fly method was able to throw the exception without any problem. However, if we implement a nonflying bird in Java, we’ll run into trouble, as shown here:
Intermixing/Penguin.java | |
| //Java code |
| class Penguin extends Bird { |
| public void fly() throws NoFlyException { |
| throw new NoFlyException(); |
| } |
| //... |
| } |
First, if we simply throw the exception, Java will complain about an unreported exception being thrown. But if we declare the intention of throwing the exception with the throws clause, we’ll get this:
| Penguin.java:3: error: fly() in Penguin cannot override fly() in Bird |
| public void fly() throws NoFlyException { |
| ^ |
| overridden method does not throw NoFlyException |
| 1 error |
Even though Scala is flexible and doesn’t insist that you specify what exceptions you throw, if you intend to extend from those methods in Java, you’ll have to ask the Scala compiler to emit those details in the method signature. Scala provides a backdoor for that by defining the @throws annotation.
Even though Scala supports annotations, it doesn’t provide any syntax to create an annotation. If you’d like to create your own annotations, you’ll have to do that using Java. @throws is an annotation already provided for you to express the checked exceptions your methods throw. So, for us to implement the Penguin in Java, we have to modify the Bird class in Scala like this:
Intermixing/Bird.scala | |
| abstract class Bird { |
| @throws(classOf[NoFlyException]) def fly() |
| //... |
| } |
Now when we compile the class, the Scala compiler will place the necessary signature for the fly method in the bytecode. The Penguin Java class will compile with no errors after this change.
18.222.49.190