- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
getClass returns Class[_]?
Mon, 2009-01-19, 01:05
Hi,
Probably this is a complicated issue, but shouldn't the following work?
val xClass: Class[X] = new X().getClass //it returns Class[_], nor Class[X]
val integerClass: Class[Integer] = new Integer(5).getClass //similar error
Thanks,
Dimitris
Mon, 2009-01-19, 01:37
#2
Re: getClass returns Class[_]?
On Sun, 2009-01-18 at 16:12 -0800, David Pollak wrote:
> Andreou,
>
>
> The return type (in the Java apis) of getClass is Class<?>:
> Class<?>
> getClass()
> Returns the runtime class
> of this Object.
It's more complicated than that. The following compiles:
Class<? extends Integer> klass = new Integer(2).getClass();
The javadoc explains:
The actual result type is {@code Class<? extends |X|>} * where {@code |X|} is the erasure of the static type of the * expression on which {@code getClass} is called. For * example, no cast is required in this code fragment:
* *
* {@code Number n = 0; }
* {@code Class<? extends Number> c = n.getClass(); }
*
Mon, 2009-01-19, 01:47
#3
Re: getClass returns Class[_]?
O/H Ismael Juma έγραψε:
> On Sun, 2009-01-18 at 16:12 -0800, David Pollak wrote:
>
>> Andreou,
>>
>>
>> The return type (in the Java apis) of getClass is Class<?>:
>> Class<?>
>> getClass()
>> Returns the runtime class
>> of this Object.
>>
>
> It's more complicated than that. The following compiles:
>
> Class<? extends Integer> klass = new Integer(2).getClass();
>
> The javadoc explains:
>
>
The actual result type is {@code Class<? extends |X|>} > * where {@code |X|} is the erasure of the static type of the > * expression on which {@code getClass} is called. For > * example, no cast is required in this code fragment:
> * > *
> * {@code Number n = 0; }
> * {@code Class<? extends Number> c = n.getClass(); }
> *
Mon, 2009-01-19, 01:57
#4
Re: getClass returns Class[_]?
This is Scala. We don't need no stinkin' compiler magic, we got it already :-)
class NiceObject[T <: AnyRef](x : T) {
def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}
implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)
scala> "Hello world".niceClass
res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String
On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou <jim.andreou@gmail.com> wrote:
class NiceObject[T <: AnyRef](x : T) {
def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}
implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)
scala> "Hello world".niceClass
res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String
On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou <jim.andreou@gmail.com> wrote:
I guess it would be nice if similar compiler magic was implemented in Scala too.
(Although not big deal, since the type of the expression is available, and we can simply add an never-failing asInstanceOf[ <type> ])
Mon, 2009-01-19, 01:57
#5
Re: getClass returns Class[_]?
On Sun, Jan 18, 2009 at 4:52 PM, James Iry <jamesiry@gmail.com> wrote:
This is Scala. We don't need no stinkin' compiler magic, we got it already :-)
class NiceObject[T <: AnyRef](x : T) {
def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}
implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)
scala> "Hello world".niceClass
res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String
Very nice.
On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou <jim.andreou@gmail.com> wrote:I guess it would be nice if similar compiler magic was implemented in Scala too.
(Although not big deal, since the type of the expression is available, and we can simply add an never-failing asInstanceOf[ <type> ])
--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Mon, 2009-01-19, 02:07
#6
Re: getClass returns Class[_]?
lol! You're right. (You could even do it a bit more nice with Class[T]
instead of Class[_ <: T] )
Let me make an observation here:
All problems in Java can be solved with an annotation. In Scala, with an
implicit conversion.
O/H James Iry έγραψε:
> This is Scala. We don't need no stinkin' compiler magic, we got it
> already :-)
>
> class NiceObject[T <: AnyRef](x : T) {
> def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
> }
>
> implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)
>
> scala> "Hello world".niceClass
> res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String
>
>
>
> On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou
> > wrote:
>
>
>
>
>
> I guess it would be nice if similar compiler magic was implemented
> in Scala too.
> (Although not big deal, since the type of the expression is
> available, and we can simply add an never-failing asInstanceOf[
> ])
>
>
Mon, 2009-01-19, 04:27
#7
Re: getClass returns Class[_]?
Except that Class[T] isn't right because Class isn't marked as covariant by Java - Java doesn't have that concept. If Sub is a subtype of Base then
val someSub : Sub = ...
val x : Base = someSub // a legal cast
val klass = x.niceClass
what type should klass have? Dynamically speaking it's in fact a Class[Sub], but the static type system can't know that. By your scheme it would be Class[Base], but Class[Base] isn't a supertype of Class[Sub] so we've gone sideways a bit. By my scheme it gets the best type the static type system can apply: Class[_ <: Base] - it's a Class for some type that is a subtype of Base, but the static type system doesn't know which.
On Sun, Jan 18, 2009 at 5:04 PM, Dimitris Andreou <jim.andreou@gmail.com> wrote:
val someSub : Sub = ...
val x : Base = someSub // a legal cast
val klass = x.niceClass
what type should klass have? Dynamically speaking it's in fact a Class[Sub], but the static type system can't know that. By your scheme it would be Class[Base], but Class[Base] isn't a supertype of Class[Sub] so we've gone sideways a bit. By my scheme it gets the best type the static type system can apply: Class[_ <: Base] - it's a Class for some type that is a subtype of Base, but the static type system doesn't know which.
On Sun, Jan 18, 2009 at 5:04 PM, Dimitris Andreou <jim.andreou@gmail.com> wrote:
lol! You're right. (You could even do it a bit more nice with Class[T] instead of Class[_ <: T] )
Let me make an observation here:
All problems in Java can be solved with an annotation. In Scala, with an implicit conversion.
O/H James Iry έγραψε:
This is Scala. We don't need no stinkin' compiler magic, we got it already :-)
class NiceObject[T <: AnyRef](x : T) {
def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}
implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)
scala> "Hello world".niceClass res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String
On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou <jim.andreou@gmail.com <mailto:jim.andreou@gmail.com>> wrote:
I guess it would be nice if similar compiler magic was implemented
in Scala too.
(Although not big deal, since the type of the expression is
available, and we can simply add an never-failing asInstanceOf[
<type> ])
Mon, 2009-01-19, 05:07
#8
Re: getClass returns Class[_]?
O/H James Iry έγραψε:
> Except that Class[T] isn't right because Class isn't marked as
> covariant by Java - Java doesn't have that concept.
> If Sub is a subtype of Base then
>
> val someSub : Sub = ...
> val x : Base = someSub // a legal cast
>
> val klass = x.niceClass
>
> what type should klass have?
Class[Base], sure enough.
> Dynamically speaking it's in fact a Class[Sub], but the static type
> system can't know that. By your scheme it would be Class[Base], but
> Class[Base] isn't a supertype of Class[Sub]
Disclaimer: I'm used to java generics semantics, I'm not sure if these
translate very well in scala, but anyway, hopefully they do:
Class[T] and Class[_ <: T] are practically equivalent since Class
doesn't have any method that accepts T (yes, this means that the java
compiler magic could safely translate T.getClass() expressions to
Class instead of Class<? extends T>). But the former is also more
specific, so it can be applied to more method signatures, specifically,
it can be applied to every method your Class[_ <: T] can be applied, but
it can also be applied to an expected method argument of type Class[T],
whereas Class[_ <: T] cannot. So we have two synonyms that the one can
be type-safely be applied to more methods, so it should be preferred.
> so we've gone sideways a bit. By my scheme it gets the best type the
> static type system can apply: Class[_ <: Base] - it's a Class for some
> type that is a subtype of Base, but the static type system doesn't
> know which.
But Class[Base] already means a "class for some type that is a subtype
of Base". Think of a method that returns "Base". That's exactly what it
means. You get back a subtype.
>
> On Sun, Jan 18, 2009 at 5:04 PM, Dimitris Andreou
> > wrote:
>
> lol! You're right. (You could even do it a bit more nice with
> Class[T] instead of Class[_ <: T] )
>
> Let me make an observation here:
> All problems in Java can be solved with an annotation. In Scala,
> with an implicit conversion.
>
>
> O/H James Iry ������:
>
> This is Scala. We don't need no stinkin' compiler magic, we
> got it already :-)
>
> class NiceObject[T <: AnyRef](x : T) {
> def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
> }
>
> implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)
>
> scala> "Hello world".niceClass
> res11: java.lang.Class[_ <: java.lang.String] = class
> java.lang.String
>
>
>
> On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou
>
> >>
> wrote:
>
>
>
>
> I guess it would be nice if similar compiler magic was
> implemented
> in Scala too.
> (Although not big deal, since the type of the expression is
> available, and we can simply add an never-failing asInstanceOf[
> ])
>
>
>
>
Mon, 2009-01-19, 06:17
#9
Re: getClass returns Class[_]?
But Class[Base] already means a "class for some type that is a subtype of Base". Think of a method that returns "Base". That's exactly what it means. You get back a subtype.
Nope. No more than ArrayList[String] is a subtype of ArrayList[Object]. The rest of your arugment is that, unlike ArrayList, Class could be covariant. You're probably right. Unfortunately, it isn't.
Mon, 2009-01-19, 10:37
#10
Re: getClass returns Class[_]?
This is unrelated, but I'm curious, is there an advantage to creating a
non-anonymous class for extension methods?
I've lately been doing all such conversions as anonymous classes:
implicit def toNiceObject[T <: AnyRef](x : T) = new {
def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}
It's shorter and doesn't pollute the namespace. The only disadvantage I
can think of is documentation. Although possibly IDEs and ScalaDoc
should be able use method documentation in anonymous classes as well, I
think?
Erkki
James Iry wrote:
> This is Scala. We don't need no stinkin' compiler magic, we got it
> already :-)
>
> class NiceObject[T <: AnyRef](x : T) {
> def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
> }
>
> implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)
>
> scala> "Hello world".niceClass
> res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String
>
>
>
> On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou
> > wrote:
>
>
>
>
>
> I guess it would be nice if similar compiler magic was implemented
> in Scala too.
> (Although not big deal, since the type of the expression is
> available, and we can simply add an never-failing asInstanceOf[
> ])
>
>
Mon, 2009-01-19, 11:47
#11
Re: getClass returns Class[_]?
On Mon, Jan 19, 2009 at 11:29:44AM +0200, Erkki Lindpere wrote:
> This is unrelated, but I'm curious, is there an advantage to creating a
> non-anonymous class for extension methods?
Unfortunately, yes.
> I've lately been doing all such conversions as anonymous classes:
>
> implicit def toNiceObject[T <: AnyRef](x : T) = new {
> def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
> }
If you look at the bytecode for the anonymous version you'll see a bunch of reflection that the
named version doesn't have to do, so the shorter version is significantly slower. This may
improve in the future as JDK7 promises some helpful features.
Mon, 2009-01-19, 13:07
#12
Re: getClass returns Class[_]?
O/H James Iry έγραψε:
>
> But Class[Base] already means a "class for some type that is a
> subtype of Base". Think of a method that returns "Base". That's
> exactly what it means. You get back a subtype.
>
>
> Nope. No more than ArrayList[String] is a subtype of
> ArrayList[Object]. The rest of your arugment is that, unlike
> ArrayList, Class could be covariant. You're probably right.
> Unfortunately, it isn't.
James, you're confusing what I say. I never said that Class[Sub] is a
subtype of Class[Base]. It is not. Who cares. Did I say "go ahead and
create a method that takes Class[Base]"? If I did, then I would miss the
possibility of applying Class[Sub]. But I can always make such a
function that takes a Class[X] where X <: Base. That's entirely irrelevant.
To close the matter, just consider that Class[Base] is a subtype of
Class[_ <: Base], (not the other way around). So a Class[Base] also *is*
a Class[_ <: Base]. Now abstract a little to see the big picture. In
object oriented languages, the basic fact is that a value of a subtype
can be assigned to more places (variables, method args, methods to it)
than a value of a supertype. It is more useful - literally it simply has
more uses. So wherever you can, *return the more precise subtype you
can*. On the contrary, a supertype can be *assigned from* more places
than a subtype (such as storing the result of a function, or storing a
method parameter). You can do less things with it, but can represent a
wider domain of values. So wherever you can, *accept the more general
supertype you can*. These are the two faces of the same coin, and they
are pretty basic and hopefully you won't deny them.
So, I suggest switching it to returning Class[Base], and if you don't
like it, just store the method result into a Class[_ <: Base] variable,
nobody will notice a thing :)
The return type (in the Java apis) of getClass is Class<?>:
Class<?>
getClass()
Returns the runtime class of this
Object
.Scala is faithfully returning what the Java APIs define.
Sorry.
David
On Sun, Jan 18, 2009 at 4:04 PM, Andreou Dimitris <jim.andreou@gmail.com> wrote:
--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp