Difference between Object and AnyRef in Scala
up vote
3
down vote
favorite
From this scheme in the Unified typed article in Scala tour I thought that AnyRef
and Object
are full equivalents.
However, when inspecting declarations in Eclipse, I've found some interesting things:
object ClassTag {
…
val Object : ClassTag[java.lang.Object] = Manifest.Object
…
val AnyRef : ClassTag[scala.AnyRef] = Manifest.AnyRef
…
}
object TypeTag {
…
val AnyRef: TypeTag[scala.AnyRef] = new PredefTypeTag[scala.AnyRef] (AnyRefTpe, _.TypeTag.AnyRef)
val Object: TypeTag[java.lang.Object] = new PredefTypeTag[java.lang.Object] (ObjectTpe, _.TypeTag.Object)
…
}
Some experiments:
import scala.reflect.ClassTag
import scala.reflect.runtime.universe.TypeTag
println(ClassTag.AnyRef == ClassTag.Object) //true
def getClassTag[V](v: V)(implicit tag: ClassTag[V]) = tag
println(getClassTag[AnyRef](null)) //Object
println(getClassTag[Object](null)) //Object
println(getClassTag(null.asInstanceOf[AnyRef])) //Object
println(getClassTag(null.asInstanceOf[Object])) //Object
println(getClassTag(new AnyRef())) //Object
println(getClassTag(new Object())) //Object
println
println(TypeTag.AnyRef == TypeTag.Object) //false
def getTypeTag[V](v: V)(implicit tag: TypeTag[V]) = tag
println(getTypeTag[AnyRef](null)) //TypeTag[AnyRef]
println(getTypeTag[Object](null)) //TypeTag[Object]
println(getTypeTag(null.asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(null.asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new AnyRef())) //TypeTag[Object]
println(getTypeTag(new Object())) //TypeTag[Object]
println(getTypeTag(new AnyRef().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new AnyRef().asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new Object().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new Object().asInstanceOf[Object])) //TypeTag[Object]
println
println(TypeTag.AnyRef.tpe == TypeTag.Object.tpe) //false
def getType[V](v: V)(implicit tag: TypeTag[V]) = tag.tpe
println(getType[AnyRef](null)) //AnyRef
println(getType[Object](null)) //Object
println(getType(null.asInstanceOf[AnyRef])) //AnyRef
println(getType(null.asInstanceOf[Object])) //Object
println(getType(new AnyRef())) //Object
println(getType(new Object())) //Object
println(getType(new AnyRef().asInstanceOf[AnyRef])) //AnyRef
println(getType(new AnyRef().asInstanceOf[Object])) //Object
println(getType(new Object().asInstanceOf[AnyRef])) //AnyRef
println(getType(new Object().asInstanceOf[Object])) //Object
So, at least at some levels of type information Object
and AnyRef
are somewhat distinguished. What is it done for? Or is it purely a bug?
scala types
add a comment |
up vote
3
down vote
favorite
From this scheme in the Unified typed article in Scala tour I thought that AnyRef
and Object
are full equivalents.
However, when inspecting declarations in Eclipse, I've found some interesting things:
object ClassTag {
…
val Object : ClassTag[java.lang.Object] = Manifest.Object
…
val AnyRef : ClassTag[scala.AnyRef] = Manifest.AnyRef
…
}
object TypeTag {
…
val AnyRef: TypeTag[scala.AnyRef] = new PredefTypeTag[scala.AnyRef] (AnyRefTpe, _.TypeTag.AnyRef)
val Object: TypeTag[java.lang.Object] = new PredefTypeTag[java.lang.Object] (ObjectTpe, _.TypeTag.Object)
…
}
Some experiments:
import scala.reflect.ClassTag
import scala.reflect.runtime.universe.TypeTag
println(ClassTag.AnyRef == ClassTag.Object) //true
def getClassTag[V](v: V)(implicit tag: ClassTag[V]) = tag
println(getClassTag[AnyRef](null)) //Object
println(getClassTag[Object](null)) //Object
println(getClassTag(null.asInstanceOf[AnyRef])) //Object
println(getClassTag(null.asInstanceOf[Object])) //Object
println(getClassTag(new AnyRef())) //Object
println(getClassTag(new Object())) //Object
println
println(TypeTag.AnyRef == TypeTag.Object) //false
def getTypeTag[V](v: V)(implicit tag: TypeTag[V]) = tag
println(getTypeTag[AnyRef](null)) //TypeTag[AnyRef]
println(getTypeTag[Object](null)) //TypeTag[Object]
println(getTypeTag(null.asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(null.asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new AnyRef())) //TypeTag[Object]
println(getTypeTag(new Object())) //TypeTag[Object]
println(getTypeTag(new AnyRef().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new AnyRef().asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new Object().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new Object().asInstanceOf[Object])) //TypeTag[Object]
println
println(TypeTag.AnyRef.tpe == TypeTag.Object.tpe) //false
def getType[V](v: V)(implicit tag: TypeTag[V]) = tag.tpe
println(getType[AnyRef](null)) //AnyRef
println(getType[Object](null)) //Object
println(getType(null.asInstanceOf[AnyRef])) //AnyRef
println(getType(null.asInstanceOf[Object])) //Object
println(getType(new AnyRef())) //Object
println(getType(new Object())) //Object
println(getType(new AnyRef().asInstanceOf[AnyRef])) //AnyRef
println(getType(new AnyRef().asInstanceOf[Object])) //Object
println(getType(new Object().asInstanceOf[AnyRef])) //AnyRef
println(getType(new Object().asInstanceOf[Object])) //Object
So, at least at some levels of type information Object
and AnyRef
are somewhat distinguished. What is it done for? Or is it purely a bug?
scala types
TypeTag
andClassTag
just provide two different things. See stackoverflow.com/questions/40202504/… and medium.com/@sinisalouc/… What you are likely seeing withTypeTag
is the actual distinction betweenAnyRef
andObject
since thatTypeTag
deals with the types andAnyRef
is indeed different thanObject
type wise sinceAnyRef
is just atrait
and is indeed different thanAnyRef
github.com/scala/scala/tree/2.12.x/src/library-aux/scala
– Daniel Hinojosa
Nov 22 at 17:31
1
Note that you don't needgetTypeTag
, you can just write e.g.implicitly[TypeTag[AnyRef]]
to summon an instance.
– Seth Tisue
Nov 22 at 17:35
@DanielHinojosa, it's interesting thatAnyRef
is declared as a trait. But I don't think it's really a trait, I think some compiler magic processes such core things in standard library differently. First of all, I believe to Seth Tissue's opinion; second, I can donew AnyRef()
, but nottrait T; new T()
; third,typeTag.mirror.runtimeClass(typeTag.tpe).isInterface()
returnsfalse
forAnyRef
(usually it returnstrue
for traits).
– Sasha
Nov 22 at 18:09
@Sasha That is an interesting catch and I think the README right before would lead to some answers. github.com/scala/scala/blob/2.12.x/src/library-aux/README. "Source files under this directory cannot be compiled by normal means. They exist for bootstrapping and documentation purposes." So there is something during scala bootstrapping that takes the traitness of AnyRef and merges it withjava.lang.Object
at runtime (maybe) and yet theAnyRef
andObject
forTypeTags
are distinct. Now, what is happening at bootstrap?
– Daniel Hinojosa
Nov 22 at 18:18
add a comment |
up vote
3
down vote
favorite
up vote
3
down vote
favorite
From this scheme in the Unified typed article in Scala tour I thought that AnyRef
and Object
are full equivalents.
However, when inspecting declarations in Eclipse, I've found some interesting things:
object ClassTag {
…
val Object : ClassTag[java.lang.Object] = Manifest.Object
…
val AnyRef : ClassTag[scala.AnyRef] = Manifest.AnyRef
…
}
object TypeTag {
…
val AnyRef: TypeTag[scala.AnyRef] = new PredefTypeTag[scala.AnyRef] (AnyRefTpe, _.TypeTag.AnyRef)
val Object: TypeTag[java.lang.Object] = new PredefTypeTag[java.lang.Object] (ObjectTpe, _.TypeTag.Object)
…
}
Some experiments:
import scala.reflect.ClassTag
import scala.reflect.runtime.universe.TypeTag
println(ClassTag.AnyRef == ClassTag.Object) //true
def getClassTag[V](v: V)(implicit tag: ClassTag[V]) = tag
println(getClassTag[AnyRef](null)) //Object
println(getClassTag[Object](null)) //Object
println(getClassTag(null.asInstanceOf[AnyRef])) //Object
println(getClassTag(null.asInstanceOf[Object])) //Object
println(getClassTag(new AnyRef())) //Object
println(getClassTag(new Object())) //Object
println
println(TypeTag.AnyRef == TypeTag.Object) //false
def getTypeTag[V](v: V)(implicit tag: TypeTag[V]) = tag
println(getTypeTag[AnyRef](null)) //TypeTag[AnyRef]
println(getTypeTag[Object](null)) //TypeTag[Object]
println(getTypeTag(null.asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(null.asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new AnyRef())) //TypeTag[Object]
println(getTypeTag(new Object())) //TypeTag[Object]
println(getTypeTag(new AnyRef().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new AnyRef().asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new Object().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new Object().asInstanceOf[Object])) //TypeTag[Object]
println
println(TypeTag.AnyRef.tpe == TypeTag.Object.tpe) //false
def getType[V](v: V)(implicit tag: TypeTag[V]) = tag.tpe
println(getType[AnyRef](null)) //AnyRef
println(getType[Object](null)) //Object
println(getType(null.asInstanceOf[AnyRef])) //AnyRef
println(getType(null.asInstanceOf[Object])) //Object
println(getType(new AnyRef())) //Object
println(getType(new Object())) //Object
println(getType(new AnyRef().asInstanceOf[AnyRef])) //AnyRef
println(getType(new AnyRef().asInstanceOf[Object])) //Object
println(getType(new Object().asInstanceOf[AnyRef])) //AnyRef
println(getType(new Object().asInstanceOf[Object])) //Object
So, at least at some levels of type information Object
and AnyRef
are somewhat distinguished. What is it done for? Or is it purely a bug?
scala types
From this scheme in the Unified typed article in Scala tour I thought that AnyRef
and Object
are full equivalents.
However, when inspecting declarations in Eclipse, I've found some interesting things:
object ClassTag {
…
val Object : ClassTag[java.lang.Object] = Manifest.Object
…
val AnyRef : ClassTag[scala.AnyRef] = Manifest.AnyRef
…
}
object TypeTag {
…
val AnyRef: TypeTag[scala.AnyRef] = new PredefTypeTag[scala.AnyRef] (AnyRefTpe, _.TypeTag.AnyRef)
val Object: TypeTag[java.lang.Object] = new PredefTypeTag[java.lang.Object] (ObjectTpe, _.TypeTag.Object)
…
}
Some experiments:
import scala.reflect.ClassTag
import scala.reflect.runtime.universe.TypeTag
println(ClassTag.AnyRef == ClassTag.Object) //true
def getClassTag[V](v: V)(implicit tag: ClassTag[V]) = tag
println(getClassTag[AnyRef](null)) //Object
println(getClassTag[Object](null)) //Object
println(getClassTag(null.asInstanceOf[AnyRef])) //Object
println(getClassTag(null.asInstanceOf[Object])) //Object
println(getClassTag(new AnyRef())) //Object
println(getClassTag(new Object())) //Object
println
println(TypeTag.AnyRef == TypeTag.Object) //false
def getTypeTag[V](v: V)(implicit tag: TypeTag[V]) = tag
println(getTypeTag[AnyRef](null)) //TypeTag[AnyRef]
println(getTypeTag[Object](null)) //TypeTag[Object]
println(getTypeTag(null.asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(null.asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new AnyRef())) //TypeTag[Object]
println(getTypeTag(new Object())) //TypeTag[Object]
println(getTypeTag(new AnyRef().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new AnyRef().asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new Object().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new Object().asInstanceOf[Object])) //TypeTag[Object]
println
println(TypeTag.AnyRef.tpe == TypeTag.Object.tpe) //false
def getType[V](v: V)(implicit tag: TypeTag[V]) = tag.tpe
println(getType[AnyRef](null)) //AnyRef
println(getType[Object](null)) //Object
println(getType(null.asInstanceOf[AnyRef])) //AnyRef
println(getType(null.asInstanceOf[Object])) //Object
println(getType(new AnyRef())) //Object
println(getType(new Object())) //Object
println(getType(new AnyRef().asInstanceOf[AnyRef])) //AnyRef
println(getType(new AnyRef().asInstanceOf[Object])) //Object
println(getType(new Object().asInstanceOf[AnyRef])) //AnyRef
println(getType(new Object().asInstanceOf[Object])) //Object
So, at least at some levels of type information Object
and AnyRef
are somewhat distinguished. What is it done for? Or is it purely a bug?
scala types
scala types
edited Nov 22 at 16:50
asked Nov 22 at 16:41
Sasha
1,5401528
1,5401528
TypeTag
andClassTag
just provide two different things. See stackoverflow.com/questions/40202504/… and medium.com/@sinisalouc/… What you are likely seeing withTypeTag
is the actual distinction betweenAnyRef
andObject
since thatTypeTag
deals with the types andAnyRef
is indeed different thanObject
type wise sinceAnyRef
is just atrait
and is indeed different thanAnyRef
github.com/scala/scala/tree/2.12.x/src/library-aux/scala
– Daniel Hinojosa
Nov 22 at 17:31
1
Note that you don't needgetTypeTag
, you can just write e.g.implicitly[TypeTag[AnyRef]]
to summon an instance.
– Seth Tisue
Nov 22 at 17:35
@DanielHinojosa, it's interesting thatAnyRef
is declared as a trait. But I don't think it's really a trait, I think some compiler magic processes such core things in standard library differently. First of all, I believe to Seth Tissue's opinion; second, I can donew AnyRef()
, but nottrait T; new T()
; third,typeTag.mirror.runtimeClass(typeTag.tpe).isInterface()
returnsfalse
forAnyRef
(usually it returnstrue
for traits).
– Sasha
Nov 22 at 18:09
@Sasha That is an interesting catch and I think the README right before would lead to some answers. github.com/scala/scala/blob/2.12.x/src/library-aux/README. "Source files under this directory cannot be compiled by normal means. They exist for bootstrapping and documentation purposes." So there is something during scala bootstrapping that takes the traitness of AnyRef and merges it withjava.lang.Object
at runtime (maybe) and yet theAnyRef
andObject
forTypeTags
are distinct. Now, what is happening at bootstrap?
– Daniel Hinojosa
Nov 22 at 18:18
add a comment |
TypeTag
andClassTag
just provide two different things. See stackoverflow.com/questions/40202504/… and medium.com/@sinisalouc/… What you are likely seeing withTypeTag
is the actual distinction betweenAnyRef
andObject
since thatTypeTag
deals with the types andAnyRef
is indeed different thanObject
type wise sinceAnyRef
is just atrait
and is indeed different thanAnyRef
github.com/scala/scala/tree/2.12.x/src/library-aux/scala
– Daniel Hinojosa
Nov 22 at 17:31
1
Note that you don't needgetTypeTag
, you can just write e.g.implicitly[TypeTag[AnyRef]]
to summon an instance.
– Seth Tisue
Nov 22 at 17:35
@DanielHinojosa, it's interesting thatAnyRef
is declared as a trait. But I don't think it's really a trait, I think some compiler magic processes such core things in standard library differently. First of all, I believe to Seth Tissue's opinion; second, I can donew AnyRef()
, but nottrait T; new T()
; third,typeTag.mirror.runtimeClass(typeTag.tpe).isInterface()
returnsfalse
forAnyRef
(usually it returnstrue
for traits).
– Sasha
Nov 22 at 18:09
@Sasha That is an interesting catch and I think the README right before would lead to some answers. github.com/scala/scala/blob/2.12.x/src/library-aux/README. "Source files under this directory cannot be compiled by normal means. They exist for bootstrapping and documentation purposes." So there is something during scala bootstrapping that takes the traitness of AnyRef and merges it withjava.lang.Object
at runtime (maybe) and yet theAnyRef
andObject
forTypeTags
are distinct. Now, what is happening at bootstrap?
– Daniel Hinojosa
Nov 22 at 18:18
TypeTag
and ClassTag
just provide two different things. See stackoverflow.com/questions/40202504/… and medium.com/@sinisalouc/… What you are likely seeing with TypeTag
is the actual distinction between AnyRef
and Object
since that TypeTag
deals with the types and AnyRef
is indeed different than Object
type wise since AnyRef
is just a trait
and is indeed different than AnyRef
github.com/scala/scala/tree/2.12.x/src/library-aux/scala– Daniel Hinojosa
Nov 22 at 17:31
TypeTag
and ClassTag
just provide two different things. See stackoverflow.com/questions/40202504/… and medium.com/@sinisalouc/… What you are likely seeing with TypeTag
is the actual distinction between AnyRef
and Object
since that TypeTag
deals with the types and AnyRef
is indeed different than Object
type wise since AnyRef
is just a trait
and is indeed different than AnyRef
github.com/scala/scala/tree/2.12.x/src/library-aux/scala– Daniel Hinojosa
Nov 22 at 17:31
1
1
Note that you don't need
getTypeTag
, you can just write e.g. implicitly[TypeTag[AnyRef]]
to summon an instance.– Seth Tisue
Nov 22 at 17:35
Note that you don't need
getTypeTag
, you can just write e.g. implicitly[TypeTag[AnyRef]]
to summon an instance.– Seth Tisue
Nov 22 at 17:35
@DanielHinojosa, it's interesting that
AnyRef
is declared as a trait. But I don't think it's really a trait, I think some compiler magic processes such core things in standard library differently. First of all, I believe to Seth Tissue's opinion; second, I can do new AnyRef()
, but not trait T; new T()
; third, typeTag.mirror.runtimeClass(typeTag.tpe).isInterface()
returns false
for AnyRef
(usually it returns true
for traits).– Sasha
Nov 22 at 18:09
@DanielHinojosa, it's interesting that
AnyRef
is declared as a trait. But I don't think it's really a trait, I think some compiler magic processes such core things in standard library differently. First of all, I believe to Seth Tissue's opinion; second, I can do new AnyRef()
, but not trait T; new T()
; third, typeTag.mirror.runtimeClass(typeTag.tpe).isInterface()
returns false
for AnyRef
(usually it returns true
for traits).– Sasha
Nov 22 at 18:09
@Sasha That is an interesting catch and I think the README right before would lead to some answers. github.com/scala/scala/blob/2.12.x/src/library-aux/README. "Source files under this directory cannot be compiled by normal means. They exist for bootstrapping and documentation purposes." So there is something during scala bootstrapping that takes the traitness of AnyRef and merges it with
java.lang.Object
at runtime (maybe) and yet the AnyRef
and Object
for TypeTags
are distinct. Now, what is happening at bootstrap?– Daniel Hinojosa
Nov 22 at 18:18
@Sasha That is an interesting catch and I think the README right before would lead to some answers. github.com/scala/scala/blob/2.12.x/src/library-aux/README. "Source files under this directory cannot be compiled by normal means. They exist for bootstrapping and documentation purposes." So there is something during scala bootstrapping that takes the traitness of AnyRef and merges it with
java.lang.Object
at runtime (maybe) and yet the AnyRef
and Object
for TypeTags
are distinct. Now, what is happening at bootstrap?– Daniel Hinojosa
Nov 22 at 18:18
add a comment |
1 Answer
1
active
oldest
votes
up vote
5
down vote
accepted
You'll see similar behavior with any type alias, I don't think there's anything particular to Object
/AnyRef
in your examples above.
scala 2.12.7> import scala.reflect.runtime.universe.TypeTag
import scala.reflect.runtime.universe.TypeTag
scala 2.12.7> class C; type D = C
defined class C
defined type alias D
scala 2.12.7> implicitly[TypeTag[C]]
res0: reflect.runtime.universe.TypeTag[C] = TypeTag[C]
scala 2.12.7> implicitly[TypeTag[D]]
res1: reflect.runtime.universe.TypeTag[D] = TypeTag[D]
C
and D
are distinct but “equivalent” types. See SLS 3.5, "Relations between types" (https://www.scala-lang.org/files/archive/spec/2.12/03-types.html#relations-between-types)
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435220%2fdifference-between-object-and-anyref-in-scala%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
You'll see similar behavior with any type alias, I don't think there's anything particular to Object
/AnyRef
in your examples above.
scala 2.12.7> import scala.reflect.runtime.universe.TypeTag
import scala.reflect.runtime.universe.TypeTag
scala 2.12.7> class C; type D = C
defined class C
defined type alias D
scala 2.12.7> implicitly[TypeTag[C]]
res0: reflect.runtime.universe.TypeTag[C] = TypeTag[C]
scala 2.12.7> implicitly[TypeTag[D]]
res1: reflect.runtime.universe.TypeTag[D] = TypeTag[D]
C
and D
are distinct but “equivalent” types. See SLS 3.5, "Relations between types" (https://www.scala-lang.org/files/archive/spec/2.12/03-types.html#relations-between-types)
add a comment |
up vote
5
down vote
accepted
You'll see similar behavior with any type alias, I don't think there's anything particular to Object
/AnyRef
in your examples above.
scala 2.12.7> import scala.reflect.runtime.universe.TypeTag
import scala.reflect.runtime.universe.TypeTag
scala 2.12.7> class C; type D = C
defined class C
defined type alias D
scala 2.12.7> implicitly[TypeTag[C]]
res0: reflect.runtime.universe.TypeTag[C] = TypeTag[C]
scala 2.12.7> implicitly[TypeTag[D]]
res1: reflect.runtime.universe.TypeTag[D] = TypeTag[D]
C
and D
are distinct but “equivalent” types. See SLS 3.5, "Relations between types" (https://www.scala-lang.org/files/archive/spec/2.12/03-types.html#relations-between-types)
add a comment |
up vote
5
down vote
accepted
up vote
5
down vote
accepted
You'll see similar behavior with any type alias, I don't think there's anything particular to Object
/AnyRef
in your examples above.
scala 2.12.7> import scala.reflect.runtime.universe.TypeTag
import scala.reflect.runtime.universe.TypeTag
scala 2.12.7> class C; type D = C
defined class C
defined type alias D
scala 2.12.7> implicitly[TypeTag[C]]
res0: reflect.runtime.universe.TypeTag[C] = TypeTag[C]
scala 2.12.7> implicitly[TypeTag[D]]
res1: reflect.runtime.universe.TypeTag[D] = TypeTag[D]
C
and D
are distinct but “equivalent” types. See SLS 3.5, "Relations between types" (https://www.scala-lang.org/files/archive/spec/2.12/03-types.html#relations-between-types)
You'll see similar behavior with any type alias, I don't think there's anything particular to Object
/AnyRef
in your examples above.
scala 2.12.7> import scala.reflect.runtime.universe.TypeTag
import scala.reflect.runtime.universe.TypeTag
scala 2.12.7> class C; type D = C
defined class C
defined type alias D
scala 2.12.7> implicitly[TypeTag[C]]
res0: reflect.runtime.universe.TypeTag[C] = TypeTag[C]
scala 2.12.7> implicitly[TypeTag[D]]
res1: reflect.runtime.universe.TypeTag[D] = TypeTag[D]
C
and D
are distinct but “equivalent” types. See SLS 3.5, "Relations between types" (https://www.scala-lang.org/files/archive/spec/2.12/03-types.html#relations-between-types)
answered Nov 22 at 17:29
Seth Tisue
23.2k960124
23.2k960124
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53435220%2fdifference-between-object-and-anyref-in-scala%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
TypeTag
andClassTag
just provide two different things. See stackoverflow.com/questions/40202504/… and medium.com/@sinisalouc/… What you are likely seeing withTypeTag
is the actual distinction betweenAnyRef
andObject
since thatTypeTag
deals with the types andAnyRef
is indeed different thanObject
type wise sinceAnyRef
is just atrait
and is indeed different thanAnyRef
github.com/scala/scala/tree/2.12.x/src/library-aux/scala– Daniel Hinojosa
Nov 22 at 17:31
1
Note that you don't need
getTypeTag
, you can just write e.g.implicitly[TypeTag[AnyRef]]
to summon an instance.– Seth Tisue
Nov 22 at 17:35
@DanielHinojosa, it's interesting that
AnyRef
is declared as a trait. But I don't think it's really a trait, I think some compiler magic processes such core things in standard library differently. First of all, I believe to Seth Tissue's opinion; second, I can donew AnyRef()
, but nottrait T; new T()
; third,typeTag.mirror.runtimeClass(typeTag.tpe).isInterface()
returnsfalse
forAnyRef
(usually it returnstrue
for traits).– Sasha
Nov 22 at 18:09
@Sasha That is an interesting catch and I think the README right before would lead to some answers. github.com/scala/scala/blob/2.12.x/src/library-aux/README. "Source files under this directory cannot be compiled by normal means. They exist for bootstrapping and documentation purposes." So there is something during scala bootstrapping that takes the traitness of AnyRef and merges it with
java.lang.Object
at runtime (maybe) and yet theAnyRef
andObject
forTypeTags
are distinct. Now, what is happening at bootstrap?– Daniel Hinojosa
Nov 22 at 18:18