// Code generated by gobind. DO NOT EDIT.

// Java class issue12328.T is a proxy for talking to a Go program.
//
//   autogenerated by gobind -lang=java issue12328
package issue12328;

import go.Seq;

public final class T implements Seq.Proxy {
    static { Issue12328.touch(); }
    
    private final int refnum;
    
    @Override public final int incRefnum() {
          Seq.incGoRef(refnum, this);
          return refnum;
    }
    
    T(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
    
    public T() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
    
    private static native int __New();
    
    public final native java.lang.Exception getErr();
    public final native void setErr(java.lang.Exception v);
    
    @Override public boolean equals(Object o) {
        if (o == null || !(o instanceof T)) {
            return false;
        }
        T that = (T)o;
        java.lang.Exception thisErr = getErr();
        java.lang.Exception thatErr = that.getErr();
        if (thisErr == null) {
            if (thatErr != null) {
                return false;
            }
        } else if (!thisErr.equals(thatErr)) {
            return false;
        }
        return true;
    }
    
    @Override public int hashCode() {
        return java.util.Arrays.hashCode(new Object[] {getErr()});
    }
    
    @Override public String toString() {
        StringBuilder b = new StringBuilder();
        b.append("T").append("{");
        b.append("Err:").append(getErr()).append(",");
        return b.append("}").toString();
    }
}

// Code generated by gobind. DO NOT EDIT.

// Java class issue12328.Issue12328 is a proxy for talking to a Go program.
//
//   autogenerated by gobind -lang=java issue12328
package issue12328;

import go.Seq;

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