// File is generated by gobind. Do not edit.

package Java

// Used to silence this package not used errors
const Dummy = 0

type Java_lang_Float interface {
}

type Java_lang_Object interface {
	Super() Java_lang_Object
}

type Java_lang_Runnable interface {
}

type Java_lang_Character interface {
}

type Java_lang_Character_Subset interface {
	Super() Java_lang_Character_Subset
}

// File is generated by gobind. Do not edit.

package gomobile_bind

/*
#include <stdlib.h> // for free()
#include <jni.h>
#include "seq.h"
#include "classes.h"
*/
import "C"

import (
	"Java"
	_seq "golang.org/x/mobile/bind/seq"
)

import "unsafe"

type proxy interface { Bind_proxy_refnum__() int32 }

// Suppress unused package error

var _ = _seq.FromRefNum
const _ = Java.Dummy

//export initClasses
func initClasses() {
	C.init_proxies()
	init_java_lang_Float()
	init_java_lang_Object()
	init_java_lang_Runnable()
	init_java_lang_Character()
	init_java_lang_Character_Subset()
}

func init_java_lang_Float() {
	cls := C.CString("java/lang/Float")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
}

type proxy_class_java_lang_Float _seq.Ref

func (p *proxy_class_java_lang_Float) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func init_java_lang_Object() {
	cls := C.CString("java/lang/Object")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
}

type proxy_class_java_lang_Object _seq.Ref

func (p *proxy_class_java_lang_Object) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_lang_Object) Super() Java.Java_lang_Object {
	return &super_java_lang_Object{p}
}

type super_java_lang_Object struct {*proxy_class_java_lang_Object}

func init_java_lang_Runnable() {
	cls := C.CString("java/lang/Runnable")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
}

type proxy_class_java_lang_Runnable _seq.Ref

func (p *proxy_class_java_lang_Runnable) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func init_java_lang_Character() {
	cls := C.CString("java/lang/Character")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
}

type proxy_class_java_lang_Character _seq.Ref

func (p *proxy_class_java_lang_Character) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func init_java_lang_Character_Subset() {
	cls := C.CString("java/lang/Character$Subset")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
}

type proxy_class_java_lang_Character_Subset _seq.Ref

func (p *proxy_class_java_lang_Character_Subset) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

func (p *proxy_class_java_lang_Character_Subset) Super() Java.Java_lang_Character_Subset {
	return &super_java_lang_Character_Subset{p}
}

type super_java_lang_Character_Subset struct {*proxy_class_java_lang_Character_Subset}

// Package gomobile_bind is an autogenerated binder stub for package java.
//   gobind -lang=go java
//
// File is generated by gobind. Do not edit.
package gomobile_bind

/*
#include <stdlib.h>
#include <stdint.h>
#include "seq.h"
#include "java.h"

*/
import "C"

import (
	_seq "golang.org/x/mobile/bind/seq"
)

// suppress the error if seq ends up unused
var _ = _seq.FromRefNum

type proxyjava_F _seq.Ref

func (p *proxyjava_F) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

// skipped method O.Super with unsupported parameter or return types

type proxyjava_O _seq.Ref

func (p *proxyjava_O) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

// skipped method O.Super with unsupported parameter or result types
type proxyjava_R _seq.Ref

func (p *proxyjava_R) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

// skipped method S.Super with unsupported parameter or return types

type proxyjava_S _seq.Ref

func (p *proxyjava_S) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

// skipped method S.Super with unsupported parameter or result types
