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
TypeTagandClassTagjust provide two different things. See stackoverflow.com/questions/40202504/… and medium.com/@sinisalouc/… What you are likely seeing withTypeTagis the actual distinction betweenAnyRefandObjectsince thatTypeTagdeals with the types andAnyRefis indeed different thanObjecttype wise sinceAnyRefis just atraitand is indeed different thanAnyRefgithub.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 thatAnyRefis 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()returnsfalseforAnyRef(usually it returnstruefor 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.Objectat runtime (maybe) and yet theAnyRefandObjectforTypeTagsare 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
TypeTagandClassTagjust provide two different things. See stackoverflow.com/questions/40202504/… and medium.com/@sinisalouc/… What you are likely seeing withTypeTagis the actual distinction betweenAnyRefandObjectsince thatTypeTagdeals with the types andAnyRefis indeed different thanObjecttype wise sinceAnyRefis just atraitand is indeed different thanAnyRefgithub.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 thatAnyRefis 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()returnsfalseforAnyRef(usually it returnstruefor 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.Objectat runtime (maybe) and yet theAnyRefandObjectforTypeTagsare distinct. Now, what is happening at bootstrap?
– Daniel Hinojosa
Nov 22 at 18:18
add a comment |
TypeTagandClassTagjust provide two different things. See stackoverflow.com/questions/40202504/… and medium.com/@sinisalouc/… What you are likely seeing withTypeTagis the actual distinction betweenAnyRefandObjectsince thatTypeTagdeals with the types andAnyRefis indeed different thanObjecttype wise sinceAnyRefis just atraitand is indeed different thanAnyRefgithub.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 thatAnyRefis 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()returnsfalseforAnyRef(usually it returnstruefor 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.Objectat runtime (maybe) and yet theAnyRefandObjectforTypeTagsare 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
TypeTagandClassTagjust provide two different things. See stackoverflow.com/questions/40202504/… and medium.com/@sinisalouc/… What you are likely seeing withTypeTagis the actual distinction betweenAnyRefandObjectsince thatTypeTagdeals with the types andAnyRefis indeed different thanObjecttype wise sinceAnyRefis just atraitand is indeed different thanAnyRefgithub.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
AnyRefis 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()returnsfalseforAnyRef(usually it returnstruefor 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.Objectat runtime (maybe) and yet theAnyRefandObjectforTypeTagsare distinct. Now, what is happening at bootstrap?– Daniel Hinojosa
Nov 22 at 18:18