Before this CL, calling overloaded methods on reverse bound Java classes and interfaces involved confusing and ugly name mangling. If a set of methods with the same name differed only in argument count, the mangling was simply adding the argument count to the name: func F() func F1(int32) But if two or more methods had the same number of arguments, the type had to be appended: func (...) F() int32 func (...) F1(int32) (int32, error) func (...) F__I(int32, int32) func (...) F__JLjava_util_concurrent_TimeUnit_2(int64, concurrent.TimeUnit) This CL sacrifices a bit of type safety and performance to regain the convenience and simplicity of Go by resolving overloaded method dispatch at runtime. Overloaded Java methods are combined to one Go method that, when invoked, determines the correct Java method variant at runtime. The signature of the Go method is compatible with every Java method with that name. For the example above, the single Go method becomes the most general func (...) F(...interface{}) (interface{}, error) The method is variadic to cover function with a varying number of arguments, and it returns interface{} to cover int32, int64 and no argument. Finally, it returns an error to cover the variant that returns an error. The generator tries to be specific; for example func G1(int32) int32 func G2(int32, int32) int32 becomes func G(int32, ...int32) int32 Overriding Java methods in Go is changed to use the Go parameter types to determine to correct Java method. To avoid name clashes when overriding multiple overloaded methods, trailing underscores in the method name are ignored when matching Java methods. See the Get methods of GoFuture in bind/testpkg/javapkg for an example. Change-Id: I6ac3e024141daa8fc2c35187865c5d7a63368094 Reviewed-on: https://go-review.googlesource.com/35186 Reviewed-by: David Crawshaw <crawshaw@golang.org>
63 lines
1.2 KiB
Go
63 lines
1.2 KiB
Go
// Copyright 2014 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package java
|
|
|
|
import (
|
|
gopkg "Java/java"
|
|
"Java/java/io"
|
|
"Java/java/lang"
|
|
"Java/java/lang/System"
|
|
"Java/java/util/Spliterators"
|
|
"Java/java/util/concurrent"
|
|
)
|
|
|
|
type Runnable struct {
|
|
lang.Runnable
|
|
}
|
|
|
|
func (r *Runnable) Run(this gopkg.Runnable) {
|
|
}
|
|
|
|
type InputStream struct {
|
|
io.InputStream
|
|
}
|
|
|
|
func (_ *InputStream) Read() (int32, error) {
|
|
return 0, nil
|
|
}
|
|
|
|
func NewInputStream() *InputStream {
|
|
return new(InputStream)
|
|
}
|
|
|
|
type Future struct {
|
|
concurrent.Future
|
|
}
|
|
|
|
func (_ *Future) Get() (lang.Object, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
// Use a trailing underscore to override multiple overloaded methods.
|
|
func (_ *Future) Get_(_ int64, _ concurrent.TimeUnit) (lang.Object, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
type Object struct {
|
|
lang.Object
|
|
}
|
|
|
|
func innerClassTypes() {
|
|
// java.util.Spliterators.iterator use inner class types
|
|
// for the return value as well as parameters.
|
|
Spliterators.Iterator(nil)
|
|
}
|
|
|
|
func returnType() {
|
|
// Implicit types (java.io.Console) should be wrapped.
|
|
cons := System.Console()
|
|
cons.Flush()
|
|
}
|