// 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 int refnum;
    
    @Override public final int incRefnum() {
          Seq.incGoRef(refnum, this);
          return refnum;
    }
    
    Future(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
    
    public Future() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
    
    private static native int __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 int refnum;
    
    @Override public final int incRefnum() {
          Seq.incGoRef(refnum, this);
          return refnum;
    }
    
    public InputStream() {
        super();
        this.refnum = __NewInputStream();
        Seq.trackGoRef(refnum, this);
    }
    
    private static native int __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 int refnum;
    
    @Override public final int incRefnum() {
          Seq.incGoRef(refnum, this);
          return refnum;
    }
    
    Object(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
    
    public Object() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
    
    private static native int __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 int refnum;
    
    @Override public final int incRefnum() {
          Seq.incGoRef(refnum, this);
          return refnum;
    }
    
    Runnable(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
    
    public Runnable() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
    
    private static native int __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();
}
