Каковы отношения между любым, AnyVal, AnyRef, объектом и как они сопоставляются при использовании в коде Java?


Я обычно заканчиваю тем, что пробую каждую комбинацию, пока она не компилируется. Может кто-нибудь объяснить, что я должен использовать где?

3 92

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 не может быть указан, и gjava.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

Scala Class Heierarchy

Any и AnyVal являются, Я полагаю, частью scala система типа и не классы как таковые (точно так же, как Nothing - Это тип, а не класс). Вы не можете использовать их прямо из кода Java.

однако, в Java / Scala взаимодействия, метод, который принимает Java Object будет ожидать scala Any/AnyRef.

что вы на самом деле пытаетесь сделать?