// Code generated by gobind. DO NOT EDIT.

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

import go.Seq;

public final class Underscore_struct implements Seq.Proxy {
    static { Underscore_pkg.touch(); }
    
    private final int refnum;
    
    @Override public final int incRefnum() {
          Seq.incGoRef(refnum, this);
          return refnum;
    }
    
    Underscore_struct(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); }
    
    public Underscore_struct() { this.refnum = __New(); Seq.trackGoRef(refnum, this); }
    
    private static native int __New();
    
    public final native String getUnderscore_field();
    public final native void setUnderscore_field(String v);
    
    @Override public boolean equals(Object o) {
        if (o == null || !(o instanceof Underscore_struct)) {
            return false;
        }
        Underscore_struct that = (Underscore_struct)o;
        String thisUnderscore_field = getUnderscore_field();
        String thatUnderscore_field = that.getUnderscore_field();
        if (thisUnderscore_field == null) {
            if (thatUnderscore_field != null) {
                return false;
            }
        } else if (!thisUnderscore_field.equals(thatUnderscore_field)) {
            return false;
        }
        return true;
    }
    
    @Override public int hashCode() {
        return java.util.Arrays.hashCode(new Object[] {getUnderscore_field()});
    }
    
    @Override public String toString() {
        StringBuilder b = new StringBuilder();
        b.append("Underscore_struct").append("{");
        b.append("Underscore_field:").append(getUnderscore_field()).append(",");
        return b.append("}").toString();
    }
}

// Code generated by gobind. DO NOT EDIT.

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

import go.Seq;

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