2016-12-23 2 views
1

Я смущен тем, как Scala's Any относится к java.lang.Object. Я знаю, что в Скале, AnyRef соответствует object, но это, кажется, делает разницу ли этот метод (который принимает java.lang.Object) определяется в классе Java или класс Scala):Scala: Передача любого метода, который принимает java.lang.Object

класс 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. Поэтому метод Scala, который принимает Object или AnyRef, не может принимать Any или AnyVal. Если вам нужен метод, который работал на все, ну, тогда вы бы написали Any, правильно?

Однако Java методы, которые принимают Object, как правило, предназначены для работы на всех ценностей, будь то фактические Object s или примитивы (int, long и т.д.), и они работают за счет преобразования бокса примитивов в Object с. Примитивы и Object не имеют общего супертипа, как в Scala. Система типа Java недостаточно выразительна, чтобы различать «Я хочу только фактические объекты», от «Я возьму что угодно, будь они объективными или примитивными».

Поэтому компилятор Scala исправляет это, превращая Java-методы Object в методы Any. Эта функция просто упрощает взаимодействие между языками. Однако это преобразование не будет применяться к коду Scala, потому что если вы хотите этого поведения, вы бы написали Any вместо Object.

2

Причиной этого является то, что Any может быть AnyRef или AnyVal, в то время как method может принимать только объекты, которые AnyRef. Если изменить тип a быть AnyRef, он будет работать:

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

В случае вызова статического метода Java, компилятор Scala превратит Any в Object, который также включает в себя бокс из AnyVal значений.