// Java class java.Future is a proxy for talking to a Go program.
//   gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
package java;

import go.Seq;

public final class Future implements Seq.GoObject, java.util.concurrent.Future {
    static { Java.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    Future(Seq.Ref ref) { this.ref = ref; }
    
    public Future() { this.ref = __New(); }
    
    private static native Seq.Ref __New();
    
    public final native java.util.concurrent.Future getFuture();
    public final native void setFuture(java.util.concurrent.Future v);
    
    @Override public native java.lang.Object get() throws java.lang.InterruptedException, java.util.concurrent.ExecutionException;
    /**
     * Use a trailing underscore to override multiple overloaded methods.
     */
    @Override public native java.lang.Object get(long p0, java.util.concurrent.TimeUnit p1) throws java.lang.InterruptedException, java.util.concurrent.ExecutionException, java.util.concurrent.TimeoutException;
}

// Java class java.InputStream is a proxy for talking to a Go program.
//   gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
package java;

import go.Seq;

public final class InputStream extends java.io.InputStream implements Seq.GoObject {
    static { Java.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    public InputStream() {
        super();
        this.ref = __NewInputStream();
    }
    
    private static native Seq.Ref __NewInputStream();
    
    public final native java.io.InputStream getInputStream();
    public final native void setInputStream(java.io.InputStream v);
    
    @Override public native int read() throws java.io.IOException;
}

// Java class java.Object is a proxy for talking to a Go program.
//   gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
package java;

import go.Seq;

public final class Object extends java.lang.Object implements Seq.GoObject {
    static { Java.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    Object(Seq.Ref ref) { this.ref = ref; }
    
    public Object() { this.ref = __New(); }
    
    private static native Seq.Ref __New();
    
    public final native java.lang.Object getObject();
    public final native void setObject(java.lang.Object v);
    
}

// Java class java.Runnable is a proxy for talking to a Go program.
//   gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
package java;

import go.Seq;

public final class Runnable implements Seq.GoObject, java.lang.Runnable {
    static { Java.touch(); }
    
    private final Seq.Ref ref;
    
    @Override public final int incRefnum() {
          int refnum = ref.refnum;
          Seq.incGoRef(refnum);
          return refnum;
    }
    
    Runnable(Seq.Ref ref) { this.ref = ref; }
    
    public Runnable() { this.ref = __New(); }
    
    private static native Seq.Ref __New();
    
    public final native java.lang.Runnable getRunnable();
    public final native void setRunnable(java.lang.Runnable v);
    
    @Override public native void run();
}

// Java class java.Java is a proxy for talking to a Go program.
//   gobind -lang=java classes
//
// File is generated by gobind. Do not edit.
package java;

import go.Seq;

public abstract class Java {
    static {
        Seq.touch(); // for loading the native library
        _init();
    }
    
    private Java() {} // uninstantiable
    
    // touch is called from other bound packages to initialize this package
    public static void touch() {}
    
    private static native void _init();
    
    
    
    public static native InputStream newInputStream();
}
