Skip to content

Instantly share code, notes, and snippets.

@flash42
Created September 26, 2019 16:36
Show Gist options
  • Save flash42/3e07daf4c0832a06c63a5ffa655e5cff to your computer and use it in GitHub Desktop.
Save flash42/3e07daf4c0832a06c63a5ffa655e5cff to your computer and use it in GitHub Desktop.
Use intersection type and method overloading to create type-safe collection initializer
import java.util.List;
import java.util.ArrayList;
// Demonstrate the usage of intersection types in Java
// We have a quite minimal setup so most of our types are created as inner classes
// Goal:
// We want to store items in two separate lists. These lists are filled by our clients calling the `addItem` method
// Our clients don't know about the implementation (two lists) and we don't want to use `instanceof`.
public class IntersectionType {
private interface Marker {};
private class Superclass {};
private class Subclass1 extends Superclass implements Marker {};
private class Subclass2 extends Superclass {};
private class Subclass3 extends Superclass implements Marker {};
private List<Superclass> markers = new ArrayList<>();
private List<Superclass> nonMarkers = new ArrayList<>();
private IntersectionType() {
// Notice that here we just instantiate classes, not knowing anything about internal details of the IntersectionType class
// Also we don't care about the `Marker` interface as it is used by Java's overloading mechanism only to differentiate between the instances.
addItem(new Subclass1());
addItem(new Subclass2());
addItem(new Subclass3());
}
public static void main(String[] args) {
new IntersectionType();
}
public <T extends Superclass & Marker> void addItem(T item) {
System.out.println("marker");
markers.add(item);
}
public void addItem(Subclass2 item) {
System.out.println("non-marker");
markers.add(item);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment