Каковы отношения между любым, AnyVal, AnyRef, объектом и как они сопоставляются при использовании в коде Java?
Я обычно заканчиваю тем, что пробую каждую комбинацию, пока она не компилируется. Может кто-нибудь объяснить, что я должен использовать где?
3 ответа:
я не соглашусь с Крисответ в одном направлении. Классы
Any
,AnyRef
иAnyVal
are классы. Но они не появляются как классы в байт-коде из-за внутренних ограничений JVM.это происходит из-за того, что не все в Java является объектом. Кроме объектов, есть примитивы. Все объекты в Java являются потомками от
java.lang.Object
, но примитивы отличаются и, в настоящее время*, не расширяется программист. Обратите внимание также, что примитивы имеют "операторы", а не методы.в скале, с другой стороны, все и объект, все объекты относятся к классу, и они взаимодействуют с помощью методов. Созданный байт-код JVM не отражает этого, но это не делает их меньше, так же как Java имеет универсальные шаблоны, хотя байт-код их не имеет.
Итак, в Scala все объекты являются потомками от
Any
, и это включает в себя как то, что Java считает объектами, так и то, что Java считает примитивами. В Java нет эквивалента, потому что нет такой унификации.все, что считается примитивом в Java, является потомком
AnyVal
в Scala. До Scala 2.10.0,AnyVal
был запечатан, и программисты не смогли его продлить. Должно быть интересно посмотреть, что произойдет с Scala на .Net, так как только совместимость требует, чтобы Scala хотя бы распознала пользовательские "примитивы".также расширяя
Any
иAnyRef
, что эквивалентноjava.lang.Object
(на JVM, во всяком случае).до Scala 2.9.x, пользователь не может расширить
Any
илиAnyVal
, ни ссылаться на них из Java, но есть были другие пользы они смогли быть положены к в Scala. В частности, введите подписи:def f(x: AnyVal) = println(x) def g(x: AnyRef) = println(x) def h(x: Any) = println(x)
что каждому должно быть очевидно из иерархии классов. Следует отметить, однако, что
f
иh
автоматическое окно, ноg
не будет. Это немного противоположно тому, что делает Java, в этомf
иh
не может быть указан, иg
(Сjava.lang.Object
) вызовет авто-бокс.начиная с Scala 2.10.0, однако, пользователь может расширить
AnyVal
илиAny
со следующей семантикой:
если класс расширяет
AnyVal
, ни один экземпляр не будет создан для него в куче при определенных условиях. Это означает, что поля этого класса (на 2.10.0 разрешено только одно поле - будет ли это изменено, еще предстоит увидеть) останутся в стеке, являются ли они примитивами или ссылками на другие объекты. Это позволяет использовать методы расширения без затрат на создание экземпляра.если признак выходит
Any
, то он может быть использован с обоими классами, которые расширяютAnyRef
и классы, которые расширяютAnyVal
.PS: На мой взгляд, Java, скорее всего, последует C# в разрешении примитивов" struct " и, возможно, typedefs, поскольку параллелизм, не прибегая к ним, оказывается трудным для достижения хорошей производительности.
это видел? В тексте страницы есть некоторые замечания по совместимости java. http://www.scala-lang.org/node/128
Any
иAnyVal
являются, Я полагаю, частью scala система типа и не классы как таковые (точно так же, какNothing
- Это тип, а не класс). Вы не можете использовать их прямо из кода Java.однако, в Java / Scala взаимодействия, метод, который принимает Java
Object
будет ожидать scalaAny
/AnyRef
.что вы на самом деле пытаетесь сделать?