Difference between Object and AnyRef in Scala
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 |
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 '18 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 '18 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 '18 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 '18 at 18:18
add a comment |
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 '18 at 16:50
Sasha
asked Nov 22 '18 at 16:41
SashaSasha
1,5781528
1,5781528
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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 18:18
add a comment |
1 Answer
1
active
oldest
votes
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',
autoActivateHeartbeat: false,
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
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 |
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 |
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 '18 at 17:29
Seth TisueSeth Tisue
23.3k961125
23.3k961125
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.
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 '18 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 '18 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 '18 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 '18 at 18:18