2016-12-23 1 views
1

ScalaのAnyjava.lang.Objectにどのように関係しているのか混乱しています。私はScalaで、)AnyRefobjectに対応するが、(java.lang.Objectを取る)メソッドは、JavaクラスやScalaのクラスで定義されているかどうかの違いを作るように見えることを知っている:Scala:java.lang.Objectを受け取るメソッドにAnyを渡す

Javaクラス:

public class JavaClass { 
    public static void method(Object input) { 
    } 
} 

のScalaアプリケーション:

object ScalaObject extends App{ 

    def method(input:java.lang.Object) = {} 

    val a:Any = null 

    method(a) // does not work 

    JavaClass.method(a) // does work 
} 

方法は、Javaクラスにあるのであれば、コンパイラは私がタイプAnyの変数を渡すことができます、なぜですか?

答えて

3

コンパイラは、ScalaとJavaの型システムの違いを "補う"ように試みます。 ScalaではObject =:= AnyRef(エイリアス)とAnyRef <: Anyです。したがって、ObjectまたはAnyRefを取るScalaメソッドは、AnyまたはAnyValを取ることはできません。すべてを扱う方法が必要だった場合は、Anyと書いたでしょうか?

しかし、Objectを取るジャワ方法は、通常、彼らが実際Object Sまたはプリミティブ(intlong、等)であるかどうか、全て値で動作するように意図され、それらはのボクシングの変換に起因して動作しますプリミティブをObjectに変換します。プリミティブとObjectは、Scalaでのように共通のスーパータイプを持っていません。 Javaのタイプのシステムは、「私は実際のオブジェクトだけが必要です」と区別するのに十分な表現力ではありません。

したがって、Scalaコンパイラは、JavaメソッドObjectAnyに変換することによってこれを修正します。この機能は、単に言語間の相互運用を容易にするためのものです。この変換をScalaコードに適用することはありません。その振る舞いが必要な場合は、実際にはObjectの代わりにAnyと書かれています。

2

その理由はmethodのみAnyRefあるオブジェクトを受け入れることができるがAnyは、AnyRef又はAnyValのいずれかとすることができるということです。あなたはAnyRefすべきaタイプを変更した場合、仕事に行くされています。静的Javaメソッドを呼び出した場合には

def method(input: java.lang.Object) = {} 
val a: AnyRef = new Object 
method(a) 

、ScalaのコンパイラはAnyVal値のボクシングを含む、ObjectAnyをオンにします。

関連する問題