Java 8 - default methods - problems for legacy code

Question from the book :

In the past (pre-Java 8), you were told that its poor form adds methods to the interface because it will break existing code. Now you are told that it’s ok to add new methods if you also provide a default implementation.

  • How safe is it? Describe the scenario in which the new stream method of the Collection interface causes compilation of outdated code to fail.
  • What about binary compatibility? Will the old code from the JAR file be saved?

My answers are as follows, but I'm not quite sure about them.

  • This is only safe if legacy code does not provide a method with the same stream name and the same signature (for example, in an inherited class that implements Collection ). Otherwise, this old deprecation code will not compile.
  • I think that binary compatibility is preserved, the old code from the old JAR file will still work. But I have no obvious arguments.

Can someone confirm or reject these answers or just add some more arguments, links or clarity to these answers?

+5
source share
1 answer
  • The new stream() method by default in Collection returns Stream<E> , as well as a new type in Java 8. Outdated code will not compile if it contains the stream() method with the same signature, but returning something else, which leads to collision of return types.

  • Outdated code will continue to work until it is recompiled.

First, in 1.7, set the following:

 public interface MyCollection { public void foo(); } public class Legacy implements MyCollection { @Override public void foo() { System.out.println("foo"); } public void stream() { System.out.println("Legacy"); } } public class Main { public static void main(String args[]) { Legacy l = new Legacy(); l.foo(); l.stream(); } } 

With -source 1.7 -target 1.7 , this compiles and runs:

 $ javac -target 1.7 -source 1.7 Legacy.java MyCollection.java Main.java $ java Main foo Legacy 

Now in 1.8, add the stream method to MyCollection .

 public interface MyCollection { public void foo(); public default Stream<String> stream() { return null; } } 

We compile only MyCollection in 1.8.

 $ javac MyCollection.java $ java Main foo Legacy 

Of course, we can no longer recompile Legacy.java .

 $ javac Legacy.java Legacy.java:11: error: stream() in Legacy cannot implement stream() in MyCollection public void stream() ^ return type void is not compatible with Stream<String> 1 error 
+8
source

Source: https://habr.com/ru/post/1233723/


All Articles