Structural Subtyping の実装。

何日か前に痺れたStructural Subtypingが.scalaから.classにコンパイルされると、
どういう実装になっているのか気になったので、jadってみますた。

public final class Flyers
{

    public static final int $tag()
    {
        return Flyers$.MODULE$.$tag();
    }

    public static final void main(String args[])
    {
        Flyers$.MODULE$.main(args);
    }

    public static final void takeoff(int i, Object obj)
    {
        Flyers$.MODULE$.takeoff(i, obj);
    }
}

public final class Flyers$
    implements ScalaObject
{

    public static final Flyers$ MODULE$ = this;
    private static Class reflClass$Cache2;
    private static Method reflMethod$Cache2;
    private static Class reflClass$Cache1;
    private static Method reflMethod$Cache1;

    public Flyers$()
    {
    }

    public void main(String args[])
    {
        Flyers.Bird bird = new anon._cls1();
        takeoff(12, bird);
        Flyers.Plane plane = new Flyers.Plane("AT-2148");
        takeoff(32, plane);
    }

    public void takeoff(int runaway, Object r)
    {
        Predef$.MODULE$;
        (new StringBuilder()).append("CALLSIGN : ");
        Object exceptionResult1 = null;
        (String)(exceptionResult1 = reflMethod$Method1(r.getClass()).invoke(r, new Object[0]));
        append();
        toString();
        println();
        Object exceptionResult2 = null;
        InvocationTargetException invocationtargetexception;
        try
        {
            exceptionResult2 = reflMethod$Method2(r.getClass()).invoke(r, new Object[] {
                BoxesRunTime.boxToInteger(runaway)
            });
        }
        catch(InvocationTargetException invocationtargetexception1)
        {
            throw invocationtargetexception1.getCause();
        }
        exceptionResult2;
        BoxedUnit.UNIT;
        return;
        invocationtargetexception;
        throw invocationtargetexception.getCause();
    }

    public int $tag()
    {
        return scala.ScalaObject.class.$tag(this);
    }

    public static Method reflMethod$Method2(Class x$1)
    {
        if(reflMethod$Cache2 == null || reflClass$Cache2 != x$1)
        {
            reflMethod$Cache2 = x$1.getMethod("fly", new Class[] {
                Integer.TYPE
            });
            reflClass$Cache2 = x$1;
        }
        return reflMethod$Cache2;
    }

    public static Method reflMethod$Method1(Class x$1)
    {
        if(reflMethod$Cache1 == null || reflClass$Cache1 != x$1)
        {
            reflMethod$Cache1 = x$1.getMethod("callsign", new Class[0]);
            reflClass$Cache1 = x$1;
        }
        return reflMethod$Cache1;
    }

    static 
    {
        new Flyers$();
    }
}
public class Flyers$Bird
    implements ScalaObject
{

    private final String name;

    public void fly(int height)
    {
        Console$.MODULE$.println("I'm Fly");
    }

    public String name()
    {
        return name;
    }

    public int $tag()
    {
        return scala.class..tag(this);
    }

    public Flyers$Bird(String name)
    {
        this.name = name;
        super();
    }
}
public class Flyers$Plane
    implements ScalaObject
{

    private final String callsign;

    public void fly(int height)
    {
        Predef$.MODULE$.println("We're Fly");
    }

    public String callsign()
    {
        return callsign;
    }

    public int $tag()
    {
        return scala.lass..tag(this);
    }

    public Flyers$Plane(String callsign)
    {
        this.callsign = callsign;
        super();
    }
}
public final class Flyers$$anon$1 extends Flyers.Bird
{

    private final String callsign = name();

    public String callsign()
    {
        return callsign;
    }

    public Flyers$$anon$1()
    {
        super("Raven");
    }
}

全力でリフレクションです。まぁ、さもありなん…という感じかな…と。
jad先生が頑張りきれなくて、実行可能なソースコードは出てきていませんけども。
これを見ると、scalajavaからもある程度使える様に.classを生成している様に見受けられます。
もう少し想像を絶する様な、何かヒドイモノが出てくると思っていただけにちょっと拍子抜けしたりとか。


scalaでコーディングしている時、intは、scala.Intなんだけども、
.classファイルになった時には、javaのプリミティブintになっているトコロなんかは、
javascalaでインターフェース取ろうとした時に、ハマる原因になるんじゃないかなぁ…と思ったり。