Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8: Spliterator, Iterator, Collection and "default" implemenations in Interfaces (Duplicate methods named spliterator)

Have an interesting situation following the release of Java 1.8.0_25 into the wilds... I believe the root of my issue is related primarily to the new (to 1.8) features of "default" implementations within Interfaces.

The application I am working on is currently targeted at 1.7, which until now has been working well. Until users started updating to 1.8. Now that our users have started updating to 1.8, our hand is forced somewhat into moving to 1.8 support.

We have fixed most of the issues (mainly relating to changes to the JavaFX packages between 1.7 and 1.8) but have one vexing issue remaining.

In my wisdom, or lack thereof, I, some time ago, decided to create a SortedList<T> which extends from AbstractList<T>. Until now, this class has worked fine, however when running on a 1.8 runtime, I get:

Duplicate methods named spliterator with the parameters () and () are inherited 
from the types Collection<T> and Iterable<T>

This, to me, appears to be caused by the "default" implementations in some of the Interfaces that are implemented by AbstractList<T> (my SortedList<T> class does not implement any additional Interfaces other than Serializable). Implementing Serializable is another problem for us, as we need to support deserialisation of SortedList<T> objects, there's no way around that!).

I can get rid of the error by providing an override implementation of spliterator() in my SortedList<T> class. However, if this is built, it no longer runs on a Java 1.7 environment. If I attempt to use SortedList<T> with a 1.7 runtime, I get:

Problem:
Error: Unresolved compilation problems:
The import java.util.Spliterator cannot be resolved
Spliterator cannot be resolved to a type

com.xxxx.xxxx.util.SortedList.<init>(SortedList.java:13) 

This error is pretty obvious, since we've now overridden the spliterator() method in SortedList<T> it needs to include java.util.Spliterator, but that doesn't exist in 1.7.

Ideally we would like to NOT require our customers to update to Java 1.8 if they don't want to.

Is our hand being forced here? Do we need to force users to update to 1.8 and also roll out a new version to any users who have updated to 1.8 by themselves?

Does anyone know a way around this issue?

On a more philosophical note, why has Interface been corrupted with with implementation :-(. Might be a nifty new feature, but they really should have avoided doing anything that would result in breaking changes to existing code, particularly in something so fundamental as lists/collections etc.

Any help or suggestions regarding this predicament would be greatly appreciated.

Cheers,

Mark

like image 990
Gumbatron Avatar asked Oct 21 '14 06:10

Gumbatron


1 Answers

The whole point of default methods is to avoid the situation you describe. The code below compiles and runs as expected with Java 7 and 8:

public class SortedList<T> extends AbstractList<T> implements Serializable {
  @Override public T get(int index) { return null; }
  @Override public int size() { return 0; }

  public static void main(String[] args) {
    SortedList<String> s = new SortedList<> ();
    System.out.println(s.size());
  }
}
like image 161
assylias Avatar answered Sep 28 '22 09:09

assylias