LoginSignup
1

More than 3 years have passed since last update.

Scala/Kotlin/JavaからJavaの可変長引数のメソッドを呼ぶ際の挙動

Last updated at Posted at 2019-06-29

なんの記事?

同一クラス内に同一名称のメソッドが、
可変長メソッドと固定長メソッドで混在しているJavaのクラス(要するに↓のようなクラス)を
Scala/Kotlin/Javaから引数1個で呼び出した場合に、どちらが呼ばれるかを調査した。

public class CalledClazz {
    public static void method(Object... args){
        System.out.println("可変長引数のメソッドです" + Arrays.toString(args));
    }
    public static void method(Object args){
        System.out.println("固定長引数のメソッドです" + args);
    }
}

結論

引数1個渡した際の挙動

調査方法(調査コード)

Javaから呼び出し

public class JavaClazz {
    public static void main(String... args) throws IOException {
        CalledClazz.method("Java");
        CalledClazz.method(null);
        Object s = null;
        CalledClazz.method(s);
        CalledClazz.method((Object)null);
    }
}

実行結果

固定長引数のメソッドですJava
可変長引数のメソッドですnull
固定長引数のメソッドですnull
固定長引数のメソッドですnull

nullを渡すと、可変長引数のほうにくる?
しかも、要素数1のObject型の配列ではなく、nullが渡る…。
しかもしかも、nullでなんらかの型で変数宣言して渡すか、Objectへキャストすると固定長引数のメソッドにくる…。

Kotlinから呼び出し

fun main() {
    CalledClazz.method("Kotlin")
    CalledClazz.method(null)
}

実行結果

固定長引数のメソッドですKotlin
固定長引数のメソッドですnull

自然な挙動っぽく見える。

Scalaから呼び出し

object CallTestByScala extends App {
  CalledClazz.method("Scala")
  CalledClazz.method(null)
}

実行結果

可変長引数のメソッドです[Scala]
可変長引数のメソッドです[null]

なんで配列になって、可変長引数のメソッドが呼ばれるんだろう。

Scalaから固定長引数のJavaメソッドを呼ぶ方法

val f: Object => Unit = CalledClazz.method
f("Scala")
固定長引数のメソッドですScala

とでるようになりました。

こうやって、型推論に任せないで、関数の型を宣言すると意図通りに呼ばれるようだ。
他にも方法があるんだろうか?

ちなみに、

val f: Object => Unit = CalledClazz.method
f("Scala", "aaaaa")

とやると、固定長引数のほうのメソッドが呼ばれ、Tuple2型の1つの値が渡され、

固定長引数のメソッドです(Scala,aaaaa)

と出ます。

オマケ

method(Object... args)はScalaから見ると、反復パラメータという扱いらしく、
scala.ListをJavaの可変長メソッドへ 意図したとおりに 渡したい場合は、

CalledClazz.method(List("a","b","b"): _*)

とする必要があります。
つけないと、List("a","b","b")というオブジェクト1個を要素とした、要素数1の配列という扱いになるようで、

可変長引数のメソッドです[List(a, b, b)]

と出てしまう。

参考資料

Scala: 反復パラメータ(Repeated Parameters)にListで渡す方法 - Qiita

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1