Java で smart cast っぽいことをやる

小ネタです。

Kotlin とかの smart cast, TypeScript とかの Type Guard のようなことを Java でできないかなと。 変数の型をチェックしたら、自動でキャストされているみたいなやつです。

普通に書くと

if (pet instanceof Bird) {
    ((Bird)pet).fly();
} else if (pet instanceof Fish) {
    ((Fish)pet).swim();
} else {
    pet.sleep();
}

cast(pet).when(Bird.class, bird -> {
    bird.fly();
}).when(Fish.class, fish -> {
    fish.swim();
}).otherwise(() -> {
    pet.sleep();
});

こうなる。

この cast メソッド周りの実装が、

public class Cast {

    private final Object object;
    private boolean closed = false;

    public static Cast cast(Object o) {
        return new Cast(o);
    }

    public Cast(Object object) {
        this.object = object;
    }

    @SuppressWarnings("unchecked")
    public <T> Cast when(Class<T> cls, Consumer<T> s) {
        if (!closed && cls.isAssignableFrom(object.getClass())) {
            s.accept((T) object);
            closed = true;
        }
        return this;
    }

    public <T> void otherwise(Runnable r) {
        if (closed)
            return;
        r.run();
    }
}

まー、使わないかなw